Skip to main content

Goal

Submit an off-chain transfer between two omnibus accounts on the same platform and confirm it settles. For transfers that go through the blockchain, see Send crypto on-chain.

Key entities and concepts

Off-chain transfers require omnibus accounts. Both the sender and recipient must have omnibus accounts on the same platform. If your platform uses segregated wallets, see Send crypto on-chain instead.

Flow overview

  1. Confirm the customer’s identity is verified and they have sufficient balance.
  2. Submit POST /v2/crypto/transfers with account_destination.
  3. Track transfer status via webhooks or polling. Off-chain transfers settle immediately.
  4. Show the completed transfer and updated balances in your app.

Prerequisites

  • The customer has a verified identity (KYC or KYB) in Bastion.
  • The customer has an omnibus account with balance in a supported asset (e.g., USDC).
  • The recipient also has an omnibus account on the same platform.
  • You have an API key and have registered your webhook.

Step 1 — confirm identity, account, and balance

Before sending, confirm the customer can transact and has sufficient balance. Get the identity
Check that:
  • status is ACTIVE
  • allowed_to_transact_fungibles is true
Get balances
Response:
Omnibus balances are chain-agnostic. The type field is OMNIBUS and chainis CHAIN_UNSPECIFIED. contract_address is omitted. Confirm enough available balance in the available field for the asset you intend to send. Your UI should surface clear errors when a transfer cannot complete (e.g., insufficient balance).

Step 2 — submit off-chain transfer

Call POST /v2/crypto/transfers to submit an off-chain transfer from the customer’s account to another account on the same platform. Request
No chain field is needed. The transfer is a ledger operation, not a blockchain transaction. Request fields: Response
Guidance:
  • Use a unique request_id as an idempotency key. request_id must be a UUID. If you retry the same transfer after a transient error, reuse the same request_id.
  • Both sender and recipient must be omnibus accounts on the same platform. If the destination account is not found, not an omnibus account, or belongs to a different platform, the request returns HTTP 400.

Step 3 — track transfer status

Track the transfer until it reaches a terminal state. You can use webhooks (recommended) and polling. Off-chain transfers settle immediately, so you will typically receive a terminal status within seconds.

Webhook — transfer status

Configure a webhook endpoint in the Bastion dashboard to receive transfer events. Bastion delivers a submit_cryptocurrency_transfer_v2 webhook on every status change. Your handler should be idempotent and use request_id to correlate events. Sender webhook (confirmed):
For off-chain transfers, destination_address, destination_chain, and transaction_hash are empty because no blockchain transaction occurs. destination_type is ACCOUNT. The events array is always present but empty. Recipient webhook (deposit credited):
For off-chain deposits, source_type is ACCOUNT and source_account_id identifies the sender. See Receive crypto deposits for full details. Handle statuses:
Webhook reliability: Failed deliveries are retried with exponential backoff (15 s base, 10 min max). Deduplicate on id + status for transfer events (the transfer id is stable across status changes), and on data.dedup_key for deposit events.

Polling — get a transfer

As a fallback, you can poll transfer status.
Response:
Use the returned status and any failure_details to decide what to show to the customer.

Step 4 — show the updated balance

After the transfer confirms, refresh balances and show the transfer in history. Refresh balances
Show transfer in your UI:
  • Display amount, asset (USDC), recipient name or account identifier, and status.
  • Indicate the transfer was instant (no blockchain confirmation wait).
  • For the recipient side: show the sender’s name or account identifier using source_account_id from the deposit webhook.

Implementation notes and recommendations