Core concepts

Quotes & smart routing

What a quote contains, when it can be filled, how long it lasts, and where fees and warnings show up

A quote prices a trade on one outcome across every venue that lists it, and returns the split that fills best. You then fill the quote by its quoteId. See Execution for the fill.

GET /orderbook/{venueMarketOutcomeId}/route

API reference: Get a quote (smart route).

Request

Query paramUse
sidebuy (default) or sell.
maxSpendBuy: the most to spend, in USD. Required for a buy.
sellSharesSell: how many contracts to sell.
slipCapBpsSlippage cap in basis points.
allowedVenuesOnly route to these venues. Repeat the param for several.
compareVenuestrue adds per-venue single-venue quotes in venueSoloQuotes[], each with its own quoteId.
deepEstimatetrue lists one-time setup costs in feeBreakdown.setupCosts. Hyperliquid's account activation is budgeted on every quote that routes to Hyperliquid either way; this flag only controls whether it, and the other setup items, appear as breakdown lines.
modelive (default) or paper.
signingAddress, fundingAddressesSelf-custody only. See Self-custody trading.
appFeeBips, appFeeBipsByVenue, referrer, referrerFeeBips, referrerFeeBipsByVenuePer-trade fee overrides. Send the ...ByVenue maps as JSON strings, for example appFeeBipsByVenue={"polymarket":20,"hyperliquid":10}. Need x-app-api-key. See Fees.
SDK
const quote = await client.getSmartRoute({
  venueMarketOutcomeId: outcomeId,
  tradeSide: "buy",
  maxSpend: 25,
});

In the SDK the trade direction is tradeSide. For signingAddress or fundingAddresses, use the HTTP query as shown in Self-custody trading.

  • Quote status (ok, no_orderbooks) is not a fill HTTP code (quote_not_found).
  • slipCapBps caps slippage; appFeeBips is your fee rate, not slippage.
  • status: "no_orderbooks" means the quote cannot be filled; a warning reason of no_orderbook only skips one venue.
  • A preview has no user JWT; an executable quote has the user's JWT.

Preview vs executable

SentResult
x-app-id onlyA preview quote. Use it to show a price. It cannot be filled, because it is not tied to a user.
x-app-id and the user's AuthorizationAn executable quote, sized against that user's balances. Fill it with POST /execution/fill.

A sell quote always needs a signed-in user. Filling a quote that belongs to someone else, or a preview quote, returns 400 with code: "quote_user_mismatch".

Can it be filled?

Check status before you fill:

statusMeaning
okA route was found. Check warnings and use an authenticated quote before filling.
insufficient_balanceThe user does not have enough funds.
insufficient_positionNot enough shares to sell. See positionAvailability.
insufficient_depth, no_orderbooks, no_bids_above_min_priceNot enough liquidity.
min_order_size_violated, insufficient_input_amountThe amount is too small for the venue.
infeasible, checker_rejected, solver_error, invalid_input, engine_unavailableNo valid route could be built.

When status is not ok, read error. message is informational. Only fill quotes with status: "ok".

Sellable shares

Every sell quote, ok included, carries positionAvailability: the user's shares when the quote was built, on the venues the request allows.

FieldMeaning
totalSellableSharesShares the user can sell in total. Asking for more returns insufficient_position.
venueMarketOutcomes[].availableSharesShares sellable on that leg. A leg is a tradeable position or a resolved, redeemable one.

Use it to cap the size you request, for example behind a "Max" button. It is a snapshot, not a reservation: the fill re-checks the live venue balance, so it can still fail if the position changed after the quote.

Expiry

Every quote carries two timestamps:

FieldMeaning
refreshAtFrom this time, fetch a new quote before showing a price. The current one still fills.
expiresAtAfter this time the quote cannot be filled.

A quote currently lasts about 45 seconds, with refreshAt about 15 seconds after it is created. Some routes expire sooner. Always read expiresAt; never hard-code the window.

A fill after expiry returns 400 with code: "quote_not_found" or "quote_expired". Follow Errors, retries & idempotency. fallbackToLatest is on Execution.

A quoteId fills at most once. See Errors, retries & idempotency.

What the quote contains

FieldMeaning
quoteIdPass to POST /execution/fill.
fills[]One entry per venue leg: venue, venueMarketOutcomeId, avgPrice, venueQty, venueFee, and the price levels used.
totalFilledTotal shares across legs.
feeBreakdownLine-item costs. See below.
totalCostIncFeesTotal the user pays, including app and referral fees.
estimatedPayoutPayout if the outcome wins, net of settlement fees.
estimatedProfit, returnPctPayout minus cost, in USD and percent.
slippageVolume-weighted price against the reference midpoint.
allocations[], bridgeSteps[]Which chain's funds pay for which venue, and any cross-chain moves needed.
warnings[]Venues left out or flagged, without blocking the quote.

Fees in the quote

feeBreakdown is the number to show before the user commits.

FieldMeaning (USD)
rawExecCostPrice times shares, before fees.
venueFeesVenue trading fees.
builderFeeBuilder-code fee, when present.
bridgeFeesExpected cross-chain transfer fees.
executionGasEstimated network gas for execution.
totalCostThe sum of the lines above. Excludes app and referral fees.
appFeeYour app fee on this trade, if it fills in full. A sell is charged on gross proceeds. Present only when above 0.
referralFeeA user-paid referral fee, when present.
setupCostsOne-time setup items, only with deepEstimate=true. Its hyperliquidActivation line shows $1.25: bridging to a new HyperCore address costs about $1.23 (Hyperliquid's 1 USDC plus Relay's ~$0.20 delivery cost, both deducted from the bridged amount), rounded up.

Use totalCostIncFees for the all-in number. Fees explains each kind.

Warnings

warnings[] lists venues the route skipped or flagged. Each entry has venue, venueMarketOutcomeId, and reason. The quote is still usable. Known reasons include low_liquidity, low_balance, stale_orderbook, empty_book, crossed_book, no_orderbook, app_fee_unsupported, referral_unpaid_on_solana, and referrer_not_activated_on_hypercore.

Geo warnings. A quote can still include venues unavailable in the user's country. The warning reason reads Venue not available in your region (XX) when the country is known. Before offering a fill, re-quote with allowedVenues restricted to eligible venues, or show that trading is unavailable. A sell quote warns on the held legs it would sell; those cannot be re-routed. The fill checks location again and can return 403 with code: "geo_blocked". See Venue geo availability.

Self-custody quotes also carry custodyWarnings[]. See Self-custody trading.

On this page