Skip to main content

Overview

Idempotent requests allow you to safely retry API calls without the risk of performing the same operation twice. This is essential for building reliable integrations, especially when dealing with network failures or timeouts.

How It Works

To make an idempotent request, include an Idempotency-Key header with a unique value. If the same key is used within 24 hours, the API returns the cached response from the first request instead of creating a new resource.

First Request

  • Processes the request normally
  • Creates the resource
  • Stores the request and response for 24 hours
  • Returns the newly created resource

Subsequent Requests (Same Key)

  • Detects duplicate key
  • Returns the cached response immediately
  • No new resource is created
  • No side effects occur

Supported Endpoints

Idempotency is supported on the following resource creation endpoints:
  • Customers: POST /customers/individuals, POST /customers/businesses
  • Associated Entities: POST /customers/:customerId/associated_individuals, POST /customers/:customerId/associated_businesses
  • Transfers: POST /transfers
  • Quotes: POST /quotes
  • FX Quotes: POST /fx/quotes
  • Balance Accounts: POST /balance-accounts
  • Fixed Routes: POST /fixed-routes/virtual-bank-accounts, POST /fixed-routes/virtual-wallets
Endpoints not listed here ignore the Idempotency-Key header — retrying a request against them may create duplicate resources.

Generating Idempotency Keys

Idempotency keys should be:
  • High-entropy: Use UUIDs — do not derive keys from guessable values like sequential order numbers
  • Stable across retries: Generate the key once per operation, persist it, and reuse the same value for every retry of that operation
  • Short-lived: Keys expire after 24 hours

Best Practices

Generate a UUID when the operation is first attempted and store it alongside the operation with an atomic get-or-create, then reuse that stored value for every retry:
A plain read-then-write can lose under concurrency: two workers both see no key, generate different UUIDs, and then retry with different keys. Serialize retries of the same operation: wait for a response or timeout before sending another request with the same key. Do not fire overlapping concurrent requests with one key. Avoid these patterns:

Error Handling

If the original request failed, subsequent requests with the same key will return the same error. This prevents partial state issues.
To fix the request, use a new idempotency key.

Key Expiration

Idempotency keys expire after 24 hours. After expiration:
  • The key can be reused for a new operation
  • Previous responses are no longer cached

When to Use

✅ Use Idempotency For:

  • Network retry logic
  • Webhook handlers (use webhook event ID as key)
  • User-triggered actions that could be double-clicked
  • Automated scheduled jobs
  • Any situation where duplicate requests are possible

❌ Don’t Use For:

  • Read operations (GET requests) - they’re naturally idempotent
  • Update operations (PATCH/PUT) - these are typically idempotent by design
  • Operations you want to repeat intentionally

Implementation Examples

JavaScript/TypeScript

Python

Webhook Handler Example

Technical Details

  • Storage: Idempotency keys are stored in the database
  • TTL: 24 hours from first request
  • Scope: Keys are scoped by operation type. Related routes that create the same resource type share one cache (for example POST /customers/individuals and POST /customers/businesses; similarly the two associated-entity create routes). Always use a unique high-entropy UUID per distinct operation — never guessable or shared values.
  • Cleanup: Expired keys are automatically cleaned up

Limitations

  • Do not reuse a key across different operations — reusing one can return the first cached response
  • Related creation routes that create the same resource type share one cache; reuse a key only when retrying that same operation
  • Do not send overlapping concurrent requests with the same key — wait for a response or timeout, then retry
  • Maximum key length: 255 characters
  • Only POST operations support idempotency (creation endpoints)