Skip to main content
Every transaction you create with POST /transactions starts from a quote. A quote locks the amounts and fees for a short window, so the customer sees a guaranteed price before you commit. You create a quote when the money starts in an OMS wallet (walletCrypto or walletFiat) or on a debit card (card). Transactions that virtual accounts, deposit addresses, and cash-ins create for you skip this step; see When quotes are not required.

Quote lifecycle

The window is short: 30 seconds by default, set per project, and never longer than the underlying provider will hold the price. expiresAt on the quote is the deadline. Creating a transaction from an expired quote returns 422 QuoteExpired, and reusing an accepted quote returns 422 QuoteConsumed. Create the quote when the customer is ready to confirm, not when they open the screen.

Checks at quote time

OMS validates the whole route when you create the quote, so most problems surface before any money moves:
  • Unsupported pairs. A source and destination combination OMS cannot route is rejected with 422 before a quote exists. The error’s details.supportedDestinations lists what the source can reach.
  • Customer readiness. A customer whose cryptoCustody endorsement is not active is refused with 403 KYCRequired on routes that need custody, even when the project does not require KYC.
  • Limits and corridor rules. Amount limits, rail availability, and cash pickup rules return their own 422 errors.
OMS checks custody again when you create the transaction, so a customer whose status changes between the two calls is still caught.

What a quote contains

  • source and destination: the two sides, echoed from the request with resolved instrument detail.
  • pricing: the amounts on each side, every fee, the exchange rate, and gas sponsorship.
  • sourceToDestination: the corridor, for example cryptoToCrypto, cryptoToFiatAccount, cryptoToCash, or fiatAccountToFiatAccount.
  • customerId and customer: the customer the quote belongs to, with a display name.
  • expiresAt: when the locked pricing expires.

Fee structure

Economics live in one pricing object. pricing.source.amount is the gross the customer pays, pricing.destination.amount is what arrives, and every fee is an entry in pricing.fees:
The amounts always reconcile:
pricing.fees is always present and is [] when no fees apply. Only non-zero fees are listed. Known fee types are developer, oms, and gas; treat type as open and display unknown types rather than rejecting them. Every amount is a decimal string at its asset’s precision: two decimals for usd and cad, and six for usdc and usdt. The same amount renders the same string in every response and webhook. Developer fees are your margin on top of OMS fees. They appear as developer entries in pricing.fees. Contact your OMS account team to configure them.

Gas sponsorship

Set sponsorGas: true on the quote request to cover network gas for the customer’s onchain delivery. When OMS absorbs the gas, pricing.sponsorGas is true on the response; the field is left out otherwise. Sponsored gas does not appear in pricing.fees. sponsorGas is ignored when the destination has no onchain leg.

Fixed-amount quoting

Set amount on exactly one side of the quote request; OMS calculates the other. pricing.fixedAmountSide reports which side you fixed:
  • source: the customer sends an exact amount and the destination is calculated. “I want to send $100.”
  • destination: the recipient receives an exact amount and the source is calculated. “My recipient gets exactly $100.”

When quotes are not required

Transactions that deposit addresses, virtual accounts, and cash-ins create for you skip the quote step. OMS prices them when the funds arrive, using the same pricing shape, but the price is not locked in advance.