Skip to main content
Cresora Commerce
Core Concepts

Idempotency

How to safely retry failed requests without creating duplicate charges.

Idempotency lets you retry a failed API request with confidence that Cresora will not create a duplicate charge.

How it works

Include an Idempotency-Key header with a client-generated UUID on every state-mutating request:

-H "Idempotency-Key: idem_550e8400-e29b-41d4-a716-446655440000"

Cresora stores the key and the result for 24 hours, scoped to your partner account. If you retry with the same key:

  • The original result is returned immediately — no second transaction is created
  • The HTTP status code is the same as the original response
  • An X-Idempotent-Replay: true response header indicates the cached result was returned

Key format

1–128 characters of letters, digits, . _ : -. Anything else is rejected with 400 validation_error — note that padded base64 (+ / =) is not accepted, base64url is. A UUIDv4 is the recommended form:

"Idempotency-Key": "idem_" + crypto.randomUUID()
⚠Warning

Reserved prefixes are rejected with 400 idempotency_key_reserved: hpp:, hpp-contract: and recurring: (Cresora's own server-minted keys), and rb:, inv-charge:, inv-installment: (reserved by the payment gateway). Don't namespace your keys with a trailing colon that lands in one of these.

Conflict detection

If you use the same key with a different request body, Cresora rejects the retry with 422 idempotency_key_reused:

{ "code": "idempotency_key_reused", "message": "Idempotency key already used with a different request body." }

This is intentional — it prevents accidentally reusing a key that was already tied to a different payment. (A separate code, 409 idempotency_key_conflict, appears only on a few non-payment create endpoints — API keys, users, webhook subscriptions — for their own duplicate-create detection.)

🔒Required everywhere — sandbox included

Idempotency-Key is required on every write — POST /api/v1/transactions and the other POST/PATCH operations — in the sandbox exactly as in production. A missing header returns 400 idempotency_key_required. There is no sandbox exemption.

Which endpoints require it?

EndpointIdempotency-Key
POST /api/v1/transactions (all types — SALE, REFUND, CAPTURE, …)Required
Other POST/PATCH write operationsRequired
GET requestsNot applicable
DELETE requestsNot required — DELETE is idempotent at the HTTP level (RFC 9110)