REST API
Manage your forms and submissions programmatically with an API key.
Available on the Pro plan and above.Read your forms and submissions, and — with a read & write key — delete submissions or pause and rename forms. (To submit to a form, see the submission API, which needs no key.)
Authentication
- Create a key under Account → API keys. The full key (
sf_live_…) is shown once — copy it then. - Send it as a bearer token on every request. Keys are scoped to one team.
curl https://api.simplyforms.dev/v1/forms \
-H "Authorization: Bearer sf_live_your_key_here"Keep keys secret and server-side — anyone with a key can read the team's data. Revoke a leaked key immediately from the dashboard.
Permissions
Every key carries a permission scope, chosen when you create it and fixed for the life of the key:
- Read-only (default) — the
GETendpoints below. - Read & write — also allows the write endpoints.
There is no way to add write access to an existing key — mint a new one instead, so a key can never gain power after it's been handed out. Use a read-only key anywhere you only need to pull data (analytics jobs, dashboards); if it leaks, it can't change anything. A read-only key calling a write endpoint returns 403.
Base URL & responses
Base URL: https://api.simplyforms.dev/v1. Every response is JSON wrapped in an envelope:
{ "success": true, "data": … }
// errors:
{ "success": false, "error": "message", "statusCode": 404 }Endpoints
GET /forms
List your team's forms.
{ "success": true, "data": [
{ "id": "…", "name": "Contact", "short_id": "abc123", "created_at": "…" }
] }GET /forms/:formId
Get one form (including its field configuration).
GET /forms/:formId/submissions
List a form's submissions, newest first, with the payload decrypted.
{ "success": true, "data": {
"items": [
{ "id": "…", "created_at": "…", "is_spam": false,
"data": { "email": "jane@example.com", "message": "Hi" },
"file_metadata": null }
],
"next_cursor": "2026-07-05T12:00:00.000Z"
} }GET /submissions/:submissionId
Get one submission (decrypted).
GET /workspaces
List your team's workspaces.
{ "success": true, "data": [
{ "id": "…", "name": "Default", "created_at": "…" }
] }GET /usage
Your current billing-period submission usage against the plan limit — useful for alerting before you hit the cap (at the cap, new submissions are paused until the period resets). The period is a calendar month in UTC, and the count includes submissions flagged as spam, matching what the limit actually enforces. submissions_limit and remaining are null on unlimited plans.
{ "success": true, "data": {
"period_start": "2026-08-01T00:00:00.000Z",
"period_end": "2026-09-01T00:00:00.000Z",
"submissions_used": 428,
"submissions_limit": 10000,
"remaining": 9572
} }Write endpoints
These require a key created with the Read & write permission; a read-only key returns 403. Writes have their own tighter rate limit (see below).
DELETE /submissions/:submissionId
Permanently delete a submission and any files uploaded with it — useful for automating retention or fulfilling erasure requests. This cannot be undone.
curl -X DELETE https://api.simplyforms.dev/v1/submissions/SUBMISSION_ID \
-H "Authorization: Bearer sf_live_your_key_here"
{ "success": true, "data": { "id": "…", "deleted": true } }PATCH /forms/:formId
Rename a form or pause/resume it. Send either field, or both. A paused form (is_active: false) stops accepting submissions. Editing a form's fields isn't available through the API — use the builder.
curl -X PATCH https://api.simplyforms.dev/v1/forms/FORM_ID \
-H "Authorization: Bearer sf_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Contact (archived)","isActive":false}'
{ "success": true, "data": { "id": "…", "name": "Contact (archived)", "is_active": false } }Pagination
limit— page size, 1–100 (default 50).before— pass the previous response'snext_cursorto get the next page.- When
next_cursorisnull, you've reached the end.
curl "https://api.simplyforms.dev/v1/forms/FORM_ID/submissions?limit=50&before=2026-07-05T12:00:00.000Z" \
-H "Authorization: Bearer sf_live_your_key_here"Rate limits & security
- Requests are rate-limited per key (roughly 120/minute). Exceeding it returns
429. - Write requests have a separate, tighter budget (roughly 30/minute) — reads and writes don't share a bucket.
- An unknown, revoked, or expired key returns
401; a plan without API access, or a read-only key on a write endpoint, returns403. - Keys only ever access their own team's data; anything else returns
404. - Sensitive values (card / SSN-like fields) are masked in responses, exactly as in the dashboard and CSV export.