Idempotency
Ordering spends money. If your request times out you cannot know whether the
order was created, and a blind retry risks charging you twice. The
Idempotency-Key header removes that risk.
Where it is required
Section titled “Where it is required”The header is mandatory — not optional — on the two endpoints that spend balance:
Omitting it returns 422 validation_failed.
How to use it
Section titled “How to use it”Generate a unique key per logical operation — a UUID is ideal — and reuse that same key for every retry of that one operation.
curl -X POST https://partner-api.esimfo.com/v1/orders \ -H 'Authorization: Bearer esf_test_at_...' \ -H 'Idempotency-Key: 9f1c4e2a-7b3d-4a58-9c06-2e8f5d1b4a73' \ -H 'Content-Type: application/json' \ -d '{ "items": [{ "package_id": "pkg_tr_3gb_30d", "quantity": 1 }] }'Retry that call with the same key and you get the original order back, not a second one. No extra balance is spent.
What the key means
Section titled “What the key means”Think of the key as naming one intent: “the order for cart #4821”. It is not a request signature and not a deduplication window on the body.
- Same key, same operation — returns the stored result. Safe.
- New operation — new key. Reusing a key across genuinely different orders returns the first order and silently fails to create the second.
If the request failed
Section titled “If the request failed”When an order errors out, the key is released. That is intentional: a rejected order — insufficient balance, a package that went unavailable — is something you fix and resubmit. You can correct the payload and retry with the same key.
Only a successful order locks its key to a result.
Choosing keys
Section titled “Choosing keys”| Approach | Verdict |
|---|---|
uuid() stored next to your cart record |
Best. Survives process restarts. |
| Hash of your own order id | Good, as long as it is unique per attempt to buy. |
uuid() generated at call time |
Broken. A retry generates a new key and orders twice. |
| A timestamp | Broken. Two retries land in different milliseconds. |
The failure mode of the last two is the exact one this header exists to prevent, so persist the key before you make the call.
