The entity model
Shapes every resource shares
The resources use a common set of conventions, so code that reads one resource reads the others. Customer reference. A resource names its customer ascustomer: { "id": "cst_..." }. Quotes are the exception: they carry customerId plus a display-safe customer summary with id and name.
Instruments. The source and destination of a transaction, and the from and to of a transfer, are instruments with one shape:
type names the account kind (walletCrypto, walletExternal, walletFiat, bankUs, bankIban, bankCanada, card, cash, depositAddress, or virtualAccount). Crypto instruments add a network. owner appears only when the account belongs to someone other than the customer. Bank instruments on a transaction carry no rail: the rail lives on the transfer that moved the money.
Amounts and fees. Money is a decimal string at the asset’s precision ("10.00" for usd, "5.000000" for usdc). Quotes, transactions, and cash-ins report economics in one pricing object: source and destination, each { amount, asset }, plus a flat fees[] list. See Quote system.
Failures and holds. A failed resource carries one failure object: { code, message, retryable }, plus bankCode when a bank gave one. A transaction waiting on you carries a hold object with a code and message. Both are left out when they do not apply.
Omitted, not null. A field that does not apply to a resource is left out of the response rather than sent as null. All timestamps are UTC with millisecond precision, for example 2026-06-15T10:00:00.000Z.
ID prefixes. Every ID is prefixed by its resource type:
Customers
A customer is the identity record every financial operation hangs off. Create one withPOST /customers and a type of individual or business. Creation can return 202 while onboarding runs asynchronously; see Customer onboarding for the fields your project requires.
A customer’s status tells you whether it can move money:
Inside a customer, endorsements track onboarding per capability. Each endorsement in
endorsements[] has a type and its own status, using the same five values. An endorsement never reads further along than its customer.
When you omit
endorsements on create, OMS requests cryptoCustody and usd. Whether verification is required, and how it runs, is configured per project. Status changes arrive as customer.statusChanged and customer.updated webhooks.
Wallets
A wallet holds value OMS manages for a customer. OMS supports two kinds through the Payments API:- Crypto wallets (
walletCrypto) hold one stablecoin on one network, with an onchainaddress. OMS manages the keys. Create one withPOST /wallets,type: "custodial", anddetails: { network, asset }. The customer needs an activecryptoCustodyendorsement. - Fiat wallets (
walletFiat) hold a USD balance at a partner bank, with no network or address. Create one withPOST /wallets,type: "fiat". See Fiat wallets.
GET /wallets?customerId=.... GET /wallets/{walletId} returns the wallet with its balances[]. Wallets are the source of quoted transactions and a common destination for deposits.
For user-controlled keys, use OMS Wallet non-custodial wallets. The two models can be combined. Account model covers custody choices in more depth.
Virtual accounts
A dedicated bank account number assigned to a customer. When fiat arrives on a supported bank rail, OMS creates a transaction that delivers the funds to the virtual account’sdestination: a stablecoin to a crypto wallet or registered external wallet, USD forwarded to a registered bank account, or USD held in the customer’s fiat wallet.
Create one with POST /virtual-accounts. Give your customer the depositInstructions once they appear on the resource. Deleting a virtual account is asynchronous: it reads deleting until the underlying account closes, then deleted. See Virtual accounts.
Deposit addresses
A persistent onchain address assigned to a customer. Whenusdc or usdt arrives, OMS creates a transaction that delivers the funds to the deposit address’s destination: fiat to a registered bank account or the customer’s fiat wallet, or crypto to an OMS wallet or registered external wallet.
Create one with POST /deposit-addresses. The address in depositInstructions appears once it is issued. There is no delete. Deposit addresses must be enabled for your project. See Deposit addresses.
Counterparties
A person or business the customer pays who is not your customer, for example a supplier. A counterparty is scoped to one customer, has anentityType of individual or business, and owns external accounts. A counterparty cannot be deleted while it owns active or pending external accounts. See External accounts.
External accounts
A registered bank account, debit card, or external wallet, owned by the customer or one of its counterparties. Every external account ID uses theext_ prefix whatever the instrument; read type to tell them apart. Register bank accounts and external wallets with POST /external-accounts. Debit cards register only through the secure card fields of the OMS browser SDK; see Debit cards.
External accounts are references, not balances. OMS never holds funds in one. They appear as the destination of a quote, deposit address, or virtual account, and as a card source on a quote.
Quotes
A quote locks pricing for a short window before you move money. You create one when the money starts in an OMS wallet or on a debit card:POST /quotes: lock pricing and get the fee breakdown.POST /transactionswith thequoteId: execute against the locked quote.
Transactions
A transaction is the record of one money movement from asource instrument to a destination instrument. There is no transaction type field: the corridor follows from the two instruments. Quotes report it as sourceToDestination, and GET /transactions filters on the same values.
Most transactions are created for you. The resource that receives the funds decides how:
precursor on the transaction names the resource that created it. Auto-created transactions skip the quote step, because OMS cannot lock pricing before the funds arrive.
Transfers
A transfer is one movement of a transaction’s money on one rail: the deposit coming in, the payout going out, or a refund going back. A transaction lists its transfers intransfers[], and GET /transfers/{transferId} returns the full record with its rail, status, and tracking references. See Transaction lifecycle.
Cash-ins
A code-based deposit flow for cash at retail locations. Creating a cash-in issues a code the customer presents at a partner location. When the cash is deposited, OMS converts it to a stablecoin and auto-creates a transaction. See Cash-ins and cash-outs.Webhooks
Webhook subscriptions tell OMS where to deliver events. Create one withPOST /webhooks, passing a url and the event types in subscriptions (or ["*"] for all of them). Each delivery carries the resource as a GET would return it, so you rarely need a follow-up read. See Receiving webhooks.