Skip to content
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." }
Build your integration to branch on 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