API Reference

Errors & Idempotency

How the API signals errors, the access-control codes to expect, and how to use idempotency keys safely.

Error responses

The API uses standard HTTP status codes. A 2xx status means success; 4xx means the request was rejected; 5xx means a server or provider error. Errors return a JSON body with a human-readable error, a machine-readable code you can branch on, and a requestId to quote when you contact support:

{
  "error": "PIX payouts to this recipient's bank are not supported. ...",
  "code": "pix_recipient_bank_not_supported",
  "requestId": "4adda759-86ec-4ec5-a3da-e1edc4cc6584"
}

The API returns 503 for temporary server and provider failures. A 502 or 504 response without that JSON body comes from our edge network, not from the API: the request may or may not have been processed, so treat it like a timeout and retry with the same Idempotency-Key.

Access-control errors

Product access is checked on every request. When a product is not enabled for your organization, you get a 403 with a specific code:

Status Code Meaning
403 banking_api_access_not_enabled Banking is not enabled for your organization’s API access.
403 wallet_transfers_not_enabled Stablecoin wallet transfers are not enabled for your organization.
403 cards_api_access_not_enabled Cards is not enabled for your organization’s API access.
403 api_access_disabled Checkout API access is not enabled for your organization.

If you see one of these, ask your Dolafy contact to enable the product and the org-level API flag.

Common resource errors

Status Code Meaning
400 recipient_rail_unsupported Recipient creation supports BRL PIX, USD ACH, and USD Wire only.
400 invalid_destination_address The Base address is malformed, or a mixed-case address has an invalid EIP-55 checksum.
404 banking_transfer_not_found No API-created transfer with that id exists for your organization.
404 recipient_not_found No active recipient with that id exists for your organization.
409 recipient_nickname_already_exists Another active external recipient already uses this nickname. Choose a different nickname.
409 recipient_partner_sync_failed The configured banking route rejected the recipient details; correct them and retry.
422 pix_recipient_bank_not_supported PIX payouts to the recipient’s bank are not supported (credit cooperatives such as Sicoob). No funds were sent. Use a PIX key registered at a different bank.
422 pix_payout_rejected The PIX payout was rejected before any funds moved; the message says why. Correct the recipient and retry.
422 pix_quote_rejected The PIX quote was rejected (for example an amount outside the allowed range); the message says why.
409 wallet_recipient_required Save and activate this Base USDC wallet recipient in the dashboard before sending through the API.
409 authorized_user_terms_required Card authorized-user terms must be accepted in the dashboard before issuing cards via the API.
400 invalid_checkout_session_amount A checkout-session amount is not a positive supported decimal with at most two decimal places.
400 checkout_session_pricing_conflict A checkout session supplied both amount and discountPercent; provide only one.
503 checkout_pix_not_available The organization is not set up to accept PIX for checkout yet.
503 provider_rate_limited The card provider is briefly rate limited. Nothing was processed. Wait the number of seconds in the Retry-After header, then repeat the same request — for POST /v1/cards, with the same Idempotency-Key.

Idempotency

Some write endpoints require an Idempotency-Key header so that retries never create duplicates:

  • POST /v1/banking/recipients
  • POST /v1/banking/transfers
  • POST /v1/cards
  • POST /v1/checkout/products
  • POST /v1/checkout/sessions

For the checkout endpoints, the key must be 8–200 characters of letters, numbers, dots, underscores, colons, or hyphens.

Your server generates the key. Use a unique value for each new request. Reuse the exact same value only when retrying the same request after a timeout or network error — Dolafy will return the original result instead of performing the action twice.

Banking transfers add two idempotency outcomes you should handle:

Status Code Meaning
409 banking_transfer_attempt_pending_review An earlier request with this key started a payout whose outcome is still being confirmed. Do not send the same payment under a new key; contact support if it does not resolve.
409 banking_transfer_idempotency_conflict This key was already used with a different amount or recipient. Use a new key for a new payment.

Retrying a transfer funding error

If transfer creation returns a temporary 503 error without a transfer object, wait at least 60 seconds and retry the same request with the same Idempotency-Key. Use increasing delays with jitter if the error continues. The retry safely resolves the original attempt and may use new pricing when the previous quote is no longer valid.

Choose the next action from the retry response:

Retry result What to do
201 with pending or completed Keep the original key and track that transfer. Do not submit the payment again.
201 with failed or cancelled The original attempt is closed. To try the payment again, create a new request with a new idempotency key.
409 banking_transfer_attempt_pending_review Do not use a new key for the same payment. Contact support if it does not resolve.
Another temporary 503 Keep the same key, increase the delay, and retry later.

Never switch to a new key only because the first request returned 503 (or an edge 502/504); doing so before the original outcome is known could create a duplicate payment.

POST /v1/banking/transfers
x-api-key: dlfy_live_...
Idempotency-Key: pix-acme-1048
content-type: application/json

Guidelines:

  • Derive the key from your own stable identifier for the operation (for example an invoice or order id).
  • Do not reuse a key for a genuinely different request; that returns the original response, not a new one.
  • Keys are stored on the created resource and reused for duplicate responses.
  • For checkout sessions, the normalized amount, discountPercent, and selected payment method are part of the request identity. Changing any of them requires a new key; equivalent decimal forms such as 37.45 and "37.45" are treated as the same amount.