Documentation
Submissions API
Read your forms and submissions from your own code. Available on the Pro and Agency plans. For creating and configuring forms instead of just reading them, see the write API.
Authentication
Create a key in Settings → API keys - it is shown once and stored only as a hash, so save it when you create it. Authenticate with a bearer token or the X-API-Key header. Keys are secret: keep them on a server, never in client-side code.
curl https://api.webforms.to/v1/submissions \ -H "Authorization: Bearer wf_live_your_key"
Or equivalently:
curl https://api.webforms.to/v1/submissions \ -H "X-API-Key: wf_live_your_key"
Every key is scoped to a workspace and a set of permissions (scopes) fixed when it is created. Read keys default to submissions:read and forms:read.
GET /v1/forms
List the forms in your workspace.
{
"ok": true,
"data": [
{ "id": "frm_...", "name": "Contact form", "publicKey": "wft_...", "isTestMode": false, "createdAt": "2026-08-16T20:00:00.000Z" }
]
}GET /v1/submissions
List submissions, newest first, across the workspace or one form.
{
"ok": true,
"data": [
{
"id": "sub_…",
"formId": "frm_…",
"data": { "email": "jane@example.com", "message": "Hi" },
"files": [],
"meta": { "submittedAt": "2026-08-16T20:00:00.000Z", "ip": "…" },
"spamScore": 0,
"status": "new",
"tags": [],
"createdAt": "2026-08-16T20:00:00.000Z"
}
],
"pagination": { "limit": 25, "hasMore": true, "nextCursor": "…" }
}Query parameters:
form_idRestrict to one form.statusComma-separated: new, quarantined, spam. Quarantined and spam are excluded by default - ask for them explicitly.limit1-100, default 25.cursorOpaque pagination cursor from the previous response's nextCursor.include_testInclude submissions marked with _test.
GET /v1/submissions/:id
Fetch a single submission by id, same shape as a list item.
Pagination
Cursor-based, not offset. Pass the previous response's nextCursor value back as cursor to fetch the next page, and stop when hasMore is false. Cursors are stable as new submissions arrive, so a walk never skips or repeats a row - unlike an offset, which drifts on a table that new rows are constantly appended to.
Rate limits
120 requests per minute per key. Every response carries X-RateLimit-Remaining and X-RateLimit-Reset. Revoking a key in the dashboard takes effect immediately - no propagation delay.
Get your endpoint
Free for 300 submissions a month. No card required.
Start free