Retry any POST safely

API

A request that times out leaves you guessing whether it ran. Every POST on the REST API now takes an Idempotency-Key header, so the safe move after a timeout is always the same: send the same request again with the same key.

What changed

  • Every POST takes the header: provisioning, verification, connect, grants, carts, answers, confirms, code resends, cancels and menus. The retired POST /v1/orders is the only exception.
  • Same key, same body. The first success is stored for 24 hours and comes back with Idempotent-Replayed: true. Layout does not run the request again.
  • Same key, different body is 409 idempotency_conflict. While the first request is still running, the same request is 409 in_progress with Retry-After.
  • Only a success is stored. After an error the key is free again, so a confirm answered with code_required is retried with the same key and the person's code added. A 4xx ran nothing. A 5xx may have, so after a 500 on a confirm, read the order before sending anything changed.
  • A replay is the first answer. A stored 202 building stays building. Read the cart for its state.
  • The body's idempotencyKey keeps working. On carts, answers and confirms it is now optional when you send the header, whose value then stands in for it. When you send both, the body's key names the cart or the confirm.

Why it matters

A confirm is where a careless retry costs the most. If one times out, retry the same call with the same key, never a new one: the retry gets the answer the first call earned, and the person is charged once.

What to do

Send a fresh random Idempotency-Key with every POST that changes something, and carry it into every retry of that call. See Idempotency.

Breaking changes

None. The header is optional, and a request without it behaves as before.

All changes