Idempotency
The Flowlix API supports idempotency for safely retrying requests without performing the same operation twice. This is critical for payment processing, where network issues or timeouts can leave you unsure whether a request succeeded.How it works
Include anIdempotency-Key header with a unique value on any POST request:
Behavior
- First request — Flowlix processes the request normally. If the
response status is
2xx, the body is stored against the idempotency key. If the response is4xxor5xx, nothing is cached, so the same key may be retried. - Retry with the same key and the exact same body — Flowlix returns
the stored response. The status code, body, and content-type are
replayed from cache; per-request headers (
Flowlix-Request-Id,X-RateLimit-*) are regenerated for the retry, so they will not match the original response. - Retry with the same key but a different body — Flowlix returns
409 Conflictwith codeidempotency_key_in_use. You cannot reuse a key with different parameters. - Retry while another request with the same key is still in flight —
Flowlix returns
409 Conflictwith codeidempotency_key_in_useand the message “A request with this idempotency key is currently being processed.” Wait briefly and retry.
Only successful (
2xx) responses are cached. If a request fails with a
client or server error, the idempotency slot is released, so you can
immediately retry the same key with the same — or even a corrected — body.Key requirements
| Rule | Detail |
|---|---|
| Format | Any string up to 255 characters. Random UUIDv4 works for one-shot requests; deterministic keys work for business-bound retries (see below). |
| Scope | Keys are scoped to the API key value used in the request. Rotating an API key resets the idempotency namespace. |
| Expiration | Keys expire after 24 hours. Cleanup runs hourly, so an entry can persist briefly past its TTL but is otherwise removed. |
| Applicable methods | Honored only on POST requests to /v1/*. On other methods the header is ignored — GET is naturally idempotent, so no key is needed. |
Generating keys
For one-shot requests (e.g. a checkout button), a random UUIDv4 is fine:Conflict errors
If you reuse an idempotency key with a different request body, or another request with the same key is still in flight, you get a409 Conflict:
message is instead:
code: "idempotency_key_in_use" and HTTP 409.
Best practices
- Always use idempotency keys for payment creation and refund requests.
- Generate a new key for each distinct operation — do not reuse keys across different payments or refunds.
- Use deterministic keys for retries — if retrying a failed request, use the same key as the original attempt and resend the exact same body.
- Do not regenerate the key on each retry — that defeats the purpose. The key must be the same across all attempts of the same operation.
- Store the key alongside the operation in your database so you can retry consistently, even after restarts.
- Treat
409 idempotency_key_in_usedifferently depending on the message: a body mismatch is a bug in your retry logic; an “in flight” conflict can simply be retried after a short delay.
Retry strategy
A recommended retry strategy for payment requests:- Generate an idempotency key for the operation (random UUIDv4 or deterministic).
- Send the request.
- If you get a network timeout or
5xxerror, wait and retry with the same idempotency key and the same body. - Use exponential backoff: wait 1s, 2s, 4s, 8s, up to a maximum of 30s.
- After 3-5 retries, stop and alert your operations team.
