Skip to main content
Every write endpoint is idempotent. Reuse the same request_id on a retry and the gateway returns that payment or quote-request with its current status. Using the same request_id prevents making a second payment or opening a second quote-request batch. This page is the API-reference summary. For the concepts behind it — the two guarantees, per-integration usage (SDK, CLI, x402, MPP), and deliver-once guidance on the acceptance side — see the Idempotency guide.
Unlike header-based schemes, the key is a field in the request body, not an HTTP header, and it is not required to be a UUID. See request_id below.

The key: request_id

You choose the value. A stable, unique-per-operation string works best (an order id, or a UUID if you already mint them). Store it before you send the request — it’s the only thing that links a retry to its original.

Supported endpoints

Idempotency applies to state-changing (POST) endpoints. Each has its own key: reusing one across the two does not carry over. GET reads (/status, /resolve, /timeline) have no side effects, so there is nothing to deduplicate.

Detecting a replay

Every write response carries idempotent_replay (boolean, always present):
  • true — you were handed a resource that already existed; nothing new was created or charged.
  • false — this request created it.

Reusing a key with different terms

A request_id locks in one set of economics — who pays, who receives, in which assets, and how much (source, destination, fulfillment_amount, max_source_amount). Reuse it with any of those changed and the gateway rejects the request rather than merging the change or silently returning the original. Exempt (you may change these freely on a retry):
  • Deadlines — quote_deadline and fulfillment_deadline. An expired deadline on a retry is not an error; the request resolves onto what already exists.
  • The signature — re-sign, or resend the original bytes. Only request_id must stay fixed.

Errors

Retrying by status

A safe retry depends on the payment’s status: Note that pending and failed call for opposite actions, so make sure to preserve the mental model:
  • pending — still settling, so reuse the same request_id (or just poll). Minting a new key here starts a second payment: a double charge.
  • failed — terminal. Reusing its request_id only hands you back the same failed payment, so a genuine re-attempt needs a new request_id.

Example

The request authorizes itself through its sender_auth signature — there is no API key. Re-send the exact same request, with the same request_id, to recover the original result after a timeout or crash; the response’s idempotent_replay tells you whether it was created now or already existed.
Using the SDK? You still pass requestId — the SDK derives the on-chain deposit nonce from it so both guarantees line up. The CLI generates a request_id if you omit --request-id; copy that value to retry.