Get API key
Guides / Idempotency

Idempotency

Networks drop. Timeouts happen. 503s happen. Idempotency keys make POSTs safe to retry without creating duplicate shipments.

The Idempotency-Key header

Send a unique Idempotency-Key on every POST — UUID v4 recommended. The first request is processed normally and the result is cached against the key; subsequent calls with the same key return the cached response without re-running the operation.

bash
curl https://merdiexpress.com/api/v1/shipments \
  -H "Authorization: Bearer mk_test_rh9ABekJfP31cN7sQ8jKvLwY" \
  -H "Idempotency-Key: 5f3c7a44-2d2b-4f63-a8b1-9c0f1d8e7b62" \
  -H "Content-Type: application/json" \
  -d '{ "service_tier_id": "HKASTDGGSTCM", "recipient": {...}, ... }'

# Same key + same body → identical response, no duplicate shipment.
# Same key + different body → 409 Conflict (sys_code 1409002)

Per-endpoint requirement

Not every mutating endpoint needs an Idempotency-Key. Create-style endpoints (which mint a new resource / debit the wallet) require it; endpoints that are naturally idempotent (delete, cancel, rotate) treat it as optional.

EndpointIdempotency-KeyWhy
POST /api/v1/shipmentsREQUIREDCreates a shipment & debits the wallet — retries must not duplicate.
POST /api/v1/webhooksREQUIREDCreates a new webhook endpoint — retries must not duplicate.
DELETE /api/v1/webhooks/{id}OPTIONALNaturally idempotent — deleting twice has the same effect.
POST /api/v1/shipments/{id}/cancelOPTIONALNaturally idempotent — cancelling an already-cancelled shipment is a no-op.
POST /api/v1/webhooks/{id}/rotateOPTIONALNaturally idempotent — converges on resource state, safe to retry.

24-hour window

Cached responses live for 24 hours. After that, the same key is treated as a fresh request.

Conflicts

Same key, different body → rejected with 409 (sys_code 1409002). The error message includes a digest of the original body so you can identify the mismatch.