Skip to main content
Every OMS integration is built from a small set of resources. The API-managed resources are Customers, Wallets (custodial), Counterparties, External Accounts, Virtual Accounts, Deposit Addresses, Quotes, Transactions, Cash-ins, and Webhooks. Understanding the relationships between them is the fastest way to design a correct integration.

The entity model

Customer
├── Wallets            (custodial stablecoin balances, created and listed under the customer)
├── Counterparties     (people and businesses the customer transacts with)
├── Virtual Accounts   (persistent bank account numbers)
├── Deposit Addresses  (persistent onchain addresses)
└── External Accounts  (registered bank accounts, debit cards, and external wallets,
                        owned by the customer or one of its counterparties)

Quote  →  Transaction
           └── sourceToDestination inferred from the instruments
               (cryptoToCrypto, cryptoToFiatAccount, cryptoToCash,
                fiatAccountToCrypto, cashToCrypto)

Cash-in  (code-based cash deposit → auto-creates Transaction)

Webhooks  (API-managed subscriptions, full CRUD)
All financial operations belong to a Customer. A customer has zero or more wallets. Counterparties, virtual accounts, deposit addresses, quotes, and transactions are also scoped to a customer; external accounts belong to a customer or to one of its counterparties. Webhook subscriptions are managed through the API independently of any customer.

Customers

A customer is an identity record. Before a customer can move money, OMS must grant endorsements that unlock specific capabilities.
EndorsementUnlocks
basicStandard operations
cryptoCustodyCrypto custody and advanced features
usdUSD stablecoin operations
Customers are created via POST /customers with a type (for example individual) and an endorsements array. Endorsements are granted after KYC/KYB verification; a webhook fires as they change.

Wallets

The Payments API wallet resource is custodial: OMS manages the keys, and they never leave OMS infrastructure. Wallets hold stablecoin balances (USDC by default) and are the source or destination for all transactions. Wallets are created and listed under the customer: POST /customers/{id}/wallets (body specifies asset and chain) and GET /customers/{id}/wallets. Each wallet holds a single asset on one chain and has an onchain address. GET /wallets/{id}/balance returns that wallet’s current balance for its asset and chain. For user-controlled keys (onchain consumer apps, agentic flows), use OMS non-custodial wallets. The two models can be combined.

Virtual accounts

A dedicated bank account number assigned to a customer. When fiat arrives via a supported bank rail, OMS automatically creates a fiatAccountToCrypto transaction and delivers USDC to the customer’s wallet. Create one with POST /virtual-accounts; the body specifies the customerId, the source asset and network, a destination (an OMS wallet, or a registered external wallet by ID), the accountHolder (always customer), and the account type (bankUs). The response’s bankDetails is null until the underlying deposit account is provisioned. Virtual accounts support list, get, and update (GET /virtual-accounts, GET/PATCH /virtual-accounts/{id}). Deletion is asynchronous: DELETE /virtual-accounts/{id} returns 202, and the status finalizes to deleted once the underlying account closes.

Deposit addresses

A persistent onchain address. When crypto arrives, OMS automatically creates and executes a transaction that delivers fiat to a registered bank external account. Create one with POST /deposit-addresses; the body specifies the customerId, the expected source asset (usdc or usdt) and network, and a registered bank external account as the destination. The response’s depositInstructions is null until provisioning populates the OMS-owned inlet address. Deposit addresses support list, get, and update (GET /deposit-addresses, GET/PATCH /deposit-addresses/{id}); there is no delete. Deposit addresses must be enabled for your project: contact us to enable them.

Counterparties

A person or business a customer transacts with, scoped to that customer. Create one with POST /counterparties; the body requires customerId and name, with optional identity fields (entityType, email, phone, dateOfBirth, taxId, nationality, address, metadata). The address object takes streetAddress, city, postalCode, and country, plus an optional countryArea. Counterparties support full CRUD. Listing requires the customerId query parameter (GET /counterparties?customerId=...). A counterparty can own external accounts; DELETE /counterparties/{id} returns 409 while the counterparty still owns active external accounts.

External accounts

A registered bank account, debit card, or external wallet, owned by a customer or by one of the customer’s counterparties. External accounts are referenced by ID as the source for on-ramps or the destination for off-ramps. Register one with POST /external-accounts. The body specifies the owner ({ kind: "customer", customerId } or { kind: "counterparty", counterpartyId }), a type (bankUs, bankIban, bankCanada, card, or walletExternal), and exactly one per-type details object matching the type. Debit cards register through this same endpoint. GET /external-accounts requires a customerId and accepts an optional counterpartyId filter; PATCH updates label and metadata; DELETE removes the registration. ID prefixes: ext_card_ (debit cards), ext_bankUs_ (US banks), ext_bankIban_ (IBAN banks), ext_bankCa_ (Canadian banks), ext_wlt_ (external wallets).

Quotes and transactions

The two-step flow for most money movement:
  1. POST /quotes: lock pricing, return full fee breakdown
  2. POST /transactions: execute against the locked quote
Quotes expire if not used within the validity window. pricing.fixedAmountSide indicates which side of the trade was specified.

Cash-ins

A code-based deposit flow for in-person cash at retail locations. Creates a deposit code the customer presents at a partner location. OMS converts the deposited cash to USDC and auto-creates a transaction. No upfront amount is required.

Webhooks

API-managed event subscriptions with full CRUD. Register a subscription with POST /webhooks (body { url, events }) and OMS delivers events as state changes occur; each delivery carries the full object so your handler branches on its status. Subscribe to specific event types, or pass an empty events array (or ["*"]) to receive all of them. Subscriptions are created, listed, updated, and deleted through the API (GET/PATCH/DELETE /webhooks/{id}) as well as in the dashboard. The create response returns a signing secret once for verifying the Webhook-Signature header.
Virtual accounts, deposit addresses, and cash-ins all bypass the quote step. They go directly to processing because OMS cannot lock pricing before the funds arrive.