Forms
Form inventory and per-form analytics.
apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
limit?integerPage size. Defaults to 50; values above 200 are clamped to 200; a non-positive or non-numeric value is a 400 (invalid_limit).
1 <= value <= 20050cursor?stringOpaque pagination cursor from a previous response's meta.nextCursor. A stale/unknown cursor returns an empty page (never a silent page-one replay).
A page of form summaries.
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms'{ "data": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "status": "draft", "updatedAt": "2019-08-24T14:15:22Z" } ], "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" }, "nextCursor": "string" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
application/json- body
name*stringDisplay name shown in the merchant's dashboard.
schema*The complete form definition — { id, version, name, steps[], settings, styles, ... }. The server validates and normalizes it on write, and
pins id to the form row, so a client-supplied id is ignored. Send
the whole tree; writes replace the draft wholesale (not a partial patch).
The created form summary.
application/json- response
data*Endpoint-specific payload.
meta*curl -X POST 'https://public-api.formtoro.com/v1/forms' \ -H 'Content-Type: application/json' \ -d '{ "name": "string", "schema": {}}'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "status": "draft", "updatedAt": "2019-08-24T14:15:22Z" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
range?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
form_ids?array<>Optional comma-separated form UUIDs to include. Max 100 ids. Omit to return every form with events in the requested window.
items <= 100Per-form funnel rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/funnel?range=30d&form_ids=019e73ce-1968-71ca-ae57-dbd8084cee79%2C019e73ce-1968-71ca-ae57-dbd8084cee7a'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ { "formId": "126460ed-49b2-4c69-849a-bd8904ec5d8f", "views": 0, "subscriptions": 0, "completions": 0 } ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidThe form summary.
application/json- response
data*Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "status": "draft", "updatedAt": "2019-08-24T14:15:22Z" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidapplication/json- body
draft_schema*The complete form definition — { id, version, name, steps[], settings, styles, ... }. The server validates and normalizes it on write, and
pins id to the form row, so a client-supplied id is ignored. Send
the whole tree; writes replace the draft wholesale (not a partial patch).
expected_updated_at?stringOptional optimistic-concurrency cursor (the form's last-seen
updatedAt). When supplied, a concurrent edit since then returns
409 conflict instead of overwriting. Omit for last-write-wins.
date-timeThe updated form summary.
application/json- response
data*Endpoint-specific payload.
meta*curl -X PUT 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{ "draft_schema": {}}'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "status": "draft", "updatedAt": "2019-08-24T14:15:22Z" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidapplication/json- body
make_live?booleanAlso make the new version live on the storefront.
falserelease_notes?stringOptional notes for the version history. Omit to use the automatically computed summary of changes.
length <= 2000The saved version.
application/json- response
data*Endpoint-specific payload.
meta*curl -X POST 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/versions' \ -H 'Content-Type: application/json' \ -d '{}'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "releaseId": "string", "releaseNumber": 0, "releaseNotes": "string", "isLive": true, "savedAt": "2019-08-24T14:15:22Z", "warnings": [ { "field": "string", "message": "string" } ], "cache": "written" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidThe form is live.
application/json- response
data*Endpoint-specific payload.
meta*curl -X POST 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/turn-on'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "isLive": true, "releaseId": "string", "releaseNumber": 0, "alreadyLive": true, "cache": "written" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidThe form is off.
application/json- response
data*Endpoint-specific payload.
meta*curl -X POST 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/turn-off'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": { "isLive": false, "outcome": "turned_off", "cache": "written" }}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An analytics object plus meta (with the resolved range).
application/json- response
data*An endpoint-specific analytics object. Shapes mirror the in-app analytics surface and the MCP analytics tools 1:1; see the per-tool docs for exact fields. Monetary fields are integer cents.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/funnel?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": {}}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/steps/dropoff?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/time-to-complete?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/devices?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/visitor-conversion?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidfieldA*stringFirst field id to correlate.
fieldB*stringSecond field id to correlate.
range?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/cross-field?fieldA=string&fieldB=string&range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/response-revenue?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}apiKeyAuthorizationBearer <token>A Formtoro API key minted in Settings → Connections. A key carries one
or more scopes; an endpoint refuses a key that lacks its required scope
with 403 insufficient_scope. Scopes:
analytics:read— all aggregate read endpoints.customers:read— customer-level lifetime value.forms:write— create and edit forms (drafts). Grantable only by a member who holds the Form-editing permission.forms:publish— save versions and turn forms on or off on the live storefront. Grantable only by a member who holds the Form-publishing permission.discounts:read— read discount definitions. Grantable only by a member who holds the Discounts-view permission.
id*stringThe form's UUID. A non-UUID value resolves to 404, never a 500.
uuidrange?stringTime window. Shorthand (7d/30d/90d), an ISO pair
(2026-01-01..2026-01-31), or a single ISO day. Omitted → last 30 days.
An array of analytics rows plus meta (with the resolved range).
application/json- response
data*array<>Endpoint-specific payload.
meta*curl -X GET 'https://public-api.formtoro.com/v1/forms/497f6eca-6276-4993-bfeb-53cbbbba6f08/trends?range=30d'{ "meta": { "requestId": "string", "shopId": "string", "credentialId": "string", "range": { "from": "2019-08-24T14:15:22Z", "to": "2019-08-24T14:15:22Z" } }, "data": [ {} ]}