Troubleshooting & FAQ.
The most common issues and their fixes, followed by frequently asked questions.
“Origin is not allowed for this form” (403)
The browser sent an Origin that is not in the form’s allowlist. Add the exact origin — scheme, host, and port, with no path or trailing slash. For example https://example.com and http://localhost:3000 are different origins.
A CORS error appears in the browser console
CORS errors usually mask a 403. Check the form’s allowlist first. Preflight requests are only answered for allowed origins, and the allowed request headers are Content-Type, Idempotency-Key, and Turnstile-Token.
“A valid idempotency key is required” (422)
Send an Idempotency-Key header with each submission, for example crypto.randomUUID(). Generate one key per submission and reuse it only when retrying that same submission.
My test submission was marked as spam
The honeypot field was filled. Make sure the hidden _website input is empty and is not accidentally autofilled or given a value by your code. Spam submissions return 202 but never send messages.
“Too many submissions for this form” (429)
You hit the per-form, per-IP rate limit (default 20 per 60 seconds). Back off and retry after the Retry-After seconds. If legitimate traffic exceeds the limit, ask your administrator to raise it.
An email or SMS never arrived
First, confirm the submission exists in the inbox and that its delivery rule is set to automatic. Remember that 202 means accepted, not delivered — the worker sends messages after acceptance. Then check that the worker is running, inspect its queue and errors, verify the credentials and recipient format, and review the provider’s logs. The backend and worker must share the same DATA_ENCRYPTION_KEY.
Uploads fail or are rejected
Uploads require an enabled media field on the form and an allowed origin. Check the file size (default 10 MB), the type (magic bytes, extension, and declared MIME must agree), and the workspace storage quota. Errors include a code such as FILE_TOO_LARGE, UNSUPPORTED_FILE_TYPE, or STORAGE_QUOTA_EXCEEDED.
“Form not found or disabled” (404)
The public key is wrong, or the form has been disabled. Copy the endpoint again from the form’s integration panel.
FAQ
Is a plain HTML form POST supported?
No. Submit with JavaScript or from your server so Contact can return JSON and enforce origin and schema rules. See Embedding.
Is the public key safe in browser code?
Yes. The public key identifies the form, not a user. Keep admin keys and integration secrets on the server only.
How do I let a submitter read their submission?
On a first-time success, Contact returns a responseToken and a responseUrl. The submitter can use the token as a bearer token to read that one submission. Store it if you need it — it is shown once.
How long are submissions and files kept?
Retention depends on your workspace configuration. See the Privacy Policy for details, and keep your own copies of anything you must retain.
Can I still get help?
Use our contact page or the delivery guide for provider-specific tips.