Skip to content

Safe retries (Idempotency-Key)

Networks fail. Your request might reach us and the answer get lost on the way back. If you then send it again, you don’t want two leads or two calls.

So every POST and PATCH takes an Idempotency-Key header:

Terminal window
curl -X POST 'https://v2-api.callview.ai/api/v1/external/leads' \
-u "$CALLVIEW_KEY_ID:$CALLVIEW_SECRET" \
-H 'Idempotency-Key: crm-10442-create' \
-H 'Content-Type: application/json' \
-d '{ "campaign_id": "7c1f2b9e-4a3d-4e8f-9b21-5d6a7e8f9a01", "external_id": "crm-10442", "phone": "+12125557812",
"consent": { "source": "web_form", "agreed_at": "2026-10-06T16:58:02Z", "url": "https://example.com/quote" } }'
  • The key is any text you choose, 1 to 255 visible characters. Use a new one for each new action, and the same one when you retry that action. Something built from your own record works well, like crm-10442-create.
  • The first time we see a key, the request runs and we keep its answer for 24 hours.
  • Send the same key with the same request in that time, and you get the kept answer back, exactly, with the header Idempotent-Replayed: true. Nothing runs again.
  • Send the same key with a different request (another path or another body) and you get 409 idempotency_mismatch.
  • Send it while the first one is still running and you get 409 idempotency_in_progress with Retry-After: 1.

Keys belong to one API key: two of your systems with different API keys can’t clash.

  • 5xx errors and 429 answers are not kept. Retrying with the same key really runs the request again, which is what you want after a hiccup on our side.
  • A request refused before it starts (a bad key, a rate limit, a body that fails the checks) never uses up the key.

If we can’t check a key (very rare), the write is refused with 503 service_unavailable rather than run without the safety net. Retry it.

GET and DELETE don’t need a key: asking twice is always safe.