Skip to main content
Networks fail. If a POST times out you can’t tell whether it ran. Send an Idempotency-Key header and you can retry it without starting a second top-up or paying an invoice twice.
The key is any string up to 255 characters that is unique to one logical operation. A UUID v4 works well, as does an id from your own system, such as topup-2026-10-week-42.

Which requests use it

Without the header, a required endpoint returns 400 idempotency_key_required. PUT replaces the whole set it targets, so repeating it is already safe.

How it works

Keys are scoped to your API key: two different API keys can use the same Idempotency-Key without colliding.
  1. First request. ChargeExpress records the key with a hash of the method, path and JSON body, runs the request, and stores the response.
  2. Same key, same request. You get the stored status code and body again, with the header Idempotent-Replayed: true. Nothing runs a second time. The X-Request-Id header is new on each call.
  3. Same key, different request. If the method, path or body differ, you get 422 idempotency_key_reused. Use a new key.
  4. Same key while the first is still running. You get 409 idempotency_key_in_progress. Wait a moment and retry with the same key.

What is stored, and for how long

  • Responses with a status below 500 are stored for 24 hours, apart from 429. That includes 4xx errors: retrying a request that failed validation with the same key returns the same error. Fix the request and use a new key.
  • 5xx and 429 responses are not stored. The key is released, so retrying with the same key runs the request again.
  • If the connection drops before a response is produced, the key is also released.
  • After 24 hours the key can be used again as if it were new.

Top-ups and the idempotency key

For POST /wallet/fundings and POST /invoices/usage/pay, the Idempotency-Key also determines the funding’s id (wallet-…). This protects against double payment even after the 24-hour window:
  • Sending the same key again for a funding that is still pending returns that same funding and its checkout_url.
  • Sending the same key again for a funding that has completed or failed returns 409 conflict.
  • Sending the same key with a different amount returns 422 idempotency_key_reused within 24 hours, and 409 conflict after that.
Use a fresh key for every new top-up.

Recommendations

  • Generate the key before the first attempt and persist it with the operation, so a restarted worker retries with the same key.
  • Retry network errors, 409 idempotency_key_in_progress, 429 and 5xx with exponential backoff, keeping the same key.
  • Don’t reuse keys across different operations.