Route / developers

Compare routes

Discover exact assets, request a quote and accept its recommendation using your API key's policy. Quotes do not need wallet addresses. Preparation checks the actual wallet before signing.

Choose exact assets#

Call GET /v1/assets and keep the returned IDs, networks, decimals and chain identities: address (the EVM token contract, the Stellar asset contract, a provider-chain token address, or native), issuer for Stellar classic assets, and providerChain and nearAssetId for NEAR Intents provider tokens. Some EVM contracts are EIP-55 checksummed, so compare EVM addresses case-insensitively. Verify an asset by these identities, not by the form of its ID: native Circle USDC on Stellar has issuer GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN although its ID derives from a NEAR Intents identifier. Your app chooses the source, destination and source-asset amount on each request. A matching symbol alone is not a matching asset; native Stellar USDC, USDC.ITS and USDT0 are different representations. Check each direction independently.

Request a quote#

Choose source and destination assets on each quote request; they do not need to be configured when creating your API key. The same key can request different pairs, subject to any optional key restrictions and the assigned policy. Read /assets, then use the returned id values exactly. Stellar asset issuers and network-specific identities must not be replaced by EVM addresses or a symbol alone. Amounts are decimal strings in source asset units, respecting its decimals.

{"sourceAssetId":"EXACT_SOURCE_CATALOG_ID","destinationAssetId":"EXACT_DESTINATION_CATALOG_ID","amount":"1000"}

Send this to POST /quotes with a UUID Idempotency-Key. Mainnet responses default to view=best: object, apiVersion, id, status, expiresAt, the requested asset IDs and amount in input, one quote summary, and nextAction. The summary contains received, minimumReceived, estimatedCostUsd, costComplete and legs.

ready-for-preparation means the recommended path passed quote checks and has released execution support. requires-fee-confirmation means only source gas remains to be checked with the actual wallet. Neither status authorizes spending. For unavailable or expired, quote and nextAction are null. Otherwise, nextAction is create-payment-and-prepare.

Request these views on POST /v1/quotes, POST /v1/auto-route or GET /v1/quotes/{id}:

View Response
best (mainnet default) One recommendation summary, without a candidate list.
list The same envelope with recommendedCandidateId and ranked candidates replacing quote. Each row contains candidateId, status and the summary fields. Only paths that can safely proceed to preparation appear.
compact The previous compact response, including all candidates, policy checks, expiry, execution/preparation selections and normalized provider failure codes.
full The previous detailed response, including policy and key restrictions, valuation, provider metadata, gas evidence and resolved asset inputs.

Use compact or full to diagnose blocked or unavailable routes; those rows are omitted from list. Testnet still defaults to compact and requires an explicit candidate. Auto-route remains mainnet-only. Invalid or repeated view parameters return 400 INVALID_QUOTE_VIEW before requesting a quote or spending quote credits.

CCTP read failures expose optional details.capacityErrorCode, capacityErrorKind, capacityErrorNetwork, capacityErrorHost, capacityErrorMethod and capacityErrorCheck on the candidate or its composed leg in compact/full. These identify the failed check using a normalized code, category and public RPC hostname; they contain no raw upstream message, body or URL. capacity.status: "unknown" remains a blocker, not proof that the amount exceeds a limit. best and list keep their summary shape.

The view changes only the response. Route retains full saved evidence. Reading a quote never creates a payment. Reads and identical idempotent replays with a different view do not refresh providers, extend expiry or add a charge. Integrations that consume the previous response fields can request compact or full explicitly.

input.amount is a decimal string in source asset units; received and minimumReceived are decimal strings in destination asset units; estimatedCostUsd is a decimal USD amount. Respect each asset's catalog precision and use decimal arithmetic. Missing estimates remain null, never zero. legs counts provider transfers: more than one means a non-atomic workflow that re-quotes later legs after settlement, with separate wallet authorization. A recommendation reflects observed paths and the saved policy or Auto-route objective; it does not guarantee a globally best price. Incomplete costs can change the ranking after preparation.

Quotes are observations, not liquidity reservations; always honor expiresAt. In compact/full, individual candidates also have expiry, fee treatment and scoped ETA; attestation timing alone does not mean recipient arrival. Only candidates meeting policy checks can be recommended.

Rift uses this same API flow for reviewed crypto, tokenized stocks, ETFs and vault shares, including different assets on the same network. Choose exact issuer/network/contract identities from the catalog. Its minimumReceived is null; direct supported EVM/Bitcoin orders require explicit acceptVariableOutput: true at preparation. HyperCore and composed Rift paths remain quote-only. Provider reports of delivery or refund remain verification-pending until independently linked chain receipts are confirmed. See Rift preparation and coverage.

Prepare a route whose source gas needs confirmation#

A missing historical gas sample does not prevent wallet preparation. When source transaction gas is the only unresolved check, the best response has status: "requires-fee-confirmation". In compact/full, the candidate exposes preparation.eligible: true and deferredChecks: ["source-gas"]. Its decision remains needs-data and costComplete remains false until the cost is validated. Provider fees, fresh USD prices, capacity and owner-selected delivery requirements must already pass. Quotes with failed checks are excluded.

