Skip to main content

Goal

Detect and handle incoming crypto deposits to a customer’s Bastion account. Deposits can arrive from external wallets, exchanges, or other accounts on your platform.

Key entities and concepts

Bastion handles block finality verification and compliance screening internally before crediting the customer’s balance. Your platform receives a single deposit_v2 webhook when the deposit is confirmed and the balance has been credited.

Flow overview

  1. Retrieve the customer’s deposit address and display it in your UI.
  2. When crypto arrives, Bastion detects the deposit, runs compliance checks, and credits the balance.
  3. Your platform receives a deposit_v2 webhook. Update the displayed balance.
  4. Optionally, query deposit history for the account.

Prerequisites

  • The customer has a verified identity (KYC or KYB) in Bastion.
  • The customer has an active account with at least one wallet address.
  • You have an API key and have registered your webhook.

Step 1 — retrieve and display the deposit address

Get the customer’s wallet address and display it in your UI so the sender knows where to send funds. Get the account
Response:
Use the addresses array to determine which chains and addresses the customer can receive on. Each entry may map to multiple chains (e.g., one EVM address shared across Ethereum, Polygon, Base, and Optimism). See the supported assets endpoint for the full list of accepted assets and networks. Display the deposit address in your UI alongside a QR code, the supported chains for that address, and which assets are accepted (e.g., USDC). Remind the customer that sending unsupported assets or using an unsupported network will result in funds not appearing.

Step 2 — detect incoming deposits

Bastion detects deposits automatically once they are confirmed on-chain (for external deposits) or completed on the ledger (for off-chain transfers). Bastion handles compliance screening internally before crediting the balance. Your platform receives a deposit_v2 webhook when the deposit is confirmed and the balance is credited.

Webhook — deposit confirmed

Configure a webhook endpoint in the Bastion dashboard to receive deposit events. One webhook is fired per deposit. Your handler should be idempotent; use the dedup_key field to avoid double-processing. On-chain deposit (from an external wallet):
Off-chain deposit (from another account on your platform, omnibus accounts only):
Use source_type to distinguish between the two: On receipt of a deposit_v2 event, record the confirmed deposit in your own ledger and refresh the account balance in your UI — Bastion has already credited the account’s on-platform balance before sending the webhook, so do not credit it again. Use dedup_key to avoid processing the same event more than once.
Webhook reliability: Failed deliveries are retried with exponential backoff (15 s base, 10 min max). Deduplicate using data.dedup_key.

Step 3 — show the updated balance

After receiving a deposit webhook, refresh balances and update your UI. Refresh balances
Response:
Balances are returned in atomic units as strings. Use the decimals field to convert to a human-readable amount (e.g., "123440000" with decimals: 6 = 123.44 USDC). Only show funds as available after receiving the deposit_v2 webhook with status: CONFIRMED.

Step 4 — query deposit history (optional)

Retrieve past deposits for an account using GET /v2/crypto/deposits. Note this endpoint returns crypto deposits only. On-ramp conversions (fiat → stablecoin) are not included; use the Conversions API for those.
Query parameters: Responses mirror the webhook payload structure. You can also retrieve a single deposit by ID: GET /v2/crypto/deposits/{deposit_id}.

Implementation notes and recommendations