Forms
Create sign-up forms, publish them, and rotate their public token.
Create a form
Creates a sign-up form in draft status with a public token. Requires an API key with the full scope. Forms are in early access.
If you omit definition, Emailit generates a starter form: one step with a heading, a required email field and a Subscribe button, plus a success step. Build and style forms in the dashboard under Email MarketingForms, then publish them.
/formsBody parameters
namestringrequiredtypestringdefault: popuppopup, full_page, flyout, embed or banner.definitionobjectThe form’s content, stored as-is. Emailit checks it only when you publish. Top-level fields:
version(integer):1.type(string): the form type.steps(array): each step hasid,name,kind(formorsuccess) andblocks. Blocks have anidand atype:text,button(action:submit,next,closeorgo_to_url),image, or an input (email,text_input,phone,date,radio,checkbox,dropdown) with a fieldname,labelandrequired.styles,targeting,experiments(objects): appearance and display rules set by the form builder.
settingsobject{}.Returns
Returns 201 Created with the form object, including definition and settings.
tokenstringstatusstringdraft until you publish the form, then live.published_atstring | nullReturns 400 if name is missing or empty, or type isn’t one of the allowed values.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "draft",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-01T11:20:31.000000+00:00",
"published_at": null,
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq5TgB2kVw7Nn1Ps4Fd9QzA", "type": "text", "content": "<p>Join our list</p>" },
{
"id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU",
"type": "email",
"label": "<p>Email</p>",
"placeholder": "you@example.com",
"required": true,
"name": "email"
},
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [
{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }
]
}
],
"styles": {
"backgroundColor": "#ffffff",
"textColor": "#0f172a",
"primaryColor": "#03a071",
"borderRadius": 12,
"fontFamily": "Inter, system-ui, sans-serif",
"buttonStyle": "solid"
},
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"statusCode": 400,
"error": "Bad Request",
"message": "Validation error",
"details": [
{
"instancePath": "",
"schemaPath": "#/required",
"keyword": "required",
"params": { "missingProperty": "name" },
"message": "must have required property 'name'"
}
]
}Retrieve a form
Retrieves a form with its full definition. Requires an API key with the full scope.
/forms/{id}Path parameters
idstringrequiredfrm_…).Returns
Returns the form object.
objectstringform.idstringfrm_.namestringtypestringpopup, full_page, flyout, embed or banner.statusstringdraft or live. Only live forms load on your site.tokenstringdefinitionobjectsettingsobjectcreated_at, updated_at, published_atstring | nullpublished_at is null until the first publish.Returns 404 if the form doesn’t exist.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "live",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-01T11:48:02.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00",
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq5TgB2kVw7Nn1Ps4Fd9QzA", "type": "text", "content": "<p>Get our monthly product notes</p>" },
{
"id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU",
"type": "email",
"label": "<p>Email</p>",
"placeholder": "you@example.com",
"required": true,
"name": "email"
},
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [
{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }
]
}
],
"styles": {
"backgroundColor": "#ffffff",
"textColor": "#0f172a",
"primaryColor": "#03a071",
"borderRadius": 12,
"fontFamily": "Inter, system-ui, sans-serif",
"buttonStyle": "solid"
},
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"error": "Form not found"
}Update a form
Updates the fields you pass and leaves the others unchanged. Requires an API key with the full scope.
Changes to a live form are visible to visitors immediately; you don’t need to publish again. To edit without affecting visitors, unpublish first.
/forms/{id}Path parameters
idstringrequiredfrm_…).Body parameters
namestringtypestringpopup, full_page, flyout, embed or banner. Update definition.type to match.definitionobjectsettingsobjectReturns
Returns the updated form object. Returns 400 if a field has the wrong type or name is empty, and 404 if the form doesn’t exist.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup (October)",
"type": "popup",
"status": "live",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-02T08:05:14.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00",
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU", "type": "email", "label": "<p>Email</p>", "required": true, "name": "email" },
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }]
}
],
"styles": { "primaryColor": "#03a071", "borderRadius": 12, "buttonStyle": "solid" },
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"error": "Invalid name"
}{
"error": "Form not found"
}List forms
Returns the workspace’s forms, newest first, without definition and settings. Requires an API key with the full scope.
/formsQuery parameters
pageintegerdefault: 1limitintegerdefault: 10searchstringmatchstringall (default) requires every filter. or matches any filter. See Filtering.
orderstringSort key for this list. See the sort keys below.
directionstringasc or desc.
Filter keys
Filters use key.condition=value query parameters, for example status.exact=live. See Filtering.
| Key | Type | Notes |
|---|---|---|
name |
string | |
type |
enum | popup, full_page, flyout, embed, banner |
status |
enum | draft, live |
created_at |
date |
Sort keys for order: name, type, status, created_at.
Returns
dataobject[]object, id, name, type, status, token, created_at, updated_at, published_at.total_recordsintegernext_page_urlstring | nullnull on the last page. It carries only page and limit; add your search and filters again when you follow it.previous_page_urlstring | nullnull on the first page.{
"data": [
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "live",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-01T11:48:02.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00"
}
],
"total_records": 1,
"next_page_url": null,
"previous_page_url": null
}Publish a form
Sets the form’s status to live and updates published_at. Live forms load on any site where the Emailit script is installed and can receive submissions. Requires an API key with the full scope.
The definition needs at least one step with kind: "form" and one with kind: "success"; otherwise the request returns 422. Submissions are stored with the form and don’t create contacts yet.
/forms/{id}/publishPath parameters
idstringrequiredfrm_…).Returns
Returns the form object with status set to live. Returns 422 if the definition is incomplete and 404 if the form doesn’t exist.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "live",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-01T11:48:02.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00",
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU", "type": "email", "label": "<p>Email</p>", "required": true, "name": "email" },
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }]
}
],
"styles": { "primaryColor": "#03a071", "borderRadius": 12, "buttonStyle": "solid" },
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"error": "Form must have a success step"
}{
"error": "Form not found"
}Unpublish a form
Sets the form’s status back to draft. The embed script stops loading it and new submissions are rejected. The token, definition and published_at stay the same, so you can publish it again later. Requires an API key with the full scope.
/forms/{id}/unpublishPath parameters
idstringrequiredfrm_…).Returns
Returns the form object with status set to draft. Returns 404 if the form doesn’t exist.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "draft",
"token": "9636697db6c8f136d6742cee9c86eb3ed53b89f0a44e3ce6",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-06T07:30:00.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00",
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU", "type": "email", "label": "<p>Email</p>", "required": true, "name": "email" },
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }]
}
],
"styles": { "primaryColor": "#03a071", "borderRadius": 12, "buttonStyle": "solid" },
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"error": "Form not found"
}Reset the public token
Generates a new public token for the form. The old token stops working immediately: sites that load the form with it no longer show it and can’t submit to it. Update your embed code with the new token. Requires an API key with the full scope.
/forms/{id}/reset-tokenPath parameters
idstringrequiredfrm_…).Returns
Returns the form object with the new token. The status doesn’t change. Returns 404 if the form doesn’t exist.
{
"object": "form",
"id": "frm_3Bzpif9xswMlVbFvGZSPNixm5j5",
"name": "Newsletter popup",
"type": "popup",
"status": "live",
"token": "e5ed3f9ec299ae1c5dc043c45f2a616c352e47a13b6b763b",
"created_at": "2026-10-01T11:20:31.000000+00:00",
"updated_at": "2026-10-06T09:12:44.000000+00:00",
"published_at": "2026-10-01T11:48:02.000000+00:00",
"definition": {
"version": 1,
"type": "popup",
"steps": [
{
"id": "3Rb7Lq2NcX9vZt4Wm8Kd1Hs6PyE",
"name": "Step 1",
"kind": "form",
"blocks": [
{ "id": "3Rb7Lq3JfM6xYc0Rr5Hh8Gk2SeU", "type": "email", "label": "<p>Email</p>", "required": true, "name": "email" },
{ "id": "3Rb7Lq4WdP1zQa6Ee9Jj3Lm7TfV", "type": "button", "label": "<p>Subscribe</p>", "action": "submit" }
]
},
{
"id": "3Rb7Lq2XkS8wUe3Tt6Mn0Bv5RgC",
"name": "Success",
"kind": "success",
"blocks": [{ "id": "3Rb7Lq6YhD4cFi9Uu2Oo7Cx1WhB", "type": "text", "content": "<p>Thanks for subscribing!</p>" }]
}
],
"styles": { "primaryColor": "#03a071", "borderRadius": 12, "buttonStyle": "solid" },
"targeting": {},
"experiments": {}
},
"settings": {}
}{
"error": "Form not found"
}Delete a form
Permanently deletes a form and all of its stored submissions. Sites that embed it stop showing it. Requires an API key with the full scope.
/forms/{id}Path parameters
idstringrequiredfrm_…).Returns
Returns 204 No Content with an empty body. Returns 404 if the form doesn’t exist.
(empty body){
"error": "Form not found"
}