Skip to content

Idempotency and retries

Send a Kustom-Idempotency-Key on every Order Management write so a retried capture or refund runs once, and retry a 5xx on a schedule or escalate it.

When a backend call to Kustom fails, the dangerous case is not the one that clearly failed — it is the one whose outcome you cannot know. The connection may have broken after Kustom committed a capture but before the response reached you. An idempotency key removes the ambiguity by making a repeat of the same request a no-op, which is what turns “retry” from a gamble into a policy. This page covers the Order Management API, where the money moves.

Why an uncertain outcome is the real problem

Section titled “Why an uncertain outcome is the real problem”

A call can fail three ways, and only one of them is safe to blindly repeat:

FailureState of the order in Kustom
The connection never openedUnchanged. Safe to retry.
The call failed midway through the operationUnknown.
The call succeeded, then the connection broke before the replyAlready changed. A blind retry duplicates it.

Two captures of €10 sent without idempotency keys, or with different ones, are two captures: €20 captured. The same two requests sharing one key are one capture of €10, and both requests get the same response.

Send an idempotency key as an HTTP header on every Order Management POST and PATCH. Kustom honors it for 24 hours from the first attempt. After that the same key is treated as a new request.

The key exists on the Order Management API only. Checkout calls, including POST /checkout/v3/orders, take none, so an ambiguous 5xx on one of them is not safe to retry blindly: read the order back first.

POST /ordermanagement/v1/orders/{order_id}/captures
Kustom-Idempotency-Key: c6010e41-5eb0-46a9-8cc0-decb265419b1
Content-Type: application/json

The API reference lists Klarna-Idempotency-Key. The Order Management API reference still names this header Klarna-Idempotency-Key, from the platform’s Klarna origins. Both names work on every Order Management call and mean the same thing: a key sent under one name matches the same key sent under the other, so an integration already sending Klarna-Idempotency-Key keeps working. Send one of them, not both. If a request carries both with different values, Klarna-Idempotency-Key is the one Kustom uses.

Generate one UUID per logical operation, not per attempt: the retry has to carry the key the original attempt used, or it is not a retry as far as Kustom is concerned. Derive it from something stable in your own system — the capture row’s primary key, say — so that a process restart mid-retry still produces the same key.

When a 5xx comes back, retry on this schedule, keeping the same idempotency key each time:

AttemptWait before it
1st retry5 seconds
2nd retry5 minutes
3rd retry5 hours

After the third retry fails, stop and escalate. The widening intervals are deliberate: a 5 second retry catches a blip, a 5 hour retry catches an incident and nothing in between is worth burning quota on.

GET calls change nothing and can always be retried on this schedule. POST and PATCH calls can use it only if the original request carried an idempotency key. If it did not, the retry is not safe — a second capture or refund may be created — so escalate immediately instead.

A 3xx or 4xx will not fix itself, so it does not get retried. Route it to a technical support team inside your own organization, which can inspect the request, correct it and then re-send it if appropriate. Some cases will need Kustom Merchant Support to resolve.

Escalation is also where customer communication lives. Kustom sends no message to the customer when one of your API calls fails. If a failed capture or refund means the customer needs to be told something, you tell them.

Before escalating, read the order back. After an uncertain outcome the order body is the only authority on what actually happened — see Update or cancel an order.

This page is also available as Markdown — append .md to its URL — and is indexed in llms.txt.