Error codes
Formcrest returns a stable, machine-readable error code with every failure. Codes are part of the public contract and stay backwards-compatible, so it is safe to branch on them.
The error envelope
When a request is made in JSON mode (see the submit reference), an error returns the HTTP status from the table below and this body:
{
"error": "<code>",
"message": "Human-readable explanation.",
"fieldErrors": { "email": "..." }
}error— the stable code, one of the values below. Branch on this, not on the message text.message— a human-readable explanation. Wording may change; do not parse it.fieldErrors— present only when specific fields failed validation; maps each field name to a reason.
HTML form redirects
A traditional HTML form post does not receive the JSON envelope. Instead, when the form has an error URL configured, the visitor is redirected to it with the code appended as a query parameter:
HTTP/1.1 303 See Other Location: https://example.com/error?error=quota_exceeded
Read the ?error=CODE value on your error page to show a relevant message. To get the JSON envelope instead of a redirect, send Accept: application/json. See HTML installation for the redirect flow.
Errors a form submitter will hit
These are the codes most relevant when submitting a form. They cover a missing or disabled form, blocked origins, oversized or over-quota submissions, throttling, failed spam checks, and a form with nowhere to deliver.
| Code | HTTP status | Meaning |
|---|---|---|
not_found | 404 | No form exists for the given form ID. Check the ID in your endpoint URL. |
form_inactive | 403 | The form is no longer accepting submissions — it was disabled, or its owner's account is suspended or deleted. |
domain_not_allowed | 403 | The request's origin or referer is not on the form's allowed-domains list. |
form_no_destinations | 412 | The form has no verified destination email to deliver to, so a real submission cannot be accepted. |
payload_too_large | 413 | The submission body exceeds the size limit (256 KB of field data). |
quota_exceeded | 402 | The owner's monthly submission quota is used up. See Plans. |
rate_limited | 429 | Too many requests from this client in a short window. Slow down and retry later. |
turnstile_failed | 400 | Cloudflare Turnstile verification failed — the cf-turnstile-response token was missing or invalid. |
honeypot_caught | 400 | The honeypot field was filled in, so the submission was rejected as spam. |
validation_failed | 422 | The request body was malformed or used an unsupported content type. May include fieldErrors. |
Note that Turnstile and honeypot failures are usually handled silently for legitimate-looking traffic — see Spam protection for how filtered submissions are treated.
Full catalog
The complete set of codes the API can return, including account, authentication, and billing errors surfaced through the dashboard.
| Code | HTTP status | Meaning |
|---|---|---|
unauthorized | 401 | Authentication is required for this action. |
forbidden | 403 | You don't have permission to perform this action. |
not_found | 404 | The requested resource does not exist. |
validation_failed | 422 | The request payload is invalid or the content type is unsupported. |
rate_limited | 429 | Too many requests. Slow down and retry. |
internal_error | 500 | Something went wrong on our end. Retry later. |
not_implemented | 501 | This feature is not yet available. |
invalid_credentials | 401 | The email or password supplied at sign-in was incorrect. |
email_not_verified | 403 | The email address must be verified before continuing. |
account_suspended | 403 | The account is suspended. |
account_locked | 429 | Too many failed sign-in attempts; the account is temporarily locked. |
email_in_use | 409 | An account already exists with that email address. |
weak_password | 422 | The chosen password is too weak. |
form_inactive | 403 | The form is no longer accepting submissions. |
form_no_destinations | 412 | The form has no verified destination emails. |
domain_not_allowed | 403 | Submissions from the request's domain are not allowed. |
payload_too_large | 413 | The submission payload exceeds the size limit. |
quota_exceeded | 402 | The monthly submission quota has been exceeded. |
honeypot_caught | 400 | The submission was rejected by the honeypot spam trap. |
turnstile_failed | 400 | Turnstile verification failed. |
destination_limit_reached | 402 | The destination-email limit for the current plan is reached. Add a top-up or upgrade. See Plans. |
billing_unconfigured | 503 | Billing is not configured for this deployment. |
Related
- Submit API reference — the endpoint, headers, and response shapes.
- Spam protection — honeypot and Turnstile behavior.
- FAQ — common questions and troubleshooting.