CCXT/Router beta

Find the best price for your trade, across ~60 exchanges.

Tell the router what you hold and what you want. It walks live order books from ~60 exchanges to your size, adjusts every level for that venue's fees, and returns the cheapest way to get there — one venue, several, or through a bridge asset.

Public, no account and no key: every endpoint is open, limited to 5 requests per second per IP, IPv4 clients only.

The cheapest price is not the best price.

GET /route?from=USDT&to=BTC&amountOut=1
venuefillask fee real cost
okx 104,776 +0.20% 104,986
binance 104,780 +0.10% 104,885
kucoin 104,791 +0.08% 104,875
bybit 104,795 +0.10% 104,900
pay 104,879 USDT get 1 BTC 1.4 bps better than any single venue
walk each book to your size add taker fees re-rank split

okx shows the best ask. After its taker fee it is the most expensive of the four. Comparing venues before fees picks the wrong one — this is what the router does instead.

Try it now

A real request to the live router, from this page. No key, nothing to install.


    
  

Already using ccxt? The whole pipeline is two calls.

The router is a plain HTTP endpoint — and it is also a class in ccxt, in every language ccxt ships. Hand it your exchange instances once: fetchRoute then only quotes venues you can actually trade on, and execute sends the orders there. No new dependency, no key, no client to write — the same live books the playground above just used.

import ccxt from 'ccxt';

// Venues go on the router. Routes are filtered to them, and execute sends there.
const venues = { 'mexc': new ccxt.mexc ({ 'apiKey': '...', 'secret': '...' }) };
const router = new ccxt.OrderRouter ({ venues });

const route = await router.fetchRoute ('USDT', 'BTC', { 'amountIn': 20 });

// This places the orders. Pass dryRun: true to rehearse instead.
const report = await router.execute (route);

What these two calls do by default — the venue modes, the checks execute runs before it sends anything, and the guarantees that hold whatever you configure. Prefer HTTP? The API reference covers the same route in one GET.

Pick how it fills

One parameter. Fewer venues means less execution risk; more venues means a better price.

okxkucoinbinancebybit
strategy=best_single

One venue for the whole order. Simplest to execute, one fee, one counterparty — and the baseline everything else is measured against.

okxkucoinbinancebybit
strategy=split_optimal

Minimum cost across the merged, fee-adjusted book with no venue limit. Because levels are fee-adjusted before merging, the greedy walk is provably cost-minimal rather than a guess.

okxkucoinbinancebybit
strategy=split_capped&maxVenues=3

The same, but never more venues than you want to manage. Three captures about 95% of the unconstrained gain.

What it does that a ticker cannot

Four things, each of which changes the price you actually get.

Fees, before the comparison

Every level is adjusted for that venue's taker fee before the books are merged. Fees differ by up to ~4× between venues and routinely invert the ranking — as above.

Book-walked, not top-of-book

Best bid/ask is the price for a trade you are not making. Each book is walked to your real size, so the answer is the price you would actually pay.

Every bridge compared

No direct market? It solves the direct pair and every bridge, then takes the best. Live now, USDC→TRY routes through ETH — ~9 bps better than the obvious USDT path.

Impact you can act on

Every hop reports what your size cost against the best price available anywhere. Positive always means worse, on both sides — so you can shrink, split, or wait.

One request

No side parameter. USDT → BTC is a buy of BTC/USDT; BTC → USDT is a sell of the same market. Working that out is the step people get backwards, so the router does it.

curl -s "https://docs.ccxt.com/router/api/route?from=USDT&to=BTC&amountOut=1"
0.22 ms

route computation, p50

~60

exchanges streamed over WebSocket

0.19–2.2 bps

measured gain from splitting

9 bps

best measured bridge gain

It refuses to quote rather than quote badly. Books older than the freshness window are excluded, not used. An empty route with a stated reason is a deliberate answer — and a far better one than a confident price that no longer exists.

Start in about a minute

Copy the command and send it. Nothing to install, nothing to register — the endpoint is public.

Read the API docs

The router prices and routes orders. It never holds funds and never places trades — you do.