GuidesRecipesAPI ReferenceChangelog
Guides

On-Chain Crypto Withdrawals

How do I withdraw crypto to an external wallet?

Overview

Withdraw crypto from a customer's trading account to an external wallet using a
crypto_transfer quote followed by a crypto transfer. The flow mirrors fiat funding but
uses different parameters and accounts for on-chain network fees.

Prerequisites

  • A customer with a verified identity
  • A trading account holding the crypto asset to withdraw
  • A registered external wallet for the destination address (see
    Add External Wallets)

Step 1: Create a crypto transfer quote

Create a quote of type crypto_transfer with side set to withdrawal. This example withdraws
0.25 ETH:

{
  "product_type": "crypto_transfer",
  "customer_guid": "customer_guid",
  "asset": "ETH",
  "side": "withdrawal",
  "deliver_amount": 250000000000000000
}
ℹ️

Base unit precision

The deliver_amount is in base currency units. For ETH, the base unit is wei (18 decimals).
The above amount represents 0.25 ETH. This precision is required to avoid rounding errors.

ℹ️

deliver_amount vs receive_amount

deliver_amount fixes what you send; fees come out of what the recipient gets.
receive_amount fixes what the recipient gets; you pay fees on top. See
Create and execute a trade
for the canonical explanation.

For crypto withdrawals, understand the related on-chain gas fees that may accompany the withdrawal. The
POST /api/quotes response includes two fields related to network fees:

{
  ...,
  "network_fee": 2900000000000000,
  "network_fee_asset": "ETH"
}

The network_fee shown above is also in the base units of the currency. The above amount
represents 0.0029 ETH. Network fees are tracked as a partner liability in the bank's gas
account. To clear the liability, transfer from your fee account to the gas account before
withdrawing fees — see Platform accounts for
the full flow.

Step 2: Execute the transfer

Execute the transfer using POST /api/transfers with the quote GUID from Step 1. Set
transfer_type to "crypto" and provide the destination wallet in external_wallet_guid.

{
  "quote_guid": "quote_guid",
  "transfer_type": "crypto",
  "external_wallet_guid": "external_wallet_guid",
  "source_participants": [
    {
      "type": "customer",
      "amount": 250000000000000000,
      "guid": "customer_guid"
    }
  ],
  "destination_participants": [
    {
      "type": "customer",
      "amount": 250000000000000000,
      "guid": "customer_guid"
    }
  ]
}

The valid type enum values for source_participants and destination_participants are bank, customer, and
counterparty. Values such as trading, account, external_wallet, or external_wallet_account are not valid
and will result in validation errors.

Key points for crypto withdrawals:

  • The guid in each participant must match the chosen type (e.g., the customer GUID for customer).
  • The amount field is required in both participant objects and must match the quote amount in base units.
  • The external_wallet_guid is set at the top level alongside the participants array; these are not
    mutually exclusive.

Step 3: Monitor the transfer

Crypto transfers process faster than fiat transfers, typically completing in a few minutes. Poll
GET /api/transfers/{transfer_guid} to monitor the transfer state until it reaches completed,
or register for webhooks. See
Transfer Process for the full
state lifecycle.

Once completed, verify the on-chain transaction using a blockchain explorer such as
etherscan.io for Ethereum-based assets.

Network fee too low

Encountering the error code network_fee_too_low during a crypto transfer indicates that the base network
fee was not met when the transaction was submitted to the blockchain. This may occur due to network
volatility between the submission and the authorization/approval of the transfer. Retrying the
transfer usually resolves this issue.

Ethereum address format requirements

When withdrawing USDC or other assets to an external wallet on the Ethereum network, ensure the destination address
meets the following requirements:

  • Starts with 0x
  • Is exactly 42 characters long
  • Contains only hexadecimal characters (0-9, a-f, A-F)

Addresses that do not meet these criteria may result in failed transfers. Double-check that you are using an
Ethereum-compatible address and not one from a different blockchain.

Minimum receive amounts for crypto transfer withdrawals

For crypto_transfer withdrawal quotes, each asset and network may have a specific minimum
receive_amount enforced by the platform. For example, USDC_NPL on Polygon enforces a minimum
of 1,000,000 base units (1.00 USDC) in production. A quote below the minimum returns a
422 Invalid Quote Amount error. Enforce per-asset minimums in your application before
submitting withdrawal quotes.

Sandbox behavior

For sandbox-specific behavior of crypto withdrawals (mocked on-chain confirmations, devnet
addresses, Solana rent handling), see
Sandbox Transfers.