Goal
Withdraw USDC from a customer’s Bastion account to their own US bank account in USD, using an off-ramp conversion. Scope: USDC to USD, wire only, first-party only (the customer withdraws to a bank account they own). To pay out to a bank account outside the United States, or to a third party, see Withdraw stablecoin to an international bank account.Key entities
Flow overview
The steps to withdraw funds from a stablecoin balance to a US bank account are:- Confirm identity, account, and balance
- Register payment instructions
- Submit the conversion
- Track status
- Show updated balance
Prerequisites
- Customer has a verified identity (KYC or KYB) with
fiat_operations_enabled = true - Customer has an on-chain account with a USDC balance on a supported chain
- You have an API key and a registered webhook
- The customer’s principal address is not in New York. See Jurisdiction overview
Step 1 – Confirm identity, account, and balance
Before allowing a withdrawal, confirm the customer can transact and has sufficient balance. Get the identity
Get balances
10 ^ decimals to get the decimal amount: 750000000 with decimals: 6 is 750.000000 USDC. Conversions take decimal strings, not base units.
Verify available covers the withdrawal amount. Fees are deducted from that amount rather than added to it, so the customer’s total debit equals the amount you submit.
Step 2 – Register payment instructions
Register the customer’s bank account as payment instructions. The returnedpayment_instructions_id is reusable across withdrawals to the same bank account.
Request
Response
id as payment_instructions_id so you can reference it on the conversion request and reuse it for future withdrawals to this bank account.
Step 3 – Submit the conversion
Submit a conversion that debits USDC from the customer’s account and sends USD to their bank. Requestpayment_purpose is required and must describe the nature of the payout. See the API reference for valid values.
destination.payment_method and destination.currency must match the payment_method and fiat_currency_symbol on the registered payment instructions.
Response - INITIATED
PLATFORM fee is the wire processing cost. It is deducted from amount before payout, so destination.amount is amount minus fees_total.
Tip: use a uniquerequest_id(UUID) as an idempotency key, and reuse the samerequest_idon retries. Thepayment_instructions_idcan be reused across withdrawals to the same bank account.
Step 4 – Track conversion status
Track the conversion via webhooks (recommended) or polling until it reaches a terminal state.Option A: Webhooks
Configure a webhook endpoint in the Bastion dashboard to receive conversion events. Each event carries the conversion object indata, using the same shape as the submit response.
id is unique per delivery. The stable conversion ID is data.id. See Conversion notifications for the full schema.
On FAILED and RETURNED, the event carries failure_reason with a human-readable description of what went wrong. Log it, and use it to decide between prompting the customer to correct bank details and routing to support. Do not display it to the customer verbatim.
Status progression
INITIATED to PROCESSING to PAYOUT_INITIATED to PAYOUT_IN_PROGRESS to COMPLETED
Handle statuses:
For canonical status definitions and recovery guidance, see Stablecoin and fiat conversions.
Webhook reliability: failed deliveries are retried with exponential backoff (15 s base interval, 10 min max). Deduplicate usingdata.idanddata.status. If no webhook arrives within a reasonable window, pollGET /v2/conversions/{conversion_id}.
Option B: Polling
PollGET /v2/conversions/{conversion_id} as a fallback. Use the returned status and fee breakdown to update your UI.
Step 5 – Show updated balance
After the conversion completes, refresh balances and show the withdrawal in your history.- Decrease the visible USDC balance by the amount submitted, which includes fees
- Display the amount, the asset (USDC), the USD delivered, and the status
- Show the destination with masked bank account details
Implementation notes
What’s next
- Withdraw stablecoin to an international bank account
- Stablecoin and fiat conversions
- Jurisdiction overview