Client area

Docs

Idempotency

One field — attempt_key — stops a retried request from buying the same thing twice. Every confirmation-tier operation accepts it, and none of them require it.

Why it exists

Networks time out on the way back. A client that renewed a service, never saw the response and retried has now renewed it twice — and an agent retries on timeout far more eagerly than a person does.

attempt_key

Every confirmation-tier operation accepts an attempt_key: a string you choose that identifies this intent, not this HTTP request. It is optional on all of them — omit it and you simply get no replay protection, which for a money operation is the wrong trade. Send it.

A repeat inside the window carrying the same key returns the existing pending action rather than creating a second one. Nothing is charged twice, and the user is not asked to approve the same thing twice.

In the body, not a header

Choosing a key

  • Derive it from the intent, not from a random value: renew-{serviceId}-{date} is a good key. A fresh UUID per attempt is a useless one — every retry gets a new key and the protection does nothing.
  • Keep it stable across retries of the same logical operation.
  • Change it when the intent changes. Renewing for two years instead of one is a different intent and needs a different key.
  • Keys are scoped to your token. Another account using the same string cannot collide with yours.

The 30-minute window

A key replays for as long as its pending action is still pending and unexpired — in practice 30 minutes, the lifetime of the hold. After that the same string starts a fresh action, which is correct: a renewal attempted yesterday and attempted again today is two intentions, not one.

Approval ends the window too. Once the user approves, the action leaves pending and the key stops replaying — so sending the same attempt_key again creates a second action and a second charge. The key protects you against a timeout, not against calling the operation twice on purpose. Check the pending action's status before retrying.

Esc
navigate open Esc close