API Reference

Transfers

Send BRL PIX, USD ACH or Wire, and Base USDC transfers, then track their status to completion.

Send money to a saved bank recipient, or send USDC to a Base wallet recipient you saved in the dashboard. Every method is funded from your organization’s available balance.

Method Required request fields Destination amount precision
BRL PIX currency: "BRL", rail: "pix", recipientId 2 decimals
USD ACH currency: "USD", rail: "ach", recipientId 2 decimals
USD Wire currency: "USD", rail: "wire", recipientId 2 decimals
Base wallet currency: "USDC", rail: "wallet", network: "base", destinationAddress Up to 6 decimals

rail: "base" is also accepted as an input alias for rail: "wallet". Responses always return rail: "wallet". Base is currently the only supported wallet network.

Wallet transfers require stablecoin access to be enabled for your organization. Save and activate the Base USDC wallet recipient in the dashboard before calling the API; the submitted destinationAddress must match that saved address. Lowercase and uppercase EVM addresses are accepted. A mixed-case address must have a valid EIP-55 checksum.

Create a transfer

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

Idempotency-Key is required. amount is the exact amount the bank recipient or wallet should receive in the destination currency. The total USDC debit, including applicable fees, is calculated automatically and is the amount checked against your organization’s send limit.

Bank transfer request

{
  "recipientId": "9a5b47c1-234d-4841-a5b8-d1b790f774be",
  "amount": "100.00",
  "currency": "BRL",
  "rail": "pix",
  "memo": "Invoice 1048",
  "description": "Acme Ltda supplier payout"
}
  • ACH and Wire use an existing USD recipient created through the API or dashboard. Choose the same rail the recipient was configured for.
  • memo is optional. When provided, it is sent as the transfer’s bank-facing reference on rails that carry one. Some PIX payout routes have no bank-facing reference; the memo is then stored on the transfer record and returned by the API, but the recipient’s bank statement will not show it.
  • purposeCode is optional. Include it when your configured ACH or Wire route requires one.
  • description is optional internal metadata and is not sent to the bank.

USD Wire example:

{
  "recipientId": "b36b2c20-731b-4209-aacd-174a2ca39112",
  "amount": "2500.00",
  "currency": "USD",
  "rail": "wire",
  "memo": "INV-1048",
  "description": "US supplier payout"
}

Wallet transfer request

Wallet transfers do not send a recipientId, but destinationAddress must match an active wallet recipient saved in the dashboard:

{
  "amount": "100.123456",
  "currency": "USDC",
  "rail": "wallet",
  "network": "base",
  "destinationAddress": "0x1111111111111111111111111111111111111111",
  "description": "Treasury wallet payout"
}

Response

Returns 201 Created with the transfer wrapped in a transfer object:

{
  "transfer": {
    "id": "7b4f1f9c-7d92-4d12-a4aa-9c5b2f4f9b25",
    "object": "banking.transfer",
    "status": "pending",
    "direction": "debit",
    "rail": "pix",
    "network": null,
    "description": "Acme Ltda supplier payout",
    "memo": "Invoice 1048",
    "sourceCurrency": "USDC",
    "sourceAmount": "18.82",
    "destinationCurrency": "BRL",
    "destinationAmount": "100.00",
    "fxRate": "5.31349628",
    "recipientId": "9a5b47c1-234d-4841-a5b8-d1b790f774be",
    "destinationAddress": null,
    "idempotencyKey": "transfer-acme-1048",
    "createdAt": "2026-06-25T12:00:00.000Z",
    "updatedAt": "2026-06-25T12:00:00.000Z",
    "completedAt": null
  }
}
  • sourceAmount is the total debited from your balance.
  • fxRate is the all-in effective rate (destinationAmount / sourceAmount), inclusive of every charge applied to the transfer. The full USDC debit is always destinationAmount / fxRate.
  • For wallet transfers, network is "base", destinationAddress is the submitted address, and recipientId is null. Bank transfers return network and destinationAddress as null.
  • If a wallet submission is rejected immediately after a provider transaction is created, the API returns 201 Created with status: "failed". Replaying the same idempotency key returns that same failed transfer.

Rejected PIX recipients

A BRL PIX transfer to a recipient the payout network cannot pay fails with 422 and no transfer object; no funds move. pix_recipient_bank_not_supported means the recipient’s PIX key belongs to an unsupported bank, such as a credit cooperative (for example Sicoob): ask the seller for a PIX key at a different bank, save it as a new recipient, and send with a new Idempotency-Key. pix_payout_rejected carries the reason in error. Retrying the same recipient does not help.

Temporary funding failures

A burst of transfers from the same balance may temporarily exceed its funding capacity. When creation returns a 503 error without a transfer object:

  1. Wait at least 60 seconds; use increasing delays with jitter for repeated failures.
  2. Retry the exact same request with the same Idempotency-Key.
  3. If the retry returns a pending or completed transfer, track it normally.
  4. If it returns a failed or cancelled transfer, the original attempt is closed. Submit a new payment with a new idempotency key only if you still want to send it.

Do not switch to a new key merely because the initial response is 503. See Errors & Idempotency for the complete decision table.

Get a transfer

Poll a transfer, or reconcile after a missed webhook, using the id returned above.

GET /v1/banking/transfers/7b4f1f9c-7d92-4d12-a4aa-9c5b2f4f9b25
x-api-key: dlfy_live_...

Response

{
  "transfer": {
    "id": "7b4f1f9c-7d92-4d12-a4aa-9c5b2f4f9b25",
    "object": "banking.transfer",
    "status": "completed",
    "direction": "debit",
    "rail": "pix",
    "network": null,
    "description": "Acme Ltda supplier payout",
    "memo": "Invoice 1048",
    "sourceCurrency": "USDC",
    "sourceAmount": "18.82",
    "destinationCurrency": "BRL",
    "destinationAmount": "100.00",
    "fxRate": "5.31349628",
    "recipientId": "9a5b47c1-234d-4841-a5b8-d1b790f774be",
    "destinationAddress": null,
    "idempotencyKey": "transfer-acme-1048",
    "createdAt": "2026-06-25T12:00:00.000Z",
    "updatedAt": "2026-06-25T12:01:20.000Z",
    "completedAt": "2026-06-25T12:01:20.000Z"
  }
}

Notes

  • status is one of pending, completed, failed, or cancelled.
  • The object under transfer is exactly the data object delivered by banking webhooks — the same status-handling code works for both.
  • Only API-created transfers for your organization are returned. Unknown ids return 404 banking_transfer_not_found.
  • The response never includes provider ids, wallet ids, bank account details, or funding addresses.