Move money
All money leaving your balance moves through a single endpoint: POST /api/transfers. You say where the money goes with the destination object, and Recurrente creates the right movement — a bank payout, a transfer to another Recurrente account, a send to a phone number, or an on-chain stablecoin send.
Destinations
In most cases destination is simply the destination’s identifier as a string — paste whichever one you hold, and its format tells us where the money goes:
The only destination that needs the object form is stablecoin, because a raw address alone doesn’t say which token or network to send on:
The object form also exists for the other types if you prefer being explicit: { "type": "bank_account", "id": "ba_..." }, { "type": "account", "id": "ac_... | @handle" }, { "type": "phone_number", "number": "..." }.
Per-destination notes:
- Payouts (
ba_) — also acceptis_instant(instant payout, subject to eligibility and a fee) andshould_perform_currency_conversion(converts your balance into the destination account’s currency). If you omitcurrency, the bank account’s currency is used. - Accounts (
ac_/@handle) — the transfer is instant and free. - Phones and contacts — the movement stays
unclaimeduntil the recipient signs up and completes KYC. You can cancel it while unclaimed. - Stablecoin — requires completing stablecoin verification in the app. Set the stablecoin in
destination.currencyand the network indestination.chain.
States
Every movement has a canonical status — the same vocabulary regardless of destination — plus a status_detail with the underlying record’s raw state.
Transfers between Recurrente accounts complete immediately. Bank payouts and stablecoin sends are asynchronous: the POST response carries the initial state, and you can follow progress with GET /api/transfers/{id} or webhooks.
Idempotency
Send an Idempotency-Key header with every POST. Retrying with the same key and body returns the original response without creating a second movement.
Listing and filtering
GET /api/transfers returns all your movements — payouts, p2p, and stablecoin — newest first. Filter by destination type with types[]:
GET /api/transfers/{id} and POST /api/transfers/{id}/cancel accept any movement ID (tr_, wi_, sw_).
Connected accounts
If you run a platform with connected accounts, pass account_id to move money for a verified child account. Child accounts support bank_account destinations, plus transfers within their own platform family — to the parent account (commission sweeps) or to sibling accounts (marketplace settlements). Out-of-family accounts, phone sends, and crypto are not available to children:
Webhooks
Every movement type emits webhooks as it progresses: transfer.sent/transfer.received (p2p), withdrawal.create/withdrawal.update (payouts), and swap.create/swap.update (stablecoin). Payout and stablecoin events include a transfer key carrying the same unified shape the API returns, alongside their historical key (withdrawal/swap). If you integrate against the unified endpoint, always read payload.transfer.
Requirements
To move money through the API you need:
- An API key with money movement enabled (Settings → API Keys).
- A verified account (KYC completed).
- For stablecoin: completed stablecoin verification in the app.
What about the withdrawals endpoints?
/api/withdrawals and the nested connected-account withdrawals keep working indefinitely for existing integrations, but they are marked deprecated: new integrations should always use /api/transfers.

