/routes for capability and decimals, /limits for form validation, then /estimate for pricing and /quote when the user commits. Do not hardcode availability or bounds.
Routes
GET /v2/orchestration/routes returns { assets: [...] }, one entry per asset. The id is <chain>:<asset>, for example base:USDC, ton:GRAM, hypercore:USDC. Fetch it:
to: supported destinations.exactOutTo: destinations supporting exact-out amounts.fixedTo: destinations supporting fixed delivery.
"all" (every other asset), a list of ids (empty means none), or an object with an except list. Availability also depends on partner configuration and live pricing. Discover routes with the same partner key used for quotes when applicable.
contractAddress identifies the token; native assets use null. chainId identifies the network where supplied. decimals is the smallest-unit exponent for that specific asset: Base USDC uses 6, BSC USDC 18, and Hypercore USDC 8. Never infer decimals from the ticker.
Read capability from set membership, not from the symbol. Two assets that share a ticker on different chains are different ids with different sets, and an id that is missing from the response is never routable.
Limits
GET /v1/orchestration/limits returns { generatedAt, routes: [...] } with bounds per canonical route. Filter by sourceChain, sourceAsset, destinationChain, and destinationAsset:
dynamicProviderLimits.possible is true, live pricing can still reject an amount inside the published band. Every bound has a typed entry in constraints whose source is one of runtime_order_bounds, flashnet_static_limit, bitcoin_l1_delivery, provider_quote, or fiat_amount.
Three minimums are static and enforced in code: 5,000 sats of swap input from Bitcoin L1 (published as minAmountSmallest: "5149" once the static deposit fee is added), 1,200 sats from Spark, and 10,000 sats for delivery to Bitcoin L1.
Some cross-chain planner routes appear on /routes but not on /limits. Treat /limits as a guardrail for your form, not as an execution guarantee: /estimate and /quote can still return amount_too_small, amount_too_large, amount_exceeds_liquidity, or route_unavailable for an amount inside the published band.
Both endpoints are rate limited to 60 requests per minute per IP. Responses carry X-RateLimit-* headers and exhaustion returns 429 rate_limited. See Rate limits.