How it works
Include anX-Idempotency-Key header with a unique string on any POST request that creates a resource:
Which endpoints require it
“Optional” means the header is honoured when you send it — replay, payload check and all — but omitting it is not rejected, and the request then executes with no idempotency protection at all. Send one anyway.
Rules
- Maximum length: 100 characters.
- TTL: Idempotency keys are valid for 24 hours.
- Scope: Keys are scoped per company and environment. The same key can be used in sandbox and production without colliding — they’re separate keyspaces.
- Payload check: If you reuse a key with a different request body, the API returns a
409 Conflictwith error codeIDEMPOTENCY_PAYLOAD_MISMATCH. This holds for the whole 24h window and for concurrent requests, not only for retries that arrive shortly after the first one. - Concurrent requests: If a request with the same body and key is already being processed, the API returns a
409 Conflictwith error codeIDEMPOTENCY_CONFLICT. A concurrent request with a different body getsIDEMPOTENCY_PAYLOAD_MISMATCHinstead. - Replay: Once a request completes successfully (
2xx), subsequent retries with the same key return the original status code and body for the remainder of the 24h window. A502 PROVIDER_TEMPORARILY_UNAVAILABLEon a boleto payment is stored and replayed the same way. A payment request with card data, or withCARDin headless mode, is the exception: it returns400 CARD_PAYMENTS_NOT_AVAILABLE_VIA_APIeven when a response is stored for its key.
Card payments are no longer accepted through the API, so a retry of an earlier card payment request with the same
X-Idempotency-Key now returns 400 CARD_PAYMENTS_NOT_AVAILABLE_VIA_API instead of the stored response (201 or 502). Recover that payment with GET /v1/payments/txid/{txId}, or by its externalId: a create request with the same externalId, mode: "hosted" and methods: ["CARD"], no card object or card fields, and a new X-Idempotency-Key returns the existing payment.
