Withdraw from User Wallet
Sends native coin or a currency token out of one of the user's wallets to an external address. The caller selects both the wallet (wallet_id) and the network (network_id); the server never falls back to another wallet of the user. The wallet must belong to the user and sit on the network's chain. For a token withdraw, network_id must be the currency token's own network.
The call is asynchronous. It creates a user transaction of type 10 (Withdraw) with status 1 (Started) and returns its id. Poll Get User Transaction until status is 3 (Done, hash set) or 4 (Error, error set). The transfer is executed by the custody provider from the named wallet.
Required permission: user:withdraw
Request
POST /v2/users/{user_id}/withdraw
Parameters
| Name | Type | In | Description |
|---|---|---|---|
user_id | string | path | Required. User ID |
Headers
| Name | Description |
|---|---|
Authorization | Required. Bearer <access_token> |
Content-Type | Required. application/json |
Body
| Field | Type | Required | Description |
|---|---|---|---|
wallet_id | string | Yes | The user's wallet the funds leave from (see List User Wallets) |
network_id | string | Yes | Network the transfer runs on. Must be on the wallet's chain; for a token withdraw, the currency token's network |
address | string | Yes | Destination address (0x + 40 hex characters) |
amount | string | Yes | Amount to send, as a decimal string. Must be greater than zero and carry no more decimals than the asset (the currency token's decimals, or the network's native-currency decimals). See Amounts and Percentages |
currency_token_id | string | No | Currency token to send. Omit it to send the network's native coin |
Example
curl --request POST \
--url '{{baseUrl}}/v2/users/6a87455ad5f439809d488ac3/withdraw' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"wallet_id": "6a8754e187be1d0e22aa6d83",
"network_id": "6740e0a20000000000000103",
"address": "0x4A096E485281DE1B8bF11A511D39d5B128EF7C4b",
"amount": "10.5",
"currency_token_id": "6913307ec95e268b239b2d8b"
}'
Response
{
"transaction_id": "6a8b5e13f9129816a6cc7a12"
}
Response Fields
| Field | Type | Description |
|---|---|---|
transaction_id | string | The user transaction to poll with Get User Transaction. Its data carries address, amount and, for a token withdraw, currency_token_id |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | 10015 | Validation failed (missing wallet_id / network_id / address, address not an Ethereum address, amount missing, not positive or too many decimals) — see details |
| 400 | 10016 | user_id, wallet_id or network_id is not a valid id |
| 400 | 10000 | currency_token_id is not a valid id |
| 400 | 10001 | User not found (domain 1) |
| 400 | 10015 | currency token not found, network not found, or network_id must be the currency token's network |
| 400 | 10015 | Domain 1: wallet does not belong to this user on this network — the wallet does not exist, is not this user's, or is not on the network's chain |
The last row shares the number 10015 with the common validation error; tell them apart by domain (1 vs 100). A failure after acceptance (for example the custody provider refusing the transfer) does not become an HTTP error: the transaction ends in status 4 with the reason in error.
See Errors for the error format and common codes.