Skip to main content

Idempotency

Money operations must be safe to retry. SafeBank supports an Idempotency-Key header on every POST: send the same key twice and the API executes the operation once, returning the original result on the repeat.

Use it for anything that creates or moves value — creating a wallet, funding, and especially creating a payment.

With the SDK (automatic)

The SDK generates an Idempotency-Key for every POST once, outside the retry loop, and reuses it across its own automatic retries. So a 429/5xx retry can never double-execute — the API's two-phase claim dedupes it.

// Nothing to do — this POST already carries a stable Idempotency-Key,
// reused if the transport retries on 429/5xx.
const payment = await sb.payments.create({
sourceWalletId: 'w_1a2b3c',
destination: { type: 'handle', handle: 'volt-components' },
amount: { value: '25.00' },
})

Making a key stable across process restarts

The SDK's auto-generated key lives for the life of a single call (including its own retries) — it is not persisted across process restarts. If your code retries at a higher level — a job that reruns, a queue redelivery — derive a stable key from the logical operation so the second run dedupes against the first.

The typed resource methods (sb.payments.create(...)) manage the key for you. When you need a deterministic key tied to a business event, send the request with your own Idempotency-Key header — for example via curl or a raw fetch:

# Deterministic key tied to the business event (e.g. an invoice id).
# Re-running the job with the same invoice id executes the payment once.
curl -X POST https://api.sandbox.safebank.ai/v1/payments \
-H "X-SafeBank-Api-Key: $SAFEBANK_API_KEY" \
-H "Idempotency-Key: pay:INV-2026-001" \
-H "Content-Type: application/json" \
-d '{
"sourceWalletId": "w_1a2b3c",
"destination": { "type": "handle", "handle": "volt-components" },
"amount": { "value": "25.00" },
"memo": "invoice INV-2026-001"
}'

Rules

  • Scope: POST only. GET is already safe; DELETE/PUT are handled by their own semantics.
  • Reuse the same key for genuine retries of the same operation. Use a new key for a genuinely new operation.
  • Same key, different body is a conflict — don't reuse a key for a different request.
  • Pair idempotency with the SDK's retry behavior for at-most-once execution under transient failures.