Send an Idempotency-Key header on a write and a retry with the same key and the same body replays the original response instead of doing the work twice. Use this whenever a request might time out or your network might drop before you see the response.
When do I need an idempotency key
Section titled “When do I need an idempotency key”It is required on POST /inventory/adjustments and POST /inventory/batch, because replaying a relative change would move stock twice. A request without it answers 400 VALIDATION_FAILED naming the Idempotency-Key header. It is optional on the other writes that accept one: PUT /products/{id}/inventory/{outlet_id}, POST /products, POST /products/{id}/variants, POST /customers, and the create calls for brands, categories, tags and suppliers. PATCH and DELETE do not take one. Pick a key that is unique per logical operation, such as a UUID you generate once per attempt, and reuse it only when retrying that same attempt. A key is 1 to 255 printable characters with no spaces.
curl https://api.oletapp.com/your-store/v1/inventory/adjustments \ -H "Authorization: Bearer olet_live_YOUR_API_KEY" \ -H "Idempotency-Key: YOUR_UNIQUE_KEY" \ -H "Content-Type: application/json" \ -d '{"product_id": "PRODUCT_ID", "outlet_id": "OUTLET_ID", "reason_id": "REASON_ID", "quantity": 1}'await fetch('https://api.oletapp.com/your-store/v1/inventory/adjustments', { method: 'POST', headers: { Authorization: 'Bearer olet_live_YOUR_API_KEY', 'Idempotency-Key': crypto.randomUUID(), }, body: JSON.stringify({ product_id: 'PRODUCT_ID', outlet_id: 'OUTLET_ID', reason_id: 'REASON_ID', quantity: 1, }),})What happens on a retry
Section titled “What happens on a retry”A retry with the same key and the exact same request body returns the same status code and the same resource data as the first attempt, without repeating the underlying change. The response carries an Idempotent-Replayed: true header so you can tell a replay from an original.
A request that failed with a client error replays that same failure, so fix the request and send it again under a new key. A 500 is not remembered, so you can retry it with the same key. Keys are remembered per credential.
If a request with that key is still being processed, a retry answers 409 IDEMPOTENCY_IN_PROGRESS. Wait and try again.
What happens if the body changes
Section titled “What happens if the body changes”Reusing a key with a different request body answers 422 IDEMPOTENCY_KEY_REUSED. This is a signal that you generated a key once and are now sending two different operations under it; use a new key per logical operation.
A key stops being remembered after 24 hours, after which point reusing it starts a fresh operation rather than replaying the old one.
Where to go next
Section titled “Where to go next”See errors for the full list of error codes, or the full API reference for which operations accept a key.