Troubleshooting
Fixes for CORS errors, origin mismatches, challenge_required, 429s, unknown fields and quota errors.
Start with the response. Every answer from Ikiform has an X-Request-Id header and, for errors, a stable error.code. This curl shows both, from the same origin your site would send:
curl -i https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Origin: https://example.com" \
-d '{"email":"ada@example.com"}'Seeing 5xx errors or timeouts from Ikiform itself? Check status.ikiform.com for current incidents first.
The browser says CORS blocked the request
The submission endpoint allows every origin, so a real CORS failure usually means the request never reached Ikiform, or went to the wrong URL.
- Check the URL is
https://ikiform.com/f/<formId>with the fullfrm_id, for examplefrm_xxxxxxxxxxxxxxxx, and no trailing path. - You are calling
/api/v1from a browser. The REST API refuses browsers by design; call it from your server. - An ad blocker, privacy extension or corporate proxy blocked the request. Try a private window without extensions.
- Your site's own
Content-Security-Policyblocks it. Addhttps://ikiform.comtoconnect-src, and toform-actionfor plain HTML posts.
Check the preflight directly; it should answer 204 with your origin echoed back:
curl -i -X OPTIONS https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type"Submissions land in spam with origin_mismatch
The form has allowed domains and the post came from somewhere else. The dashboard shows origin_mismatch among the spam reasons.
- Add every domain the form is served from, including
www, staging and preview domains. Subdomains of a listed domain already match. - Add
localhostwhile developing locally. - Posts from your own server carry no
Origin. Send a secret key, which skips the check. - With Reject chosen instead of Mark as spam, the same posts get
403 origin_not_allowed.
403 challenge_required
The form's spam check is set to Ikiform and the post had no Turnstile token.
- Browser code: call
challenge(formId)from the SDK right before each submit, and pass the token tosubmitasturnstileToken. - Server code: send
Authorization: Bearer ik_sk_...with a secret key; secret keys skip the check. - Plain HTML posts never see this code; they get the check page instead. If you see it from a form post, something is sending
Accept: application/json. - Testing with curl? Turn the check off for a test form, or use a secret key.
403 captcha_failed means a token was sent but didn't verify. Tokens are single use and expire after 300 seconds, so get a new one for every attempt.
429 rate_limited
- Read
Retry-Afterand wait that many seconds. - Testing by hand? The Standard preset allows 5 posts a minute from one IP, and 3 in 10 seconds. Switch a test form to Relaxed.
- Posting from your server for every visitor? All posts share your server's IP. Post from the browser, or choose Relaxed or Custom.
- Many people behind one office or event network share an IP too. Relaxed allows 20 a minute.
422 with Unknown field
The form has fields defined and the post sent a name that isn't in the definition. error.fields names it, for example { "website": ["Unknown field \"website\""] }.
- Add the field to the definition, or remove the input.
- Rename the input to start with
_if it is only a marker for you; reserved names are dropped, not validated. - Check that the honeypot name matches the form's Honeypot field setting.
- Field ids are lowercase snake_case:
firstNamein your markup is not the same asfirst_namein the definition.
429 quota_exceeded
The workspace received 2 times its monthly limit this month and stops accepting submissions until the next month starts or the workspace upgrades. See Monthly usage.
Submissions don't show up
- Look under the spam filter. Spam gets a normal success response, so the visitor can't tell.
- Check the form isn't paused, and that the id in your
actionmatches the dashboard. - A browser post that shows Ikiform's error page was rejected; the page lists the reason.
Webhooks fail
no_matching_signature: verify against the raw body, before any JSON parsing, and check you copied the rightwhsec_secret. Paste a delivery into the verifier.timestamp_too_old: your server clock is off, or you are replaying an old delivery.- Timeouts: answer within 15 seconds and do slow work afterwards.
- Redirects aren't followed. Use the final URL, including the trailing slash your framework expects.
- The endpoint was disabled after 5 days of failures or a
410. Fix it, then turn it back on from the endpoint page.