Skip to main content
HTTP 409 · type conflict. Within the 24-hour idempotency window (scoped to the API key), this Idempotency-Key was already used for a request with a different body. The original request stands; this one did nothing and charged nothing. For contrast: same key + same body is a replay — it returns the original response with fn-idempotent-replay: true and never bills twice. The dedupe lives in the ledger, not just the HTTP layer: a replayed spending POST can never create a second reservation.

The shape

original_request_id identifies the request that claimed the key — findable in the dashboard’s API log.

How to fix

  • If this is a genuinely new request, give it a fresh Idempotency-Key (UUIDs recommended).
  • The classic cause is confirming a proposal with the original turn’s key. The confirm re-POSTs the turn with "confirm": true — a different body — so it needs a fresh key. This error firing there is the guardrail working: you got a 409, not a silent spend. See Budgets and proposals.
  • If you build keys deterministically (e.g. from an order id), make every distinct body produce a distinct key — hash the body in.

Reproduce it

Two calls, same key, different body (works on an fn_test_ key, $0):