Skip to main content

Create Withdrawal

Pays a member's balance out to an external address. member_id, dchain_id, amount and address are required; the asset follows from the network.

amount is what the destination receives — the fee is charged on top of it.

POST/api/withdrawalsAuth: Required

Answers 201. Quote the fee first with Withdrawal Fees — it returns the total fee and the total that will be debited for exactly this amount, network and destination.

Request Body

member_idnumberRequired

The member whose balance is paid out.

dchain_idstringRequired

The network to pay out on, from List Assets. The asset is derived from it — there is no asset_id field on this call.

amountstring | numberRequired

The amount the destination receives. The fee is charged on top, so the balance is debited amount + fee. Accepted as a string or a number; send a string to avoid float rounding.

addressstringRequired

Destination address.

address_tagstring

Destination memo, for networks that use one (XRP, XLM, TON).

client_withdrawal_idstring

Your own id for this payout. Optional — but see the warning below. It is also a filter on List Withdrawals, which is how you check whether a payout landed.

Response

201, with the created payout.

The payout comes back with its id, its public uuid, the fee that was applied, operation_type, and status — which starts at aml_processing. Read it back with Get Withdrawal to follow it to a terminal state.

Errors

Beyond the shared errors:

CodeMeaning
1001A field is invalid or the object is not yours — the message names it: member_id, dchain_id, or client_withdrawal_id is not unique for owner
1003Amount, balance or address failed validation; the message carries the detail
2066This network needs a destination tag as well as an address
2002The core refused the payout; the reason is in the message
2070Payouts are switched off for the moment — retry later
3009The core is in maintenance — retry later
Nothing here is idempotent — a retry can pay twice

client_withdrawal_id is optional, and the API does not document any deduplication. A request that times out, or a retry loop, can create a second payout and send the money twice.

Protect yourself on the client side:

  1. Always send a client_withdrawal_id you generated, one per intended payout.
  2. If a request fails or times out, do not blindly retry. First call GET /api/withdrawals?member_id=…&client_withdrawal_id=… and see whether the payout already exists.
  3. Only retry when that lookup comes back empty.

Do not rely on the service recognising a reused client_withdrawal_id for you. Treat duplicate protection as your responsibility.

Budget for the fee before you send

The member needs amount + fee on the balance, not amount. So whenever there is a fee, a payout of exactly the whole balance cannot go through.

Call Withdrawal Fees first: it returns total_fee and total_amount (= amount + total_fee) for this exact request. For a "send everything" flow, quote first and then send balance − total_fee.

Money moves off the platform

This is the one call that sends funds to an address you supply, and the token in the header authorises it on its own. Validate the destination address in your own code before calling, and keep the token server-side.