Docs Response format & errors
Docs
Response format & errors
PostTo decides how to respond based on one thing: whether your request looks like a plain browser form submission, or an API call.
Two response modes
If your request has no Accept: application/json header — the default for a plain HTML <form> — a successful
submission gets a redirect to a hosted success page, and a failed one gets a rendered error page. This is the zero-JavaScript
path: your form works with no code beyond the HTML tag itself.
Send Accept: application/json and you get JSON back instead, for both success and failure. Use this from a fetch call
if you want to show your own success/error state without a full page reload. Signed-mode (server-to-server) requests always get JSON, since
there's no browser to redirect.
Success response
HTTP 200, with the new submission's ID and its initial status:
{ "id": "sub_01JXF...", "status": "pending" }
status is pending immediately after a successful POST. It updates in the dashboard (and in the webhook payload, if you
have one configured) once spam filtering and delivery finish — usually within a second or two.
Submission statuses
| Status | Meaning |
|---|---|
pending |
Received, being processed |
delivered |
Sent to your destination email |
flagged |
Delivered, but scored as possible spam — worth a glance in the dashboard |
held |
Blocked by spam filtering, not delivered automatically — reviewable and releasable from the dashboard |
unscored |
Delivered; AI spam classification was skipped or unavailable, so only the baseline check ran |
failed |
Delivery to your inbox failed after retries — retry manually from the dashboard |
Error response
A non-2xx status, with a machine-readable code and a human-readable message:
{ "error": "rate_limited", "message": "Too many requests. Please wait a moment and try again." }
error, never on message. error is a stable code that won't change
wording or language; message is just for humans and may be reworded at any time.
Error codes
| Code | HTTP status | Meaning |
|---|---|---|
not_found |
404 | The token in the URL doesn't match any endpoint |
endpoint_paused |
403 | The endpoint has been paused by its owner |
endpoint_unverified |
403 | The destination email hasn't been verified yet |
origin_not_allowed |
403 | The request's Origin header isn't in the endpoint's domain allowlist |
invalid_signature |
401 | Signed mode: the HMAC signature is missing, wrong, or expired |
turnstile_failed |
403 | Cloudflare Turnstile human verification failed |
quota_exceeded |
402 | The account's monthly submission quota has been reached |
empty_submission |
422 | The request body had no fields in it |
rate_limited |
429 | Too many submissions in a short window — see Rate limits |
Try it against your own form
Create an endpoint and get a working URL in under a minute — free plan, no credit card.
Start for free