Idempotency
Retry a write safely, when you cannot tell whether the first one landed.
A timeout tells you nothing about whether the request succeeded. Send an
Idempotency-Key and retrying is safe.
curl -X POST https://api.chatform.in/v1/forms/$FORM_ID/responses \
-H "x-api-key: $CHATFORM_SECRET_KEY" \
-H "idempotency-key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{"answers": {"q_email": "maya@northwind.co"}, "complete": true}'Use a fresh UUID per logical operation and reuse it across retries of that operation.
What happens
- First request: processed normally, and its result is stored.
- Same key, same body: the stored response is returned unchanged, with
Idempotency-Replayed: true. Nothing is created twice. - Same key, different body: 422
idempotency_key_reuse. Replaying the first response would hide a bug in your code behind a plausible success. - Same key while the first is still running: 409
idempotency_in_progresswithRetry-After. - The first request failed with a 5xx: the key is released. A 5xx is not an outcome, so a retry is a real retry.
Keys are kept for 24 hours.
Where it applies
POST /v1/forms/{id}/responses, POST /v1/responses/{id}/complete,
POST /v1/forms/{id}/sessions, POST /v1/forms, POST /v1/forms/{id}/publish.
Recording an answer is naturally idempotent — the same answer to the same question overwrites rather than duplicates — so it needs no key.
Webhooks, in the other direction
Deliveries are at-least-once, so your endpoint needs the same property. Record
webhook-id and skip ones you have already handled.