Developers

Idempotency

Retry writes safely without applying them twice.

Networks fail. If a write times out you can't tell whether it reached Zaher — and retrying something like "adjust stock by -3" blindly could apply it twice.

Every write endpoint (POST and PATCH) accepts an Idempotency-Key header. Send a unique value per change, and send the same value when you retry it:

curl https://api.zaher.io/v1/products/PRODUCT_ID/variants/VARIANT_ID/stock \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0b8f6d1e-2c3a-4f5b-9e7d-1a2b3c4d5e6f" \
  -d '{ "mode": "adjust", "quantity": -3 }'

How it behaves

SituationResult
First request with a keyRuns normally; the result is kept for 24 hours
Retry with the same key and bodyThe first result is returned again, with Idempotent-Replayed: true. Nothing runs twice
Same key, different body or endpoint409 idempotency_mismatch
Retry while the first is still running409 idempotency_in_progress — wait and retry
The first request failed with a 5xxThe key is released, so your retry runs for real

Results of 4xx errors are kept too: retrying a request that was rejected returns the same rejection.

Choosing keys

  • Use a UUID per change, or derive one from your own data — e.g. shipment-{your shipment id} — so a crashed job that restarts reuses it.
  • Keys are scoped to your store and are up to 255 characters.
  • Don't reuse a key for a different change.

Reads don't need it

GET requests never change anything and are always safe to retry.

On this page