Quotes

Estimate how much a user will receive for a given input amount. Always quote before showing a number — rates and minimums move with market conditions.

POST/v1/quotes

Request body

NameTypeRequiredDescription
fromstringrequiredLowercase payin currency ticker.
tostringrequiredLowercase payout currency ticker.
amountFromstringrequiredDecimal string (e.g. "0.01"). The amount the user will send.
modestringoptional"float" (default) or "fixed". "fixed" locks the rate and returns a rateId — see Fixed-rate quotes below.

Example

const res = await fetch(`${BASE}/v1/quotes`, {
  method: 'POST',
  headers: { 'Authorization': AUTH, 'Content-Type': 'application/json' },
  body: JSON.stringify({ from: 'btc', to: 'eth', amountFrom: '0.01' }),
});
const { quote } = await res.json();
console.log(`User receives ~${quote.amountUserReceives} ${quote.to}`);

Response

{
  "quote": {
    "from": "btc",
    "to": "eth",
    "amountFrom": "0.01",
    "amountTo": "0.1532",
    "networkFee": "0.0021",
    "amountUserReceives": "0.1511",
    "rate": "15.32",
    "fee": "0.001",
    "min": "0.0008",
    "max": "5.0",
    "mode": "float"
  }
}

Response fields

NameTypeDescription
amountTostringEstimated payout before subtracting networkFee.
networkFeestringOn-chain fee for the outbound transfer, in the payout currency.
amountUserReceivesstringThe number to display to the user. Equal to amountTo - networkFee. We compute this for you so the math is right.
ratestringExchange rate used (before fees).
feestringLiquidity provider fee in the payout currency.
minstringMinimum payin for this pair.
maxstringMaximum payin for this pair.
modestringThe quote mode — "float" here. See the Fixed-rate quotes section for "fixed".

Fixed-rate quotes

Pass mode: "fixed" to lock the exchange rate. Instead of an indicative quote you get a rateId — a short-lived token that pins the rate. Hand that rateId to POST /v1/swaps and the user is guaranteed the quoted output amount, regardless of how the market moves between quote and deposit.

const res = await fetch(`${BASE}/v1/quotes`, {
  method: 'POST',
  headers: { 'Authorization': AUTH, 'Content-Type': 'application/json' },
  body: JSON.stringify({ from: 'btc', to: 'eth', amountFrom: '0.01', mode: 'fixed' }),
});
const { quote } = await res.json();
// quote.rateId    → pass to POST /v1/swaps
// quote.expiresAt → ISO timestamp; re-quote once it passes

A fixed quote response sets "mode": "fixed", carries two extra fields, and omits fee:

{
  "quote": {
    "mode": "fixed",
    "from": "btc",
    "to": "eth",
    "amountFrom": "0.01",
    "amountTo": "0.1532",
    "networkFee": "0.0021",
    "amountUserReceives": "0.1511",
    "rate": "15.32",
    "min": "0.0008",
    "max": "5.0",
    "rateId": "f7c2a1b9e4d8...",
    "expiresAt": "2026-05-21T18:01:00.000Z"
  }
}
NameTypeDescription
rateIdstringThe locked-rate token. Pass it as rateId to POST /v1/swaps with mode: "fixed". Present only on fixed quotes.
expiresAtstringISO 8601 timestamp when the rateId expires — roughly 60 seconds after the quote. Present only on fixed quotes.

Rules for fixed-rate quotes:

  • The rateId is valid for only ~60 seconds. Create the swap promptly. Once expiresAt passes, request a fresh quote — a stale rateId is rejected on swap creation with rate_expired (HTTP 409).
  • Pass the same amountFrom to POST /v1/swaps that you quoted. The locked rate is bound to that exact input amount.
  • A fixed quote has no fee field — the locked rate already accounts for the liquidity-provider fee.

Notes

  • Always show amountUserReceives as the headline number. Showing raw amountTo over-promises by networkFee.
  • Use tickers from GET /v1/currencies; the quote response echoes canonical tickers. Example: USDT on TRON is usdtrx (common aliases like usdttrx are accepted but normalized).
  • Float quotes are indicative, not locked. The final amount on POST /v1/swaps may differ slightly because we re-quote at swap creation time.
  • For a locked rate that can't drift between quote and deposit, use fixed-rate quotes (mode: "fixed") — see the section above.

Errors

Type / codeWhen
validation_error (amount_below_min, HTTP 400, param: amountFrom)amountFrom is below the pair's minimum. Error message includes the minimum.
validation_error (amount_above_max, HTTP 400, param: amountFrom)amountFrom is above the pair's maximum. Error message includes the maximum.
validation_error (pair_unsupported, HTTP 400, param: pair)The from/to pair is not currently available for the requested mode (float or fixed).
validation_error (other)Missing field or invalid currency.
authentication_error (unauthenticated)Missing/invalid Authorization header.
rate_limit_error (rate_limited)Per-credential limit exceeded. See Rate limits.
upstream_error (provider_credential_pending, HTTP 503)Your account is still being activated. Fee-sensitive quotes and swap creation will succeed once activation completes.
upstream_error (upstream_empty_quote, HTTP 502)Genuine upstream issue (rare — usually amount_below_min / amount_above_max is returned instead when our pair-bounds lookup succeeds). Back off and retry.
upstream_error (other)Generic liquidity-layer issue. Back off and retry.