In compact/full, preparationSelection.candidateId identifies the first unexpired preparation candidate with released, enabled execution support. order contains the available choices. provisional: true means the selected candidate needs source gas confirmation. rankingComplete: false means at least one preparation choice has incomplete costs, so this order cannot establish the lowest total cost. Standard routing uses the owner's priority; Auto-route uses its interpreted objective. This field can be non-null while selected and executionSelection.candidateId are null.

  1. Accept the mainnet recommendation with POST /payments using {mode: "prepare", quoteId}. Include candidateId to choose a different candidate explicitly.
  2. Call POST /payments/{id}/prepare with the actual public sender and recipient addresses and the adapter's required fields. This can reserve a provider attempt; persist its identity and retry the same operation after a timeout.
  3. Route builds the actual wallet action and checks its network fee, native balance, recipient requirements, fresh prices and owner limits. Protocol preparation skips the historical gas scan; EVM calls and Stellar contracts use transaction simulation, while Bitcoin uses the actual selected inputs and transaction size.
  4. Follow the prepared action's signing and submission flags. A source-gas deferral is never permission to sign or fund an unchecked transaction. If an approval is needed, complete that separately, then request the fresh transfer action. No approval is requested when the existing allowance is sufficient.

Preparation normally resolves the fee when network reads and transaction simulation succeed. A reverted simulation, insufficient balance, missing fresh price or unavailable node produces a blocker. Route never substitutes zero gas or bypasses the owner's fee limit. For composed routes, only the first leg's source gas can be deferred: a complete second-leg preview budget is still required before starting, and the actual second transaction is checked again after receipt. No new fee, credit rate or charge trigger is introduced by this selection field.

Gas estimate evidence#

In view=full, gas exposes each network budget with its currency, assumptions, sample count and availability. Its components add up to the gas amount: execution, rollup data posting and operator fees where applicable, or a network fee for Bitcoin and classic Stellar payments. Arbitrum's historical data-posting gas is removed before applying today's posting estimate, so it is counted once. Provider messaging and destination-delivery charges remain separate entries in fees; components explain a gas total and must not be added to it again.

Ethereum, Base and Arbitrum source budgets also apply when the destination is Stellar. The normal historical model uses successful canonical direct calls from the last 24 hours matching the contract, method and supported path. Route reads that history backward, newest first, in pages sized to public RPC limits, and stops at three samples, the 24-hour limit or its fixed read budget. Stellar CCTP samples may carry metadata after the recipient hook. Three samples use a 25% margin; one or two use 50% and low confidence. If a quiet OFT path has no such recent sample, Route can use exact-path references from the last seven days after verifying unchanged source/token runtime and EIP-1967 implementation code. This fallback reports referenceOnly: true, sampleWindowHours: 168, marginBps: 10000 (a 100% margin), and low confidence. Changed or unverifiable deployments, missing required fee components and older references remain unavailable.

newestSampleAt identifies historical execution evidence; estimatedAt records the current fee estimate. Current gas prices and rollup fee oracles apply to every EVM budget, including older references. These are comparison estimates, not guaranteed fee ceilings or wallet-readiness checks. Configuration, balance and allowance can differ from the reference transfer; Route simulates the actual transaction and enforces the owner's fee limit before signing. NEAR classic Stellar deposits use live Horizon fees, excluding Soroban calls and account/trustline setup. NEAR native Bitcoin deposits use the documented transaction-size and fee-rate model.

NEAR deposits from Solana and Fogo use the current RPC fee for the released one-signature deposit message, including its priority fee, with a 25% network-fee margin. Original SPL-token deposits also reserve the live rent for one new recipient token account; an existing account reduces the actual requirement. The estimate uses recent global priority observations, so it cannot predict wallet-specific contention. Token extensions and other signing arrangements are not included. Preparation rechecks actual accounts, rent, balances and transaction simulation. A missing or invalid observation leaves amount: null and an unavailableReason; it never becomes a zero fee.

eta.referenceOnly: true identifies historical or broad traffic references that cannot satisfy the delivery policy. LayerZero uses the exact OFT peers, including Stellar's encoded contract identity; sparse current traffic can show a labeled 30-day reference. Axelar's source-chain GMP median is not a full ITS estimate. NEAR estimates begin after deposit confirmation; they do not include the time to obtain that confirmation. Bitcoin source recognition and destination arrival are separate observations. Follow the Bitcoin confirmation and delivery guidance. Stellar-source CCTP exposes Standard attestation at approximately five seconds; it does not offer a separate Fast source mode. Attestation and mint delivery remain separate stages.

When LayerZero timing is unavailable, eta.unavailableReason distinguishes insufficient matching history from an upstream restriction, timeout or other read failure. A transient history read is retried once. Cost-priority policies with maxSeconds: null can still select a route with unavailable or historical-reference timing if every other policy check passes.

