Developers
Send requests, manage forms and receive the answers from your own code, or let an AI agent do it.
What you can do
Call the REST API to send a request to one person and read the answers, or to create, publish and change forms, share links, webhooks and translations.
- Receive events: a webhook posts every submission of a form to your URL, and a request callback posts once, when a request ends.
- Connect an AI agent over MCP, so Claude, ChatGPT, Cursor and other agents can do the same through tools.
No code needed?
Zapier, Make and n8n connect Formstep click by click. See the Automation guides.
Pages in this section
- Send a request with the REST APICreate an API token, read a form's field keys, and create a prefilled request with curl, from any tool that can make an HTTP call.
- Receive and verify the callbackRun a small receiver in Node or Python, check each callback's signature with your signing secret, and read the answers Formstep pushes when a request ends.
- Create requests from codeList a form's field keys, create a request with prefill, locked fields and context, hand the recipient documents, and read the answers.
- Create a form and a request in one callSend the blocks with the request: Formstep builds the form, publishes it and returns the link, with no editor in between.
- Request callbacksFormstep POSTs a signed event to the callbackUrl of a request when it is completed, expires or is canceled.
- API referenceEvery REST API method with its parameters, examples and responses: forms, submissions, share links, requests, webhooks and more.
- API tokensCreate, manage, and rotate tokens for the API and MCP server.
- MCP serverUse Formstep from Claude, ChatGPT, Cursor and other MCP clients.
- Webhook API referencePayload schema, event types, signing, retries, and REST subscription endpoints.
Endpoint
The REST API has one URL. Every call is a POST with a JSON body that names the method and its parameters.
Authentication
Send an API token as a bearer token in the Authorization header. A token reaches the
one workspace it was created in. Create one from OAuth and API Keys in the workspace sidebar.
curl -X POST https://api.formstep.io/api/v1 \
-H "Authorization: Bearer fs_..." \
-H "Content-Type: application/json" \
-d '{"method": "forms.list", "params": {}}'const res = await fetch('https://api.formstep.io/api/v1', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.FORMSTEP_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ method: 'forms.list', params: {} }),
})
const data = await res.json()import os, requests
res = requests.post(
"https://api.formstep.io/api/v1",
headers={"Authorization": f"Bearer {os.environ['FORMSTEP_TOKEN']}"},
json={"method": "forms.list", "params": {}},
)
data = res.json()Keep tokens on the server
Never put a token in browser code. Call the API from your backend.
Request and response
The body has two fields: method and params. Every method and its parameters are in the
API reference.
{
"method": "forms.list",
"params": { "workspaceId": "abc123..." }
}Every response has an ok field. On success, the result is in data. On failure, error holds a
code, a message, and usually details.reason, which says what to fix. The codes and reasons are
listed in the error reference.
{ "ok": true, "data": { ... } }
{ "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Field 'name' is required." } }Rate limits
120 calls a minute per token, shared with the MCP server.
requests.createanddocuments.createalso share a limit of 60 calls a minute per token.
A call over a limit fails with 429 RATE_LIMITED and details.retryAfterMs. Wait that long, then retry.