Request Withdrawal
Status: Implemented. Session-token endpoint; rejected with
403for wallet-funded spot accounts, which withdraw by moving assets in their own wallet.
POST /v1/withdrawals
Submit a withdrawal of amount units of asset from the session user's spot wallet to the Canton party dest_user_handle_party.
Auth: Authorization: Bearer <session_token> (see place-order). The session must carry the withdraw permission and have a Canton party_id. The user is taken from the session — there is no user_id field.
Request
POST /v1/withdrawals
Authorization: Bearer <session_token>
Content-Type: application/json
{
"asset": "CC",
"amount": "10.0",
"dest_user_handle_party": "alice::1220abc...",
"idempotency_key": "ui-withdraw-1748275200"
}
| Field | Type | Required | Notes |
|---|---|---|---|
asset | string | yes | Case-insensitive. Aliases: USDC / USDA / USDC-X → CUSD; AMULET / CANTONCOIN / CANTON_COIN → CC; CETH → cETH; USDCX → USDCx. Must be withdrawal-enabled in the asset registry. |
amount | string | yes | Decimal > 0, at most the asset's registered number of decimal places. |
dest_user_handle_party | string | no | Defaults to the session's own party_id when omitted or blank. |
idempotency_key | string | yes | Non-empty. Re-sending the same key with a different payload is rejected by the ledger. |
Withdrawal fee: quoted server-side at request time. Stablecoins (CUSD, USDCx, USX, USDC.B) pay a fixed 1 of the same asset; CBTC / cETH / CC pay the equivalent of 1 USD in the withdrawn asset (oracle price, rounded up to the asset's decimals; fee_quote_price / fee_quote_ts_ms are then present). Preview it with GET /v1/withdrawals/quote?asset=... (same auth).
Response — 200
{
"withdrawal_request_id": "8c9a1f2e-7b6d-5c4a-3b2c-1d0e9f8a7b6c",
"withdrawal_id": "8c9a1f2e-7b6d-5c4a-3b2c-1d0e9f8a7b6c",
"status": "submitted",
"asset": "CC",
"amount": "10.0",
"fee_asset": "CC",
"fee_wallet_symbol": "CC",
"fee_amount": "0.0000142858",
"fee_quote_price": "70000",
"fee_quote_ts_ms": 1748275200000,
"destination_party": "alice::1220abc..."
}
withdrawal_request_id and withdrawal_id are the same hyphenated UUID. status is always "submitted" in this response; poll GET /v1/withdrawals/{wid} for the live state.
Errors (plain-text body): 400 validation (asset is required, unsupported withdrawal asset, amount must be positive, amount supports at most N decimal places, withdrawal destination is required, idempotency_key is required, session does not have party_id), 401 missing/invalid session token, 403 withdrawal permission denied or wallet-funded account (spot withdrawals disabled), 409 ledger precondition failed (e.g. insufficient spot balance), 502 other ledger/trading errors (including an idempotency_key reused with a different payload), 503 fee quote unavailable/stale or eligibility check unavailable, 504 request timed out (15 s).