Limited time discount
Fast Forms, Big Savings This Summer
Up to 60%Off
Up to 60%Off
Grab Now
documentation-logo
Menu
  • Guides
  • For Developers

How to manage forms and entries using the IvyForms REST API

The IvyForms REST API lets you list forms, read their fields, pull entries, and submit new ones from your own scripts or applications.

These endpoints require either the Agency or Elite plan and a valid API key with the right scope. For setup, see How to use the REST API feature in IvyForms.

What is the base path for API requests?

All endpoints share the same base path, and only the endpoint part changes:

{site}/wp-json/ivyforms-public/v1

Every request also needs the X-IvyForms-Api-Key header described in the setup documentation.

If your site doesn’t use pretty permalinks, you can reach the same endpoints through the query-string form instead: {site}/?rest_route=/ivyforms-public/v1/forms.

How do I list all forms?

You can list every form on your site by sending a GET request to /forms, using a key with the read scope.

Method: GET
Endpoint: /forms

Example:

1
2
curl --location '{site}/wp-json/ivyforms-public/v1/forms' \
--header 'X-IvyForms-Api-Key: YOUR_API_KEY'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "data": [
    {
      "id": 71,
      "name": "Contact form",
      "fields": [
        {
          "id": 4,
          "type": "email",
          "fieldIndex": 0,
          "label": "Email",
          "required": true
        },
        {
          "id": 5,
          "type": "textarea",
          "fieldIndex": 1,
          "label": "Message",
          "required": false
        }
      ]
    }
  ]
}

How do I get a single form?

You can fetch one form, including its full field list, by sending a GET request to /forms/{form_id}, using a key with the read scope.
Method: GET
Endpoint: /forms/{form_id}

Example:

1
2
curl --location '{site}/wp-json/ivyforms-public/v1/forms/71' \
--header 'X-IvyForms-Api-Key: YOUR_API_KEY'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
  "id": 71,
  "name": "Contact form",
  "fields": [
    {
      "id": 4,
      "type": "email",
      "fieldIndex": 0,
      "label": "Email",
      "required": true
    },
    {
      "id": 5,
      "type": "textarea",
      "fieldIndex": 1,
      "label": "Message",
      "required": false
    }
  ]
}

How do I list entries for a form?

You can list every entry submitted on a form by sending a GET request to /forms/{form_id}/entries, using a key with the read scope.
Method: GET
Endpoint: /forms/{form_id}/entries

Example:

1
2
curl --location '{site}/wp-json/ivyforms-public/v1/forms/71/entries' \
--header 'X-IvyForms-Api-Key: YOUR_API_KEY'

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "data": [
    {
      "id": 132,
      "form_id": 71,
      "submitted_at": "2026-07-14 10:32:00",
      "values": {
        "4": "[email protected]",
        "5": "Hi, I'd like a quote."
      }
    }
  ]
}

How do I get a single entry?

You can fetch one entry by sending a GET request to /entries/{entry_id}, using a key with the read scope.
Method: GET
Endpoint: /entries/{entry_id}

Example:

1
2
curl --location '{site}/wp-json/ivyforms-public/v1/entries/7' \
--header 'X-IvyForms-Api-Key: YOUR_API_KEY'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "entry": {
    "id": 7,
    "formId": 7,
    "userId": 1,
    "author": "root",
    "dateCreated": "2026-07-21 12:29:44",
    "dateEdited": "2026-07-21 12:29:53",
    "status": "read",
    "ipAddress": "",
    "userAgent": "Google Chrome",
    "sourceURL": "{site}/?ivyforms_preview=7&_wpNonce=849532fd45",
    "starred": false,
    "lifecycleStatus": "draft",
    "expiresAt": "2026-08-20 12:29:44",
    "draftMeta": "{\"currentPageId\":\"page_1\",\"completedPages\":[]}",
    "hasResumeToken": true
  },
  "fields": [
    { "id": "65", "entryId": "7", "fieldId": "75", "fieldValue": "iva" },
    { "id": "66", "entryId": "7", "fieldId": "76", "fieldValue": "2" },
    { "id": "67", "entryId": "7", "fieldId": "77", "fieldValue": "" }
  ]
}

The response has two parts: an entry object with metadata, and a fields array with the actual submitted values.

  • id, formId; entry and form identifiers
  • userId, author; the WordPress user tied to the entry, if any
  • dateCreated, dateEdited; timestamps for creation and last edit
  • status; read/unread state
  • ipAddress, userAgent, sourceURL; submitter and page context
  • starred; whether the entry is flagged in the admin
  • lifecycleStatus, expiresAt, draftMeta, hasResumeToken; used for multi-page forms saved as a draft partway through

Each item in fields links a fieldId to its fieldValue, always returned as a string, even for numeric or single-choice fields.

How do I submit a new entry?

You can create a new entry by sending a POST request to /forms/{form_id}/submissions, with field values keyed by field ID.
A key with the submit scope can post entries directly. Without that scope, submissions still work if you include a valid form render nonce instead, the same way an embedded form would submit.
Method: POST
Endpoint: /forms/{form_id}/submissions
Required properties:

  • values (object); one key per field ID, with the field’s submitted value

Example:

1
2
3
4
5
6
7
8
9
10
11
curl --location '{site}/wp-json/ivyforms-public/v1/forms/1/submissions' \
--header 'X-IvyForms-Api-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
  "values": {
    "1": "Jane Doe",
    "2": "[email protected]",
    "6": "Hi, I would like a quote.",
    "25": "0"
  }
}'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "data": {
    "success": true,
    "entry": {
      "stored": true,
      "id": 8
    },
    "confirmation": "Thanks for reaching out! We've received your message and will get back to you shortly.",
    "confirmationResult": {
      "id": 1,
      "type": "successMessage",
      "message": "Thanks for reaching out! We've received your message and will get back to you shortly.",
      "showForm": false,
      "url": "",
      "pageUrl": "",
      "isDefault": true
    }
  }
}

confirmationResult mirrors whatever confirmation is configured on the form itself. This example shows a success message; a form configured to redirect after submission would likely return a different type with url or pageUrl populated instead.

What should I keep in mind when using these endpoints?

If you’re building an integration on top of these endpoints, test on a staging site first and log both requests and responses while you build.

  • Skip layout-only fields (like html and section fields) and CAPTCHA fields (turnstile, recaptcha, hcaptcha) when building a submission payload; they’re not meant to be filled in through the API.
  • A CAPTCHA field on the form (like Turnstile) still needs a solved token in the payload, keyed as turnstile_{fieldIndex}; there’s no way to bypass it through the API.
  • Send all field values as strings, regardless of the field’s underlying type.
  • Don’t hardcode API keys in front-end JavaScript or ship them to the browser.
  • Don’t reuse a key with the submit scope across untrusted third-party tools; generate a separate key per integration so you can revoke one without affecting the others.