Skip to content

Retrying safely (Idempotency-Key)

Every write — POST, PUT, DELETE — carries an Idempotency-Key header, at most 100 characters. Pick something you already have that names the operation:

Write A good key
Ack an order your sales order number, SO-0012345
Ack a payment your journal id, JRN-000881
Push a customer CUST-0042@<source_version>
You send You get
Same key, same body The first answer again, byte for byte, with Idempotent-Replayed: true
Same key, different body 422 IDEMPOTENCY_KEY_REUSED
Same key while the first call is still running 409 REQUEST_IN_PROGRESS — retry shortly
No key 400 IDEMPOTENCY_KEY_REQUIRED

Keys are kept for 7 days per client. So if a call times out and you don’t know whether it landed, send it again with the same key: either it runs now, or you get the answer it gave.

A key goes with one request. To send a changed body — a corrected price, a second push of the same customer to see unchanged — use a new key.

Push a unit twice under one key, then once under another:

Terminal window
push() {
curl -si -X PUT "$SLFLO_BASE/units/BOX-$USER" -H "Authorization: Bearer $SLFLO_TOKEN" \
-H "Content-Type: application/json" -H "Idempotency-Key: $1" -d "{\"name\":{\"en\":\"$2\"}}" \
| grep -iE '^HTTP|idempotent-replayed|"result"|"code"'
}
k="unit-$(date +%s)"
push "$k" Box # 200, "result":"created"
push "$k" Box # 200, Idempotent-Replayed: true, "result":"created" — the first answer again
push "$k" Crate # 422, "code":"IDEMPOTENCY_KEY_REUSED"
push "$k-2" Box # 200, "result":"unchanged" — a new call, and nothing changed