Before you start: the OMS API is in early access. Every endpoint, including the ones in this guide, requires an early-access API key. Request access before you begin.
Deposit address provisioning and management is not yet available in the OMS API. To be notified when it launches, register your interest.
Register interest
Share your use case and we’ll reach out when deposit address provisioning and management is available.
GET /transactions/{id} and GET /customers/{id}/transactions) are available now.
Prerequisites
Before creating a Deposit Address, you need:- A customer with a
cst_ID and thecryptoCustodyendorsement active. - A crypto destination: a
WalletTargetobject with one ofwallet(OMS custodial wallet,wlt_),blockchainAddress(external on-chain address), orexternalAccount(saved on-chain address,cpBcAddr_). - Webhook subscriptions configured in the OMS Dashboard for
transaction.cryptoToCrypto.*events.
Step 1: Create the Deposit Address
Creating a deposit address is not yet available in the OMS API. The request and response below describe the intended shape so you can plan your integration.
usdc or usdt on polygon or ethereum, and destinations are specified via a WalletTarget object (the same shape used elsewhere for crypto delivery).
Request
source.asset: The crypto asset to accept (usdcorusdt).source.network: The blockchain to monitor (polygonorethereum).destination.asset: The crypto asset to deliver (usdcorusdt).destination.network: The destination rail (polygonorethereum).- A
destination.walletobject with one of:wallet,blockchainAddress, orexternalAccount.
developerFees: Array of fee entries. Each entry hastype(percentage),rate(as a string, e.g.,"0.015"), and optionalwallet(OMS wallet receiving the fee). Percentage-only because the deposit amount is unknown until funds arrive. If omitted, no developer fees are collected.label: A human-readable name for this address.metadata: Up to 20 arbitrary key-value pairs.
Response, 201 Created
id: The Deposit Address ID (prefixda_). Use this for GET, PATCH, and DELETE operations.status: Starts asactive. Can be changed topausedordeletedlater.transactionType: AlwayscryptoToCryptofor the destinations defined in the request schema.source.depositInstructions: The blockchain address your customer should send funds to. This is server-generated and unique to this Deposit Address.omsFeeSchedule: Shows how OMS fees will be calculated on auto-created transactions. Since there is no Quote step for Deposit Addresses, this gives you visibility into the fee structure upfront.
source.depositInstructions.address to your customer as the address they should send crypto to. Store da_01H9Xy... in your system for tracking.
Test in sandbox
Once a deposit address is provisioned for you, you can simulate an inbound deposit in sandbox instead of sending real crypto. CallPOST /deposit-addresses/{depositAddressId}/simulate with an amount in cents. OMS returns a synthetic transactionHash and fires the same transaction.cryptoToCrypto.* webhooks as a real deposit. This endpoint returns 404 in production.
Step 2: Customer Sends Funds
The customer sends crypto to thedepositInstructions.address from any external wallet. There is nothing to do on the API side at this point, OMS monitors the blockchain for incoming deposits.
For this example, the customer sends 250.00 USDC on Polygon to 0xABC123....
Step 3: OMS Detects the Deposit and Auto-Creates a Transaction
When OMS detects the onchain deposit, it automatically creates a Transaction inprocessing status. This transaction skips the Quote step entirely, there is no Quote object, and quote is null.
Webhook, transaction.cryptoToCrypto.processing
OMS fires this webhook as soon as the transaction is created:
quote: null: Auto-created transactions skip the Quote step.depositAddress: "da_01H9Xy...": Links this transaction back to the originating Deposit Address.source.txHash: The onchain transaction hash of the incoming deposit.source.amountGross: "250.00": The actual amount deposited, now known.source.amountNet: "246.25": After deducting the 3.75 developer fee.destination.amountGross: "246.25": Amount to be delivered.destination.amountNet: "246.25": Same as gross (no additional fees on destination).source.feesDeducted.developer: "3.75": Your 1.5% fee on the 250.00 USDC deposit.fixedAmountSide: "source": The source amount is fixed; destination is calculated from it.- The
metadatafrom the Deposit Address is carried over to the transaction.
Polling Alternative
If you prefer polling over webhooks, you can retrieve the transaction directly:Step 4: Transaction Completes
OMS processes the conversion (in this crypto-to-crypto example, no exchange is needed since source and destination are both USDC on Polygon) and delivers funds to the destination wallet.Webhook, transaction.cryptoToCrypto.completed
processing webhook:
statusis nowcompletedandsubStatusisnull(sub-statuses only apply to the cash pickup flow).updatedAtreflects the completion time.
wlt_01H9Xf..., and 246.25 USDC has been delivered to the destination wallet wlt_01H9Xb....
Step 5 (Reuse): More Deposits
The Deposit Address remainsactive and continues monitoring 0xABC123.... Every subsequent deposit to that address triggers the same flow, a new auto-created transaction with a new txn_ ID, the same depositAddress, and fees calculated from the same configuration.
There is no limit on the number of transactions a single Deposit Address can produce.
Managing Deposit Addresses
The management operations below (pause, resume, change destination, delete, and list) are not yet available in the OMS API. They describe the intended pattern.
Pause a Deposit Address
Pausing stops OMS from processing new deposits. Any in-flight transactions continue to completion."status": "paused".
Resume a Deposit Address
Change the Destination
You can redirect future deposits to a different wallet or external account without creating a new Deposit Address. The source (and its deposit instructions) remain the same.Delete a Deposit Address
Soft-deletes the address. OMS stops monitoring for deposits.204 No Content.
List Deposit Addresses
Failure Handling
If a transaction fails after the deposit is detected, OMS fires atransaction.cryptoToCrypto.failed webhook with an error object:
transaction.cryptoToCrypto.refundCompleted webhook. If the refund itself fails, you’ll receive transaction.cryptoToCrypto.refundFailed.
Compliance Review
In some cases, a transaction may be held for compliance review. This fires a developer-only webhook (not forwarded to customers):processing status during review. Once resolved, it proceeds to completed or failed with the corresponding webhook.
Summary: Webhook Events for Deposit Address Transactions
| Event | When |
|---|---|
transaction.cryptoToCrypto.processing | Deposit detected, transaction created |
transaction.cryptoToCrypto.completed | Funds delivered to destination |
transaction.cryptoToCrypto.failed | Delivery failed |
transaction.cryptoToCrypto.refundCompleted | Refund sent back to sender |
transaction.cryptoToCrypto.refundFailed | Refund attempt failed |
transaction.cryptoToCrypto.underReview | Under compliance review (developer-only) |
Key Differences from Quote → Transaction Flow
Deposit Addresses differ from the standard Quote → Transaction flow in several ways:- No amount upfront. The Quote flow requires a known amount to generate pricing. Deposit Addresses handle “send any amount” scenarios.
- No Quote object. Auto-created transactions have
quote: null. Pricing is calculated when the deposit arrives. - Fee visibility via
omsFeeSchedule. Since there’s no Quote with exact pricing, the Deposit Address response includesomsFeeScheduleso developers know the fee structure in advance. - Percentage-only developer fees. Fixed USD fees aren’t supported because the deposit amount is unknown until arrival.
- Reusable. A single Deposit Address produces unlimited transactions over its lifetime. Quotes are one-time-use.
- Transactions start at
processing. There’s noopen→acceptedstep. The transaction goes straight toprocessingwhen the deposit is detected.