This page covers the custodial
wallet resource of the Payments API. If your product needs users to control their own keys on-chain (consumer apps, agentic flows), use OMS non-custodial wallets. The two models can be combined in a single product.Object
type is walletCrypto for a crypto wallet or walletFiat for a fiat wallet. A crypto wallet carries the network it operates on and its on-chain address, which is omitted until the custody provider reports one. A fiat wallet has no network or address. provider is the legal entity holding the wallet’s assets; treat it as a free-form string. routing reports whether the wallet is currently claimed by a live deposit address or virtual account; see Routing and wallet claims.
At launch, wallets are custodial only: a single asset on one chain. Provisioning is scoped per asset and chain, so hold multiple assets by creating one wallet each under the same customer.
Claimed wallets
A wallet that a live deposit address or virtual account settles into is claimed by that resource. Every wallet carries a read-onlyrouting object that reports this state:
routing.claimedBy identifies the claimant as { "type": "depositAddress", "id": "da_..." } or { "type": "virtualAccount", "id": "va_..." }, and claimedAt records when the current or last claim started. Both are absent when the wallet is unclaimed. releasedAt is set only when the status is released.
A claimed wallet stays readable by ID with its balance and transactions, and you can still update it. It cannot fund a withdrawal while the claim stands: POST /quotes and POST /transactions return 422 WalletClaimed. GET /wallets omits claimed wallets by default; pass includeHidden=claimed to include them.
Create a wallet
POST /customers/{id}/wallets provisions a wallet for a customer for the requested asset and chain, and returns the created wallet.
Idempotency-Key header to safely retry without provisioning duplicates.
If the customer has not completed KYC verification, wallet creation returns 403 KYCRequired.
Associate an embedded wallet
POST /customers/{customerId}/wallets/associate links an existing embedded (WaaS) wallet to a customer so subsequent operations reference it like any other wallet. The wallet is identified by a WaaS ID token in the request body: the token’s subject is the wallet ID, so the wallet ID is never passed directly, and the token’s audience must be the authenticated project. The response returns the associated wallet.
Balance
Read a wallet’s current balance withGET /wallets/{id}/balance. The response includes the display balance and its estimated value; pass estimatedBalanceCurrencyCode to value the balance in a currency other than USD (the default).
GET /customers/{id}/balance. See Customers.
To rank wallets by value, list them with GET /wallets?orderBy=balance. Wallets sort by the estimated USD value of their available balance, highest first; pass order=asc to reverse the order. Wallets without a USD estimate sort last. The order uses live balances, so a balance that changes while you page through the list can skip or repeat a wallet.
When a crypto-to-crypto quote converts funds between two of the customer’s own OMS Wallets, OMS refreshes both wallet balances as soon as the transaction write is durable. The project-wide GET /wallets list (called with no customerId) therefore shows the new source and destination balances right after POST /transactions returns, without waiting for the terminal webhook or a customer-scoped read. The refresh is best effort: an error is logged and never fails or rolls back the transaction. The partner response is withheld until the refresh ends or its short budget elapses.
Fiat wallet balance
A fiat wallet’sbalance renders as a fixed-point USD decimal string with exactly two decimal places: "0.00" for a never-funded wallet, "500.00" when funded, "-25.00" when overdrawn. The key is present on every 200, never omitted, never null. Crypto wallets keep per-asset decimal scaling, so a USDC balance still renders trimmed (for example, "1234.56").
When the wallet provider returns a successful balance response but omits an entry for a given wallet, estimatedBalanceValue defaults to "0.00" so a zero-balance fiat wallet keeps a stable response shape.
Funding a wallet
A wallet can receive funds in three ways:
A direct transfer to the
address credits the wallet balance. Virtual accounts and deposit addresses are the flows where OMS auto-creates a transaction in response to incoming funds.
Transaction history
GET /wallets/{id}/transactions returns a wallet’s transaction history, most recent first, with cursor-based pagination and optional transactionType, since, and until filters. The id path parameter accepts a wallet ID (wlt_ prefix).
Routing and wallet claims
A wallet becomes claimed when a live virtual account or deposit address is configured to route settlement funds to it. A claimed wallet stays visible and readable, but its outbound withdrawals are blocked while the claim stands.The routing field
Every wallet response carries a routing object:
claimedBy always resolves, even when the claiming resource has since been deleted, because the claim history is a separate persisted record.
What a claimed wallet allows and refuses
A balance the wallet held when it was claimed is preserved; the claim never drains funds.
Listing claimed wallets
The defaultGET /wallets page hides every wallet with claimStatus: "claimed". Pass includeHidden=claimed to include them:
GET /wallets/{id} returns a claimed wallet without the flag.
When the claim is released
Deleting or terminating the claiming virtual account or deposit address releases the wallet. The wallet’sclaimStatus moves to released, releasedAt is set, and the wallet becomes actionable again: it reappears in the default listing and can fund withdrawals.
Key operations
Programmatic wallet creation via
POST /wallets with an explicit custodyType (custodial or embedded) is coming in an upcoming release. Today, provision wallets under a customer with POST /customers/{id}/wallets.Related
- Virtual accounts: assign a bank account number that auto-funds a destination
- Deposit addresses: set up a monitored crypto address that routes to a destination
- Transactions: move funds out of a wallet via crypto, bank transfer, or cash