cryptoToFiatAccount). No developer action is required after the address is provisioned.
Deposit addresses are persistent. OMS keeps them active until they are frozen or closed.
Deposit addresses must be enabled for your project before you can create them, and the customer must be provisioned for them. To get set up, share your use case below.
Contact us
Tell us about your on-ramp flow and we’ll enable deposit addresses for your project.
How it works
Once a deposit address is provisioned, you display its on-chain address to the customer. When a supported stablecoin arrives at that address, OMS:- Detects the inbound transfer on the source chain.
- Creates a transaction whose
precursoris{ "type": "depositAddress", "id": "da_..." }. Dereference the deposit address by thatidfor its inlet address and instructions. - Moves the transaction directly to
processing(there is no quote step, because pricing cannot be locked before the funds arrive). - Converts the incoming crypto and delivers it to the configured fiat destination.
sourceToDestination: "cryptoToFiatAccount" and follows the standard transaction lifecycle, including webhook events.
Creating a deposit address
Create a deposit address withPOST /deposit-addresses:
The
201 response returns the deposit address with depositInstructions: null. Provisioning populates the OMS-owned inlet address asynchronously, and the address moves from pending to active once the instructions are ready.
Deposit instructions
ThedepositInstructions field carries the details to display in your UI. It is null until provisioning completes:
Crypto sent to
address is converted and paid out to the configured fiat destination.
Payout memo
A deposit address destination can carry an optional customer-supplied payment memo that OMS delivers to the beneficiary’s bank in place of the memo OMS would otherwise generate. Setdestination.details.memo on create or on a PATCH that replaces destination.
memo is not honored on bankUs destinations with network: "ach" or network: "achSameDay", on the CAD/local leg of bankCanada, on virtual accounts, or on quote requests. A non-empty value on those surfaces is rejected with 422 memoNotSupported. A value outside the allowed character set or over 140 characters is rejected with 422 validationError. An omitted, null, or whitespace-only value is accepted everywhere.
ACH company discretionary data
For abankUs destination with network: "ach" or network: "achSameDay", set an optional destination.details.companyDiscretionaryData. OMS carries the value in the NACHA batch header on every outbound ACH payout from the deposit address. This is the originator’s internal metadata and never reaches the beneficiary; it is distinct from memo, which does.
Customer summary
Deposit addresses carry acustomer summary resolving the owning customer in one hop:
GET /deposit-addresses/{depositAddressId}, on every entry of GET /deposit-addresses, on POST /deposit-addresses and PATCH /deposit-addresses/{depositAddressId} responses, and on the deposit-address webhook payloads. The destination instrument also carries an opaque displayName you can render as-is. See Customer summary on a transaction and Instrument display name for the shared model.
Listing and retrieving
GET /deposit-addresses lists deposit addresses across every customer in your organization. Both filters are optional: customerId scopes the list to one customer, and status to one lifecycle state. Paginate with limit, startingAfter, and endingBefore; each page returns nextCursor, previousCursor, and hasMore.
GET /deposit-addresses/{depositAddressId} fetches a single deposit address by ID.
Updating
PATCH /deposit-addresses/{depositAddressId} accepts destination (re-point to a different bank-type external account), returnDestination, label, metadata, and sponsorGas; any other key in the body is rejected with 400.
Re-pointing destination to a healthy bank external account recovers a deposit address from inactiveActionRequired back to active. A re-point on an already active address updates the target without a status transition.
There is no delete endpoint for deposit addresses.
Statuses
Simulating inbound deposits
Sandbox deposit addresses accept real testnet transfers. Fund the address’s on-chain inlet from a testnet faucet (for example, Circle’s testnet USDC faucet on Sepolia), and OMS reacts to the on-chain confirmation just as it would to a mainnet deposit: the standardcryptoToFiatAccount transaction is auto-created and progresses through the transaction lifecycle, firing the same webhook events.
There is no sandbox-only simulation endpoint for a deposit-address inbound. The fiat sibling on virtual accounts (see Simulating inbound deposits) still exists because bank rails have no public testnet.
Deposit address vs. virtual account
Both are persistent auto-route configurations. The difference is which side is fiat:Related
- Deposit addresses guide: walkthrough of the inbound flow and webhook handling
- Virtual accounts: the fiat equivalent, a bank account number that auto-converts to crypto
- External accounts: registering the bank account a deposit address pays out to
- Transaction lifecycle: statuses, sub-statuses, and webhook events for the auto-created transaction
- Failed transactions and returns: where inbound crypto goes when the payout cannot complete, and how to configure it