Safe Retries When Creating Orders
Audience: developers integrating a merchant's webshop, order system or ERP with Logitrail's Order API, who retry POST /v1/orders after a timeout or an error.
Networks fail, and so do servers. If your integration retries a failed order create, you need to know whether the first attempt created an order. Otherwise a retry can leave a duplicate order in the warehouse queue. This guide explains how to retry order creation without creating duplicates. It assumes you already have Logitrail API credentials — see Authentication if you don't.
1. Send an Idempotency-Key with every create
Add an Idempotency-Key header to every POST /v1/orders request:
POST /v1/orders
Idempotency-Key: 4f0d6c2e-6a43-4c55-9d0e-2b8f1f7a9c31
Content-Type: application/json
{ "order": { "merchants_id": "80992", ... } }
Rules for the key:
- One key per order. Generate a new key, for example a UUID, when your system decides to send a new order to Logitrail.
- Same key on every retry of that order. Store the key with the order on your side before the first attempt, so a retry after a crash or restart still uses it.
- Up to 64 visible ASCII characters (letters, digits and punctuation), with no spaces. A UUID (36 characters) fits. A malformed key is rejected with
400 INVALID_IDEMPOTENCY_KEYand nothing is created. - Keys are scoped to your merchant account. Another merchant's keys never collide with yours.
The header is optional. Requests without it, or with an empty value, behave as they always have: every request creates a new order.
2. What a retry returns
| You send | Logitrail returns |
|---|---|
| A key not used before | 201 Created with the new order. |
| The same key and the same body as an earlier request | 201 Created with the order the earlier request created, and the response header Idempotent-Replayed: true. No second order is created. |
| The same key with a different body | 409 Conflict, error_code: IDEMPOTENCY_KEY_REUSED. No order is created. Use a new key for a new order. |
"The same body" means the same JSON content. The order of the fields in the JSON does not matter.
If the first request asked for "status": "confirmed" but was cut off before the order was confirmed, the retry confirms it. The replayed order then comes back as confirmed, as you asked.
A replay returns the order as it is now, not a copy of the first response. If the order has moved on since, for example it was confirmed, shipped or deleted, the replay shows that. A replay also skips the product checks, so it still returns the order even if a product in it has since been changed or removed.
3. Which errors to retry
| Response | Meaning | What to do |
|---|---|---|
503 ORDER_CREATE_TIMEOUT | Creation did not finish in time. Usually no order was created, but in rare cases the order was saved just as time ran out. | Retry with the same key, after a short backoff (for example 1 s, 2 s, 4 s). You get the order back if it was created after all, and no duplicate either way. |
Other 5xx, or a network error or timeout on your side | The outcome is unknown. The order may or may not exist. | Retry with the same key. Without a key, a retry here can create a duplicate. |
400, 401, 403, 409, 422 | The request itself is not acceptable. | Do not retry unchanged. Fix the request first. |
Error responses carry a machine-readable error_code next to the human-readable message. A 503 response also carries a request_id. Quote it to Logitrail support if you need to report the failure:
{
"message": "Order creation did not complete in time. Retry the request with the same Idempotency-Key: if the first attempt did create the order, the retry returns it instead of creating another.",
"error_code": "ORDER_CREATE_TIMEOUT",
"request_id": "Kx3nAhxpgi0EMRw="
}
4. Checklist
- Generate and store one
Idempotency-Keyper order, before the first attempt. - Send the same key on every retry of that order.
- Retry
503, other5xxand network failures with backoff. Do not retry4xxunchanged. - Treat
201withIdempotent-Replayed: trueas success: it is the order you created earlier.