Reference
API reference
Everything you need to integrate with the submission endpoint. There's exactly one URL and three methods.
Endpoint
POST
/f/:formIdSubmit a form. Form ID is the public 8-char key (or custom slug) shown in your dashboard.
GET
/f/:formIdIn a browser, renders the hosted form page (when one exists) or a friendly “API-only” notice. From a non-browser client, returns 405.
/f/:formIdCORS preflight. Returns 204 with permissive CORS headers.
Accepted content types
application/x-www-form-urlencoded— standard HTML form POSTs.multipart/form-data— HTML form POSTs that include file inputs.application/json— programmatic submissions fromfetch/ clients.
Response shape
We return JSON when the request's Accept header asks for it (or when there's no text/html in the Accept). Browser navigations get a redirect or a styled HTML response instead.
Successful JSON response (200 OK):
json
{ "ok": true, "message": "Submission received" }Error JSON response (4xx or 5xx):
json
{ "error": "Form not found or inactive." }Status codes
| Status | Meaning | When |
|---|---|---|
200 | OK | Submission accepted and queued for delivery. |
302 | Found | Browser submitted the form and _redirect / _next is set. |
400 | Bad Request | Submission is empty after stripping control fields. |
404 | Not Found | Form ID doesn't exist or has been deactivated. |
405 | Method Not Allowed | Method other than POST/OPTIONS without a hosted form. |
410 | Gone | Owner account is scheduled for deletion. |
429 | Too Many Requests | Rate limit hit (per-IP, per-form, or per-account-month). Retry-After header tells you when. |
500 | Server Error | Unexpected error. Submission was not stored. |
Headers we set
| Field | Type | Description |
|---|---|---|
Access-Control-Allow-Origin | * | Submit from any origin without proxying. |
Access-Control-Allow-Methods | POST, OPTIONS | Echoed on preflight responses. |
Access-Control-Allow-Headers | Content-Type | All clients need. |
Retry-After | seconds | Returned with 429 responses. |
cURL example
bash
curl -X POST https://formto.email/f/YOUR_FORM_ID \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "ada@example.com",
"message": "Hello!",
"_subject": "New homepage lead"
}'No API keys
The endpoint is intentionally public. Your form ID is the only piece of information needed to submit. Pair it with the honeypot, rate limits, and (if needed) per-form deactivation from your dashboard instead of treating the URL as a secret.