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/quotesRequest body
| Name | Type | Required | Description |
|---|---|---|---|
from | string | required | Lowercase payin currency ticker. |
to | string | required | Lowercase payout currency ticker. |
amountFrom | string | required | Decimal string (e.g. "0.01"). The amount the user will send. |
mode | string | optional | "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
| Name | Type | Description |
|---|---|---|
amountTo | string | Estimated payout before subtracting networkFee. |
networkFee | string | On-chain fee for the outbound transfer, in the payout currency. |
amountUserReceives | string | The number to display to the user. Equal to amountTo - networkFee. We compute this for you so the math is right. |
rate | string | Exchange rate used (before fees). |
fee | string | Liquidity provider fee in the payout currency. |
min | string | Minimum payin for this pair. |
max | string | Maximum payin for this pair. |
mode | string | The 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 passesA 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"
}
}| Name | Type | Description |
|---|---|---|
rateId | string | The locked-rate token. Pass it as rateId to POST /v1/swaps with mode: "fixed". Present only on fixed quotes. |
expiresAt | string | ISO 8601 timestamp when the rateId expires — roughly 60 seconds after the quote. Present only on fixed quotes. |
Rules for fixed-rate quotes:
- The
rateIdis valid for only ~60 seconds. Create the swap promptly. OnceexpiresAtpasses, request a fresh quote — a stalerateIdis rejected on swap creation withrate_expired(HTTP 409). - Pass the same
amountFromtoPOST /v1/swapsthat you quoted. The locked rate is bound to that exact input amount. - A fixed quote has no
feefield — the lockedratealready accounts for the liquidity-provider fee.
Notes
- Always show
amountUserReceivesas the headline number. Showing rawamountToover-promises bynetworkFee. - Use tickers from
GET /v1/currencies; the quote response echoes canonical tickers. Example: USDT on TRON isusdtrx(common aliases likeusdttrxare accepted but normalized). - Float quotes are indicative, not locked. The final amount on
POST /v1/swapsmay 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 / code | When |
|---|---|
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. |