Skip to content

Idempotency & Retries

Every realtime call must carry an Idempotency-Key. It is not a rate-limit courtesy — it is what makes a retry safe. Networks fail after the supplier has already been asked; without a key, the only way to find out whether a check ran is to run it again and pay for it twice.

Send a value you can regenerate: a UUID, an order ID, or a hash of the work you are doing. The server scopes it to your account, so two users cannot collide.

Same keyPayloadResult
New keyanyRuns normally, charged
Same keyidenticalThe stored response is returned; replayed=true. No new charge.
Same keydifferent409 idempotency_conflict — a key is bound to the payload it first carried
Same keyidentical, first call still running409 request_in_progress with Retry-After

Idempotency-Key is limited to 191 bytes and replay records are retained for 30 days by default.

They look similar in a response and mean different things:

FieldWhereMeans
replayedtop levelThis call never reached a supplier — you replayed a key.
cachedinside each resultThis product’s verdict was served from the result cache.

A replayed call reproduces the original response, including each entry’s cached value. Neither flag changes what you were charged: a replay never moves money, and a cache hit is still charged at the product’s per-check price.

Only settled outcomes are stored as facts. Failed and unknown results are not cached — a later check of the same identifier against the same product will ask the supplier again rather than replaying an inconclusive answer.

What you sawWhat to do
Timeout, or HTTP 500Resend the original body with the original key. The outcome is uncertain; this is the case the key exists for.
409 request_in_progressWait Retry-After, then resend the same body with the same key.
409 idempotency_conflictThe key already carries a different payload. Generate a new key — do not edit the body and reuse the old one.
429 realtime_rate_limitedWait Retry-After. Nothing was submitted, so the same key is still unused and safe to send.
503 realtime_route_unavailableNothing was submitted. Retry later, same key.

The one thing never to do after a timeout is to submit a new key with the same work: if the first call did land, you have just paid for the check twice.

HTTPcode
400idempotency_key_required — header missing
409request_in_progress — the original call is still running
409idempotency_conflict — the key was first used with a different payload