Idempotency
Send an Idempotency-Key on every POST so a retry never runs twice and never bills twice. How long keys last and what to do on a conflict.
Networks drop replies. If your call to POST /reports times out, you do not know whether the report was ordered. If you send it again you may order, and pay for, two.
An idempotency key fixes this. Send the same key with the retry and we return the first response instead of running the call again. There is no second charge.
#How to use it
Add the header Idempotency-Key to every POST. Use a fresh random value for each new action (a UUID is fine) and reuse it only to retry that same action.
curl -X POST https://adv.heliosynctech.com/api/v1/reports \
-H "Authorization: Bearer $AOS_KEY" \
-H "Idempotency-Key: 0d1a6f5e-6b43-4c8b-9a2a-3c1c1f6e0b11" \
-H "Content-Type: application/json" \
-d '{ "type": "litigation_check", "subject": { "kind": "person", "name": "Sandbox Lender" } }'
import { randomUUID } from "node:crypto";
const key = randomUUID(); // make it once per action, keep it for the retries
async function orderReport() {
return fetch(`${process.env.AOS_API_BASE}/reports`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AOS_KEY}`,
"Idempotency-Key": key,
"Content-Type": "application/json",
},
body: JSON.stringify({ type: "litigation_check", subject: { kind: "person", name: "Sandbox Lender" } }),
});
}
import os, uuid, requests
key = str(uuid.uuid4()) # make it once per action, keep it for the retries
res = requests.post(
f"{os.environ['AOS_API_BASE']}/reports",
headers={"Authorization": f"Bearer {os.environ['AOS_KEY']}", "Idempotency-Key": key},
json={"type": "litigation_check", "subject": {"kind": "person", "name": "Sandbox Lender"}},
timeout=30,
)
#The rules
- Window: a key is remembered for 24 hours, per account. In that time the same key returns the stored response.
- No second charge: a replay is free. You are billed once, for the first call. A request with a key over 255 characters is refused with
invalid_idempotency_key. - Same key, same request: if you reuse a key with a different body or path, you get
409withidempotency_key_reused. Make a new key. See errors. - Still running: if the first call has not finished, you get
409withidempotency_in_progress. Wait and send the same request again. - What is stored: the response of a call that succeeded. A replay carries the header
Idempotent-Replayed: true. A call that failed is not stored, and was free, so after you fix the request you can send it again, even with the same key. - Only POST:
GETandDELETEare safe to repeat and ignore the header.
Keys are scoped to the account, and to test or live mode.
#Retrying safely
- Make the key before the first attempt.
- If you get a timeout, a
429, a500or a503, send the same request with the same key after a pause. See rate limits. - Stop on
400,401,402,403and404: a retry will not change them. - Save the key with your own record of the order, so a restart can retry the right call.