In view=full, valuation.networkGas prices native gas by network, including intermediate networks. Public prices are batched and may be reused for up to 60 seconds, never beyond their original five-minute freshness limit. Preparation and signing revalidate prices. If CoinGecko is unavailable or omits an asset, Route tries DefiLlama using the exact chain and contract or reviewed asset-price identifier, validating precision, timestamps and confidence. An optional configured CoinMarketCap fallback uses reviewed numeric market IDs and active listings; symbols never select a market. Remaining supported identities can use a timestamped Kraken USD trade or a fresh narrow order-book midpoint. valuation.*.source identifies CoinGecko, DefiLlama, CoinMarketCap or Kraken. assetId identifies the asset; market identifies a reviewed Kraken pair or cmc:<numeric ID>. USDT0 retains its distinct market identity. Failed, stale or missing prices remain unknown. Stablecoins are never assigned a fixed one-dollar value. See pricing failures for retry guidance.

Use a new Idempotency-Key for a new quote after a policy or data-source fix. Reusing an old quote request's key returns its saved observation; it does not refresh pricing or rerun the comparison.

Mainnet execution availability#

Use startPayment on the configured mainnet SDK to request the best quote, accept it and read the next required payment action. Persist both UUID request IDs with the business order before calling it. With exact catalog IDs and a decimal source-asset amount:

const { quoteId, paymentId, nextAction } = await sdk.startPayment(
  { sourceAssetId, destinationAssetId, amount },
  { quoteRequestId, paymentRequestId }
);
// Save these IDs and follow nextAction.action.type through the payment workflow.

The result is {quoteId, paymentId, nextAction}; nextAction is the existing payment next-action response. Refusals throw and stop the workflow. After a timeout, call again with identical input and both saved IDs: the server can return the existing payment even if its quote has since expired. The helper does not automatically retry, replace a payment, sign or submit a transaction. A fresh quote needs new request IDs.

For separate API calls, accept the recommendation with POST /v1/payments, {mode: "prepare", quoteId}, and a new persisted UUID Idempotency-Key, or call acceptQuote(quoteId, paymentRequestId). Route uses the recommendation bound to the saved quote, preferring a fully checked execution choice over the source-gas-only preparation fallback. It rechecks expiry, policy/provider settings and the original and current key restrictions. If that choice is no longer usable, Route refuses; it never silently switches routes. Creating a payment saves a draft; provider preparation, wallet checks and authorization remain separate.

To choose an alternative, use a candidateId returned by view=list with the existing createDraft(quoteId, candidateId, paymentRequestId) method. Reuse the identical body and key after a timeout. Omitting candidateId is mainnet-only; null or an empty ID is invalid.

In compact/full, executionSelection.candidateId identifies a fully eligible path with execution support; preparationSelection.candidateId is the source-gas fallback. selected can name a quote-only route and is not an execution instruction. executionEnabled describes released support, not passed policy or wallet checks. If only source gas remains unresolved, follow the preparation flow and require live readiness before signing.

Owners may set maxSeconds: null to omit a delivery deadline. Cost priority can then use a path with partial ETA; speed priority still requires comparable full-arrival estimates. USD payment and fee limits remain mandatory and unchanged.

For supported NEAR/OFT swap-and-bridge routes, use the composed payment workflow. It keeps both child payments under one parent, re-quotes after the intermediate receipt and retains the final recipient minimum.

NEAR deposits from supported EVM networks can renew an expired review on the same payment, with a fresh wallet intent challenge and no replacement transaction or deposit. New review windows are capped at five minutes and the original provider/refund deadlines. Other source families and submitted or uncertain actions remain subject to reconciliation.

Continue with the selected payment#

Save the quote ID, payment request ID and returned payment ID with your business order, then follow Execute a payment. If you selected an alternative explicitly, also save its candidate ID. Show fresh wallet checks and fees before asking for a signature.

Standard eligible comparisons cost 1 credit; Auto-route comparisons cost 4. Reads and ineligible comparisons are free. See the complete billing rules for payment holds and retries.

Example client#

route-client.mjs uses only Route endpoints and has no provider SDK dependencies. Its prepareDeposit, getPreparation, wallet approval, registerSource and refreshPayment methods follow this same lifecycle. quickstart.mjs discovers Ethereum and Stellar USDC, requests a quote, saves a review draft if possible and reads its blockers. It never signs a transaction.

Set ROUTE_BASE_URL, ROUTE_API_KEY and ROUTE_QUOTE_REQUEST_ID in your backend environment, then run node quickstart.mjs with both downloads in the same directory. ROUTE_PAYMENT_REQUEST_ID and ROUTE_CANDIDATE_ID are only needed to opt into saving a review draft. Keep those UUIDs for retries; use new ones for a new comparison. Optional ROUTE_AMOUNT defaults to 100.

Links from earlier guides

This section is now in Compare routes.

This section is now in Configure access.

This section is now in API reference.

This section is now in Multi-step payments.

This section is now in Provider connections.

This section is now in Execute.

This section is now in Track and recover.

This section is now in NEAR execution.

This section is now in NEAR execution.

This section is now in NEAR execution.

This section is now in NEAR execution.

This section is now in Usage and billing.

This section is now in Track and recover.

This section is now in Track and recover.

This section is now in Provider connections.

This section is now in Auto-route.