Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.capa.fi/llms.txt

Use this file to discover all available pages before exploring further.


Overview

When creating a transaction, a network drop, client timeout, or unexpected 5xx response can leave you unsure whether the operation was processed. Retrying the request without a safeguard can result in duplicate transactions. The Idempotency-Key header lets you retry any transaction-creation POST safely. If Capa receives a request with a key it has already seen, it replays the original response β€” no duplicate transaction is created. The header is opt-in: if omitted, the request is processed normally with no idempotency guarantee.

Supported Endpoints

The header is recognized on the following POST endpoints only. All other endpoints ignore it.

How It Works

  1. Generate a unique Idempotency-Key (UUIDv4 recommended) for each logical operation and include it as an HTTP header.
  2. Capa processes the request and caches the response under the (userId, key) pair.
  3. On retry, send the identical request body with the same key. Capa detects the duplicate and returns the original response β€” the handler is not invoked again.
  4. Failed originals can be retried. If the first attempt resulted in an error (non-2xx), the record is marked FAILED and a subsequent request with the same key reprocesses normally.
  5. The guarantee window is 48 hours. After that the key expires, the record is reclaimed, and the next request is treated as a new operation. It is the caller’s responsibility to avoid duplicates beyond this window.

Header Reference

FieldValue
NameIdempotency-Key
RequiredNo (opt-in)
Format16–128 printable ASCII characters
Recommended valueUUIDv4
Scope(userId, idempotencyKey) β€” scoped per user, not per endpoint

Behavior Matrix

ScenarioBehaviorHTTP Status
New keyRequest is processed; response cached under keyHandler’s status (2xx)
Same key + same body, original completedCached response replayed; handler not invokedOriginal status
Same key + same body, original in-flightRequest rejected β€” wait and retry409 Conflict
Same key + different bodyRejected β€” request body hash mismatch422
Same key + original failed (non-2xx)Record marked FAILED; request reprocessedHandler’s status
Key older than 48hRecord reclaimed; request treated as newHandler’s status (2xx)

Errors

HTTP StatusCodeMessage
400INVALID_USER_INPUT_ERRORMalformed Idempotency-Key header (format violation)
409 Conflictβ€”Same key is already being processed; retry after a short delay
422INVALID_USER_INPUT_ERRORIdempotency-Key was already used with a different request body

Best Practices

  • Generate a fresh UUIDv4 per logical operation. Never hardcode or reuse keys across distinct operations.
  • Persist the key client-side until you receive a confirmed terminal response for that operation.
  • Retry with the identical body. Changing any field in the request body is treated as a different operation and results in a 422.
  • Do not share a key across endpoints for the same user. Keys are scoped to (userId, key), so the same key on a different endpoint collides on a body hash mismatch.
  • Omit the header on GET, PUT, PATCH, and DELETE requests β€” it has no effect on those methods.
  • Plan for the 48-hour window. Retries after expiry are reprocessed as new requests; implement your own deduplication logic for long-lived operations.

Example

curl --request POST \
  --url https://staging-api.capa.fi/api/partner/v2/on-ramp \
  --header 'Content-Type: application/json' \
  --header 'partner-api-key: <your-api-key>' \
  --header 'Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \
  --data '{
    "userId": "user_abc123",
    "fiatCurrency": "MXN",
    "blockchainSymbol": "ETH",
    "tokenSymbol": "USDC",
    "fiatAmount": 500,
    "destinationWalletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  }'
If this request times out or fails at the network level, resend the exact same body with the same Idempotency-Key. Capa will return the original response without creating a second transaction.