Skip to main content
Network failures happen. A timeout or server error does not prove that a POST failed before creating a charge, withdrawal, or other resource. An Idempotency-Key identifies retries of the same operation so the server can avoid duplicate effects while that key is retained.

How it works

Send an Idempotency-Key on a public POST or PATCH request to a /v1/ endpoint. Use one key for one business operation and persist it before submitting the request. A retry of that operation uses the same key, API key, acting account, method, path and body.
  1. Bachs executes the first request.
  2. A successful JSON response is cached for 24 hours from when it is stored.
  3. A matching retry returns the cached body and status without running the handler again. Reading a cached response does not extend its lifetime.
A timeout or 5xx leaves a write’s outcome uncertain. Only successful responses are cached, so the absence of a cached response does not prove that a write had no effect. Check the operation’s state before repeating it or creating a replacement with a new key. See Handling errors.

Using the header

This is an illustrative sandbox request. Keep its key for retries of this operation; generate a different key for a separate checkout.

Scope and caching

A 4xx or 5xx response is not cached by this middleware. Handle validation errors before trying again. For an uncertain write, reconcile its actual state before repeating it; keeping the same key is part of recovery, not proof that every failed exchange is safe to repeat. If the original request is still running, a retry can return 409 IDEMPOTENCY_IN_PROGRESS. Wait briefly and retry the same operation with the same key. When a key’s response has expired, it no longer protects against a new execution; reconcile before resubmitting an old operation.

Fingerprint mismatch 409

Each idempotency key is bound to the exact request it was first used with (method + path + body). If you reuse a key with a different request body, you will receive 409 with IDEMPOTENCY_CONFLICT:
This protects against accidentally reusing a key for a different operation. If you receive this error, generate a new unique key for your new request.

Choosing good keys

Good

Tied to a specific business operation:
  • order_ORD-12345
  • withdrawal_2026-05-14_batch-3_item-7
  • checkout_usr_abc_session_xyz

Avoid

Keys that could collide or repeat:
  • Random UUIDs regenerated on each retry (defeats the purpose)
  • Timestamps alone (collide under load)
  • Generic strings like retry_1

Recover an uncertain write

  • Keep the original operation ID, Idempotency-Key, request body and acting account in your records.
  • For a timeout or 5xx, retrieve or reconcile the operation. For a withdrawal, use Get Payout or List Payouts.
  • If you confirm a retry is needed, reuse the original key and unchanged request. Follow Retry-After on rate-limit errors and wait briefly on IDEMPOTENCY_IN_PROGRESS.
  • If you cannot establish the outcome, investigate or contact support with the request ID. Do not create a replacement operation with a fresh key solely because the first response was lost.