Idempotency-Key makes the retry safe: we recognize the key, and instead of running the request again we return the original response.
Send a key on every write
POST /v1/quotes and POST /v1/quotes/{id}/hosted-link accept an Idempotency-Key header. It’s optional today, and we recommend it on every call. GET requests are naturally safe to repeat and ignore it.
- One key per operation. Generate a new key (a UUID v4 is ideal) when you decide to do something, and reuse that same key for every retry of it.
- Format: 1 to 255 printable ASCII characters. Anything else is
400 IDEMPOTENCY_KEY_INVALID. - Scope: keys belong to the API key that sent them, so two integrations can’t collide.
- Lifetime: 24 hours. After that the key is forgotten and can be used again.
What a retry gets back
“Same request” means the same method, path, query string and body bytes, sent by the same API key acting as the same broker. Serialize the body once and resend those exact bytes; re-serializing can reorder keys or change spacing, and that counts as a different request.
A request we reject before doing any work (a malformed body, a
422, a 429) doesn’t use up its key. Fix the problem and send it again with the same key.
When the response was lost
Very rarely, a request finishes its work but we fail to record the response. The key is then stuck: we can’t replay an answer we don’t have, and we won’t run the request again in case it already took effect. A retry with that key, once the original has been gone for two minutes, gets500 IDEMPOTENCY_RECORD_LOST. It has no Retry-After, because retrying the same key won’t help.
What to do depends on the endpoint:
POST /v1/quotes: the quote may or may not exist, and there’s no way to look it up yet. Create it again with a new key. An extra quote is harmless: nothing is sent to anyone, and it expires on its own. It does count toward your daily quote limit.POST /v1/quotes/{id}/hosted-link: the link may or may not have been replaced. Call it again with a new key; that revokes whichever link is current and gives you a fresh one.
Retry rules
A sketch of a retrying client:
Without a key
A write sent without a key is never deduplicated. Retrying a timed-outPOST /v1/quotes without one can create a second quote, and retrying POST /v1/quotes/{id}/hosted-link replaces the link again, so the first new link you might have stored stops working.