/submit returns follows the same shape: the matching HTTP status code,
plus a JSON body with success: false, a stable code, and a human-readable message.
code is the part worth branching on - it doesn’t change between releases the way
message copy might. If you’re building an agent or any code that needs to react to a
specific failure (retry, prompt for a fix, surface a specific UI state), read code,
not message.
All codes
Using this table
- Humans: match the
codeyour form’s error handler logged (or the one shown in a failed dashboard test send) against this table to find out what went wrong. - Agents: read
codeto self-correct.invalid_access_keymeans re-check the key you wired in;domain_not_allowedmeans the submitting origin isn’t on the form’s allowlist yet;upgrade_requiredmeans the field or feature you’re trying to use is Pro-only. See Troubleshooting & FAQ for the common ones mapped to fixes.
Options reference
The reserved fields and per-form config each error relates to.
Troubleshooting & FAQ
Common issues, mapped to the codes above.