Saltar al contenido

Idempotency

Safe retries with Idempotency-Key.

Network blips happen. If you POST an order and the response never arrives, retrying with the same Idempotency-Key gives you the original order back instead of a duplicate.

How it works

  • Pick any string up to 255 chars for the Idempotency-Key header.
  • The first response (any 2xx or 4xx) is cached for 24 hours, scoped to your API key + method + path.
  • Replays return the cached response and add Idempotent-Replayed: true.
  • Replays with a different body return 409 idempotency_error — choose a new key.
  • 5xx responses are NOT cached, so retries can succeed naturally.

Example

First call
POST /v1/orders
X-API-Key: tbz_…
Idempotency-Key: pickup_2026-05-26_carlos_1
Content-Type: application/json

{ … order body … }

→ 201 Created
   { id: 'ord_abc', order_number: 'ORD-042', … }
Same key, same body — safe retry
POST /v1/orders
Idempotency-Key: pickup_2026-05-26_carlos_1

→ 201 Created
   Idempotent-Replayed: true
   { id: 'ord_abc', order_number: 'ORD-042', … }
Same key, DIFFERENT body — conflict
POST /v1/orders
Idempotency-Key: pickup_2026-05-26_carlos_1
Content-Type: application/json

{ … different body … }

→ 409 Conflict
   {
     error: {
       type: 'idempotency_error',
       code: 'idempotency_key_in_use',
       message: 'Idempotency-Key was reused with different request parameters…'
     }
   }

Picking good keys

A good key is unique per logical action. Bad: a random UUID generated on every retry — that defeats the point. Good: a deterministic function of the user intent, e.g. "order:{userId}:{cartId}" or "refund:{orderId}:{amount}".

When to use it

  • Always for POST calls in production.
  • Always for refunds, payments, or anything money-related.
  • Optional but recommended for PATCH and DELETE.