Submit withdrawal
Submit a withdrawal of collateral to the chain.
X-API-Key / X-Signature headers. In v0 only withdraw-to-self is supported: the recipient is always the wallet that signed the request (ethereumAddress), so there is no to field.
Response behavior
Asynchronous. A202 Accepted means the withdrawal passed validation and was queued to the matching engine with status: PENDING. The definitive outcome (applied, or rejected for insufficient free collateral) is delivered asynchronously — poll GET /v1/accountTransferUpdates or subscribe to the account transfer update WebSocket channel and correlate on withdrawalId.
Signing the request
Withdrawals use EIP-712 typed data (eth_signTypedData_v4), so wallets render each field and institutional / MPC signers can whitelist on the domain. Sign this typed data with the wallet that owns ethereumAddress, then split the 65-byte result into {r, s, v} for the signature field. The gateway recovers the signer and rejects mismatches with HTTP 401.
Domain
amount is the integer collateral quote-quantum amount (same value as the amount request field).
Per-environment domain parameters
| Environment | chainId | verifyingContract (BridgeVault) |
|---|---|---|
| staging | 421614 | 0xe91f43c1ad084463db129034fb7b93545dfe1d4e |
| testnet | 46630 | 0xe0166c85fcb29ea6d21915dd0dc54387e8d17915 |
| production | TBA | TBA |
eth_signTypedData_v4 call (ethers v6 / viem)
v component must be 0x1b (27) or 0x1c (28); wallets that return 0 / 1 should have 27 added before sending.Body
Master EVM address initiating the withdrawal. In v0 this is also the on-chain recipient (withdraw-to-self) — there is no separate destination field.
^(0x|0X)?[0-9a-fA-F]{40}$"0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
Amount to withdraw, as a base-10 integer string in quote quantums (1e9 = $1; for example, 1000000000 represents $1). Requests with an amount below the minimum withdrawal size for the collateral currency are rejected with HTTP 400, for example validation error on field 'amount': must be at least 1000000000 quote quantums. Amounts must be positive, fit in a signed 64-bit integer, and be exactly representable in collateral base units; float-style decimals are rejected.
^[0-9]+$"5000000000000"
Client-supplied nonce for replay protection.
1"b1c2d3e4-5f60-7182-93a4-b5c6d7e8f901"
secp256k1 EIP-712 typed-data signature (r, s, v) over the Withdraw payload (eth_signTypedData_v4). See the POST /v1/withdraw endpoint description for the exact domain, types, and message. Produced by the wallet that owns ethereumAddress; requests whose recovered signer does not match are rejected with HTTP 401.
Trading account to debit. Defaults to 0 when omitted.
0 <= x <= 9Response
Withdrawal accepted and queued to the matching engine. The body carries status: PENDING and a withdrawalId; the terminal outcome is delivered on the account transfer update stream.
Server-generated identifier (UUID) correlating this withdrawal with the matching AccountTransferUpdate on the account transfer update stream.
"b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
20-byte EVM address as hex: optional 0x or 0X prefix and exactly 40 hexadecimal digits. API responses normalize to lowercase a–f after 0x.
^(0x|0X)?[0-9a-fA-F]{40}$Account index (account index, 0–9). Identifies the account for orders, positions, fills, and API keys.
0 <= x <= 9Withdrawal amount echoed back as a human-readable decimal in quote currency (quote resolution 1e9), matching how the amount is reported on the account transfer update feed.
"5000"
"1.5"
Synchronous status of a submitted withdrawal. Always PENDING on the 202 response — the withdrawal has been queued to the matching engine but not yet applied. The terminal outcome (APPLIED, REJECTED_INSUFFICIENT_COLLATERAL, ...) is delivered asynchronously on the account transfer update stream (see AccountTransferUpdate).
PENDING Server receive timestamp (epoch microseconds).