Funding

Withdraw funds

POST
/execution/withdraw

Authorization

appIdbearerAuth
headerx-app-id<token>

Your application ID. Required on app-tier and user-tier routes. Omitted on routes that authenticate with x-app-api-key only.

headerAuthorizationBearer <JWT>

JWT access token from POST /auth/verify. Required with x-app-id on user routes. On the smart-route quote it is optional and turns a preview into an executable quote.

Request Body

application/json
  1. body
requestId?string

Optional idempotency key for an exact-amount transfer. Reuse with the identical body to recover a lost response. Not combined with max.

Formatuuid
amountRaw*string

Amount to deliver, as a positive integer string in the destination token's atomic units (6 decimals, so 1000000 = 1 USDC; 18 decimals on BNB Chain). Minimum is one whole token. Same-chain transfers debit exactly this. A bridge or swap leg debits up to ~2% more to cover its fee, and when the live fee is lower the recipient gets more than this amount; the preview's receiveAmountRaw is the estimate. To withdraw everything, send max: true.

Match^[1-9][0-9]*$
tokenSymbol*string

Stable-coin symbol the withdrawal is denominated in.

Value in"USDC""USDC.e""USDT"
destinationAddress*string

Recipient address. EVM destinations: 0x-prefixed 20-byte hex. Solana: base58 (32–44 chars).

Match^(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{32,44})$
destinationChainId*integer

Chain ID where the recipient address should receive funds.

Range1 <= value
max?boolean

Withdraw-max intent: cap amountRaw to the deliverable maximum instead of rejecting it. Send the full balance as amountRaw with this flag to empty the balance.

signingAddress?string

Self-custody: the linked EVM wallet that owns and signs this withdrawal. Omit for managed custody.

Length42 <= length <= 42
approveMode?string

Self-custody only (ignored without signingAddress): what the signing wallet can sign. Send the same value to the quote, preview and withdraw. sponsored (default): the wallet can sign an EIP-7702 authorization and Calibur batch, so every source is available. user_broadcast: it cannot (e.g. MetaMask). The withdrawal still never asks it to send a transaction or hold gas; sources that would need a batch (an approve, a same-chain swap, or a same-chain transfer of anything but native Circle USDC; decided by token) are left out of Max, preview and selection. A same-chain native USDC transfer is then two EIP-3009 signatures (amount less the network fee, and the fee).

Value in"sponsored""user_broadcast"

Response Body

200

application/json
  1. response
withdrawalId*string

Withdrawal id. Poll it on the status endpoint.

status*string

Withdrawal status. pending: accepted, not started (the submit response always returns this). bridging: moving funds across chains. transferring: same-chain transfer in progress. Terminal: completed, partial (some sources delivered; see completedAmountRaw), failed.

Value in"pending""bridging""transferring""completed""partial""failed"
requested*

What is being withdrawn.

completedAmountRaw*string

Estimated total delivered by the completed parts. null until the withdrawal is terminal. Integer string in the destination token's atomic units (6 decimals, so 1000000 = 1 USDC; 18 decimals on BNB Chain).

destination*

Where the funds are delivered.

legs*array<>

Transfers that make up the withdrawal.

expected*

Quote for the withdrawal. null fields unless pricingStatus is quoted.

pricingStatus*string

Fee quote state. quoted: expected holds a current quote. unquoted / quoting: no quote yet. unviable: at least one source is too small to cover its fees.

Value in"unquoted""quoting""quoted""unviable"
errorMessage*string

Why the withdrawal failed or only partly completed. null otherwise, and always null on the submit response (errors there are returned as HTTP errors).

sources*array<>

Balances the withdrawal is funded from.

pendingSignatures?array<>

Self-custody only: requests the signing wallet must answer before the withdrawal continues. Absent for managed custody. Answer them on POST /execution/withdrawals/{withdrawalId}/signatures.

Example Request
curl -X POST 'https://api.t.sufwankhalid.com/execution/withdraw' \  -H 'Content-Type: application/json' \  -d '{  "amountRaw": "50000000",  "tokenSymbol": "USDC",  "destinationAddress": "0x2f9a4c7e1b3d6f8a0c5e9b2d4f7a1c3e6b8d0f52",  "destinationChainId": 8453}'
Example Response
{  "withdrawalId": "cmf3s7d9k00e1mw0l4n2x6pvh",  "status": "pending",  "requested": {    "tokenSymbol": "USDC",    "amountRaw": "50000000"  },  "completedAmountRaw": null,  "destination": {    "chainId": 8453,    "address": "0x2f9a4c7e1b3d6f8a0c5e9b2d4f7a1c3e6b8d0f52",    "tokenSymbol": "USDC"  },  "legs": [    {      "type": "bridge",      "status": "planned",      "sourceChainId": 137,      "destChainId": 8453,      "amountRaw": "50000000",      "txHash": null,      "bridgeOperationId": null,      "sourceTokenSymbol": "USDC",      "errorMessage": null    }  ],  "expected": {    "outputRaw": "49930000",    "feeRaw": "70000",    "etaSeconds": 30  },  "pricingStatus": "quoted",  "errorMessage": null,  "sources": [    {      "sourceId": "cmf3s7d9m00e2mw0l8k5r1bqa",      "chainId": 137,      "tokenSymbol": "USDC",      "tokenAddress": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",      "decimals": 6,      "amountRaw": "50000000",      "custodyKind": "DEPOSIT_WALLET",      "status": "pending",      "txHash": null,      "bridgeOperationId": null    }  ]}