A single product can combine them: custodial for fiat flows and compliance, non-custodial for user-controlled on-chain assets, agentic for autonomous payments.
The remainder of this page covers the account types used by the custodial model. For non-custodial and agentic wallets, see OMS wallets.
Custodial wallets
The primary balance store. OMS manages private keys, with no end-user signing and no wallet SDKs required. All operations are server-to-server API calls.address. The type field is internal for OMS-managed wallets. blockchainAsset resolves the on-chain identity of the asset (protocol, chain ID, and token ID).
Creating a wallet: POST /customers/{customerId}/wallets with asset and chain. Returns the created wallet record.
Listing wallets: GET /customers/{customerId}/wallets returns the customer’s wallets, one per asset and chain.
Reading a balance: GET /wallets/{walletId}/balance returns the wallet’s current balance for its asset and chain, along with an estimated value in the requested currency.
Funding a wallet: Send crypto directly to the wallet’s address, or use the on-ramp flows (cash-in, virtual accounts, deposit addresses) to convert fiat.
Multiple wallets: A customer can have more than one wallet, for different currencies, use cases, or segregation needs.
At launch, OMS custodial wallets are
internal (OMS-managed). Embedded wallets, provisioned through the same customer endpoint, are planned for a later release.Virtual accounts
A bank account number wired to a customer’s wallet. Fiat deposits auto-convert to crypto.depositInstructions to display in your UI (left out until the underlying deposit account is provisioned). A transfer to that account number delivers crypto to the configured wallet. When funds arrive, OMS creates a transaction directly in processing: fiatAccountToCrypto for a crypto wallet destination, or fiatAccountToFiatAccount for a bank or fiat wallet destination.
Virtual accounts are managed through the API: create with POST /virtual-accounts, list with GET /virtual-accounts, read and update with GET/PATCH /virtual-accounts/{id}. Deletion is asynchronous: DELETE /virtual-accounts/{id} initiates closure of the underlying deposit account; the status reads deleting until it closes, then finalizes to deleted. A sandbox POST /virtual-accounts/{id}/simulate/inbound-transfer endpoint exercises the inbound flow. See Virtual accounts.
Deposit addresses
A reusable onchain address wired to a destination. Onchain deposits auto-create a transaction.processing: cryptoToFiatAccount for a bank or fiat wallet destination, or cryptoToCrypto for a registered external wallet.
Deposit addresses are managed through the API: create with POST /deposit-addresses (the destination is a registered bank external account, the customer’s fiat wallet, or a registered external wallet), list with GET /deposit-addresses, read and update with GET/PATCH /deposit-addresses/{id}. There is no delete. depositInstructions carries the accepted asset and network from creation, and its address is left out until the inlet address is issued. Re-pointing the destination to a healthy external account recovers an inactiveActionRequired address to active. Deposit addresses must be enabled for your project: contact us to enable them. See Deposit addresses.
External accounts
Off-platform bank accounts, external wallets, and debit cards, referenced on a quote by their ID. A quote’s source is always an OMS wallet or a card, so banks are destinations. Every external account ID uses the sameext_ prefix, whatever the instrument. The type field on the resource identifies the instrument:
Register bank accounts and external wallets with
POST /external-accounts. The body specifies an owner (a customer, or one of the customer’s counterparties), a type (bankUs, bankIban, bankCanada, or walletExternal), and exactly one per-type details object matching the type. Debit cards register through their own endpoint, POST /external-accounts/cards; the generic endpoint rejects type: card with CardMustUseCardEndpoint. See Debit cards. List with GET /external-accounts (optional customerId, counterpartyId, and status filters), update label and metadata with PATCH, and remove with DELETE. When delivering to a raw onchain wallet, a quote can also pass a blockchainAddress directly instead of a registered external wallet’s ext_ ID.
External accounts are not OMS-managed balances. OMS never holds funds in an external account; it is only a source or destination reference on a transaction.