Idempotency
A network failure can leave you unsure whether a POST executed. Send an Idempotency-Key header and any POST becomes safely retryable: the first request runs, its response is stored, and identical retries replay that stored response instead of executing again.
Sending a key
Add the header to any POST. Use a value that uniquely identifies the operation — an order id, a batch id, or a UUID you persist — not a timestamp. Keys are limited to 255 characters; a longer one is 400 idempotency_key_too_long.
curl -s https://api.synexcloud.com/v1/imports \
-H "Authorization: Bearer $SYNEX_API_KEY" \
-H "Idempotency-Key: import-batch-2026-07-12" \
-H "Content-Type: application/json" \
-d '{ "file": "file_00a1b2c3d4e5f607", "target": "pass_00a1b2c3d4e5f607", "rows": 120, "levels": [] }'
Semantics
- The first request executes normally, and its response is stored for 24 hours, scoped to your API key.
- A retry with the same key and same payload returns the stored response — marked with an
Idempotent-Replayed: trueheader — without executing anything. - The same key with a different payload fails with
409idempotency_key_reused. - If the original request is still executing, a concurrent retry fails with
409idempotency_key_in_flight, carrying aRetry-Afterheader — wait that long and retry. - Responses with a
5xxstatus are not stored, so a failed attempt can be retried with the same key. - Responses with a
4xxstatus are stored. Replaying the key returns the same rejection rather than re-validating — a request that was already answered does not get a second verdict. Fix the payload and use a new key. - A replayed body is the original response, so its
error.request_idnames the original request; theX-Request-Idheader always names the current one. See errors.
GET, PUT, PATCH, and DELETE requests ignore the Idempotency-Key
header — they are already safe to retry (GET/DELETE) or apply the same
final state (PUT/PATCH). Only POST writes need a key.
If a request never finished
The 24-hour window covers a stored response. While a request is running, its key is only reserved for the short window advertised in Retry-After. If the request dies mid-flight — a worker evicted, a connection dropped — the reservation lapses on its own instead of answering every later attempt with idempotency_key_in_flight. Retrying the same key after Retry-After either replays a response the original managed to store, or executes for real because it never got that far.
The practical rule: on a 5xx, a timeout, or a dropped connection, retry with the same Idempotency-Key. Honor Retry-After on a 409, and back off exponentially otherwise.
Choosing a key
Derive the key from something that is stable across retries of the same logical operation:
- Good —
order-88213,batch-2026-07-12, a UUID you generate once and persist before the first attempt. - Bad — the current time, a random value regenerated on each retry, or a key reused across genuinely different requests.
This pairs naturally with 5xx retries: on a server error, retry with the same key and exponential backoff (see Errors).