Track DEX to CEX spreads, CEX volume, liquidity quality, route history, symbol data, and webhook-ready payloads across major crypto venues. This page is built as a standalone exchange-style documentation surface, not just a scanner tab.
Normalized DEX to CEX route rows with DEX price, CEX price, spread, liquidity, flow, and CEX volume.
Health, diagnostics, metrics, and chain-aware venue status for execution monitoring and automation safety.
Use the same data model to build your own scanner, bot, dashboard, alert router, or execution preview in minutes.
To start using the API, first request an API key from the author. After you receive the key, add it directly to the endpoint URL as a query parameter and then use the route, symbol, or scanner endpoints exactly as shown below.
After the author sends you an API key, append it directly to the endpoint URL as the apiKey query parameter.
Put the key right after the endpoint, then continue with any other query params like minSpread, limit, hours, or interval.
This means your integration flow is simple: get key, add key to URL, call endpoint, render live routes in your own scanner or dashboard.
https://api.example.com/api/dex/routes?apiKey=YOUR_API_KEY&minSpread=0.5&limit=100curl "https://api.example.com/api/dex/routes?apiKey=YOUR_API_KEY&minSpread=0.5&limit=100"Currently, the API is public with no authentication required. Rate limiting applies to all endpoints.
| Type | Limit | Window |
|---|---|---|
| IP-based | 100 requests | 60 seconds |
| Burst | 10 requests | 1 second |
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please try again in 30 seconds.",
"retryAfter": 30
}| 200 | OK - Successful request |
| 400 | Bad Request - Invalid parameters |
| 404 | Not Found - Symbol or route not found |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
| 503 | Service Unavailable - Route snapshot initializing |
| GET / | Service status |
| GET /health | Health check with venue status |
| GET /api/status | Scanner status |
| GET /metrics | Prometheus metrics |
| GET /api/exchanges | List all CEX / DEX venues |
| GET /api/exchanges/diagnostics | Venue diagnostics |
| GET /api/dex/status | DEX scanner status with chain coverage |
| GET /api/dex/routes | All DEX to CEX routes |
| GET /api/dex/routes/cex-above | CEX > DEX only |
| GET /api/dex/routes/dex-above | DEX > CEX only |
| POST /api/dex/scan | Full scan request |
| GET /api/dex/symbols | List all DEX route symbols |
| GET /api/dex/symbol/:symbol | Symbol details across DEX / CEX venues |
| GET /api/dex/routes/:symbol | All routes for symbol |
| GET /api/dex/symbol/:symbol/history | Route history |
Service status and basic information.
{
"status": "online",
"service": "dex-scanner-api",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"uptime": "3d 4h 12m",
"environment": "production"
}Health check with detailed exchange and snapshot status.
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00.000Z",
"checks": {
"database": "connected",
"venues": {
"total": 34,
"online": 31,
"offline": 3,
"degraded": 0
},
"snapshot": {
"lastUpdated": "2024-01-15T10:29:58.000Z",
"ageMs": 2000,
"rows": 612
}
},
"latency": {
"avg": 45,
"max": 120,
"unit": "ms"
}
}{
"scanner": "running",
"alerts": "ready",
"version": "1.0.0",
"chains": "8 connected",
"snapshotAge": "2 seconds",
"activeRoutes": 612
}# HELP dex_routes_total Total route updates by venue
# TYPE dex_routes_total counter
dex_routes_total{venue="uniswap_v3"} 12482
dex_routes_total{venue="binance"} 88210
...{
"venues": [
"uniswap_v3",
"curve",
"jupiter",
"binance",
"bybit",
"okx",
...
],
"count": 34,
"categories": {
"cex": 26,
"dex": 8
}
}{
"timestamp": "2024-01-15T10:30:00.000Z",
"venues": [
{
"venue": "binance",
"status": "online",
"lastSuccess": "2024-01-15T10:29:58.000Z",
"lastError": null,
"errorCount": 0,
"avgResponseTime": 234,
"quoteCount": 1847
},
{
"venue": "jupiter",
"status": "online",
"lastSuccess": "2024-01-15T10:29:57.000Z",
"lastError": "2024-01-15T10:15:22.000Z",
"errorCount": 2,
"avgResponseTime": 189,
"quoteCount": 654
}
]
}{
"timestamp": "2024-01-15T10:30:00.000Z",
"totalVenues": 34,
"onlineVenues": 31,
"chains": ["ethereum", "arbitrum", "solana", "base"],
"venues": [
{
"venue": "jupiter",
"status": "online",
"lastUpdate": 1705312798000,
"quoteCount": 234,
"isDex": true,
"chainId": "solana"
},
{
"venue": "binance",
"status": "online",
"lastUpdate": 1705312798000,
"quoteCount": 1847,
"isDex": false
}
]
}Get all DEX to CEX opportunities above the minimum spread threshold.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| minSpread | float | 0 | 0+ | Minimum spread percentage |
| limit | integer | 1000 | 1-5000 | Maximum results |
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"count": 247,
"rows": [
{
"symbol": "ETHUSDC",
"base": "ETH",
"quote": "USDC",
"dexPrice": 3182.42,
"cexPrice": 3240.98,
"spreadPercent": 1.84,
"dexEx": "uniswap_v3",
"cexEx": "binance",
"cexVolumeUsd": 1860000,
"timestamp": 1705312798000,
"priceChange24h": 2.9,
"dexUrl": "https://app.uniswap.org/",
"dexChainId": "ethereum",
"dexLiquidity": 2400000,
"dexMarketCap": 780000000,
"dexBuys": 128,
"dexSells": 116
}
]
}Get only routes where CEX is trading above DEX.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| limit | integer | 1000 | 1-5000 | Maximum results |
| minVolume | float | 0 | 0+ | Minimum CEX quote volume |
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"count": 89,
"rows": [
{
"symbol": "SOLUSDC",
"base": "SOL",
"quote": "USDC",
"dexPrice": 186.11,
"cexPrice": 187.86,
"spreadPercent": 0.94,
"dexEx": "jupiter",
"cexEx": "bybit",
"cexVolumeUsd": 2740000,
"timestamp": 1705312798000
}
]
}Get only routes where DEX is trading above CEX.
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"count": 41,
"rows": [
{
"symbol": "ARBUSDC",
"base": "ARB",
"quote": "USDC",
"dexPrice": 1.168,
"cexPrice": 1.142,
"spreadPercent": -2.28,
"dexEx": "camelot",
"cexEx": "bybit",
"dexLiquidity": 1900000,
"timestamp": 1705312798000
}
]
}Programmatic route scan request. Same response shape as /api/dex/routes.
{
"minSpread": 0.5,
"chains": ["ethereum", "arbitrum", "solana"],
"cexExchanges": ["binance", "bybit", "okx"],
"symbols": ["ETHUSDC", "SOLUSDC"],
"includeDex": true
}Get a paginated list of all route symbols available in the scanner.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| limit | integer | 50 | 1-100 | Results per page |
| offset | integer | 0 | 0+ | Pagination offset |
| sort | string | bestSpread | bestSpread/worstSpread/volume | Sort field |
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"total": 247,
"limit": 50,
"offset": 0,
"count": 50,
"symbols": [
{
"symbol": "ETHUSDC",
"base": "ETH",
"quote": "USDC",
"routeCount": 14,
"bestSpread": 1.84,
"worstSpread": -0.42
},
{
"symbol": "SOLUSDC",
"base": "SOL",
"quote": "USDC",
"routeCount": 11,
"bestSpread": 0.94,
"worstSpread": -0.31
}
],
"pagination": {
"nextOffset": 50,
"hasMore": true,
"totalPages": 5
}
}Get route data for a specific symbol across all supported venues.
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"symbol": "ETHUSDC",
"base": "ETH",
"quote": "USDC",
"venueCount": 12,
"bestRoute": {
"dexEx": "uniswap_v3",
"cexEx": "binance",
"spreadPercent": 1.84,
"dexPrice": 3182.42,
"cexPrice": 3240.98
},
"worstRoute": {
"dexEx": "curve",
"cexEx": "okx",
"spreadPercent": -0.22,
"dexPrice": 3196.25,
"cexPrice": 3189.20
},
"routes": [
{
"dexEx": "uniswap_v3",
"cexEx": "binance",
"spreadPercent": 1.84,
"dexPrice": 3182.42,
"cexPrice": 3240.98
}
]
}{
"error": "symbol_not_found",
"message": "No route data for INVALID",
"suggestions": ["ETH", "SOL", "ARB", "LINK"]
}Get all route combinations for a specific symbol with detailed statistics.
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"symbol": "ETHUSDC",
"count": 14,
"stats": {
"best": 1.84,
"worst": -0.42,
"average": 0.61,
"median": 0.55,
"stdDev": 0.47
},
"routes": [
{
"symbol": "ETHUSDC",
"base": "ETH",
"quote": "USDC",
"dexPrice": 3182.42,
"cexPrice": 3240.98,
"spreadPercent": 1.84,
"dexEx": "uniswap_v3",
"cexEx": "binance",
"cexVolumeUsd": 1860000,
"timestamp": 1705312798000,
"dexData": {
"chainId": "ethereum",
"liquidity": 2400000,
"marketCap": 780000000,
"buys24h": 128,
"sells24h": 116,
"url": "https://app.uniswap.org/"
}
}
]
}Get historical route data for charting. For now, returns current snapshot only until the database-backed history layer is enabled.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| hours | integer | 24 | 1-168 | Hours of history |
| interval | string | 1h | 1m/5m/15m/1h/4h/1d | Aggregation interval |
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"symbol": "ETHUSDC",
"message": "History endpoint requires database implementation",
"currentData": {
"hours": 24,
"note": "Returns current snapshot only. DB integration needed for historical route history.",
"plannedFeatures": [
"TimescaleDB integration",
"OHLC route data",
"Volume profile"
]
},
"snapshot": [
{
"timestamp": 1705312798000,
"spreadPercent": 1.84,
"dexPrice": 3182.42,
"cexPrice": 3240.98,
"dexEx": "uniswap_v3",
"cexEx": "binance"
}
]
}Telegram bot webhook endpoint.
This endpoint is for Telegram integration only.
curl -X POST "https://api.example.com/botYOUR_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"update_id": 123456789,
"message": {
"message_id": 1,
"from": {"id": 123456789, "is_bot": false, "first_name": "User"},
"chat": {"id": 123456789, "type": "private"},
"date": 1705312800,
"text": "/start"
}
}'{
"ok": true
}{
symbol: string; // "ETHUSDC"
base: string; // "ETH"
quote: string; // "USDC"
dexPrice: number; // 3182.42
cexPrice: number; // 3240.98
spreadPercent: number; // 1.84
dexEx: ExchangeId; // "uniswap_v3"
cexEx: ExchangeId; // "binance"
cexVolumeUsd?: number; // 1860000
timestamp: number; // Unix ms
dexChainId?: string; // "ethereum"
dexUrl?: string; // Router / pool URL
dexBuys?: number; // 24h buy count
dexSells?: number; // 24h sell count
dexLiquidity?: number; // USD
dexMarketCap?: number; // USD
priceChange24h?: number; // Percentage
}type ExchangeId =
| "binance" | "bybit" | "okx" | "gateio"
| "kucoin" | "mexc" | "whitebit" | "htx"
| "uniswap_v3" | "curve" | "jupiter" | "orca"
| "camelot" | "velodrome" | "balancer" | "pancakeswap";try {
const response = await fetch('/api/dex/routes');
if (response.status === 429) {
const data = await response.json();
await sleep(data.retryAfter * 1000);
return retry();
}
if (response.status === 503) {
await sleep(2000);
return retry();
}
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('API request failed:', error);
}async function apiRequest(url, attempt = 1) {
try {
return await fetch(url);
} catch (error) {
if (error.status === 429 && attempt < 5) {
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
await sleep(delay);
return apiRequest(url, attempt + 1);
}
throw error;
}
}class DexScannerAPI {
private baseURL: string;
constructor(baseURL = 'https://api.example.com') {
this.baseURL = baseURL;
}
async getRoutes(minSpread?: number): Promise<RoutesResponse> {
const params = new URLSearchParams();
if (minSpread) params.set('minSpread', minSpread.toString());
const response = await fetch(this.baseURL + '/api/dex/routes?' + params.toString());
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
async getSymbol(symbol: string): Promise<SymbolResponse> {
const response = await fetch(this.baseURL + '/api/dex/symbol/' + symbol);
if (response.status === 404) throw new Error('Symbol ' + symbol + ' not found');
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
}
const api = new DexScannerAPI();
const routes = await api.getRoutes(0.5);
const symbolData = await api.getSymbol('ETH');import requests
from typing import Optional, Dict, Any
class DexScannerAPI:
def __init__(self, base_url: str = "https://api.example.com"):
self.base_url = base_url
self.session = requests.Session()
def get_routes(self, min_spread: Optional[float] = None) -> Dict[str, Any]:
params = {}
if min_spread:
params['minSpread'] = min_spread
response = self.session.get(
f"{self.base_url}/api/dex/routes",
params=params
)
response.raise_for_status()
return response.json()
def get_symbol(self, symbol: str) -> Dict[str, Any]:
response = self.session.get(
f"{self.base_url}/api/dex/symbol/{symbol}"
)
if response.status_code == 404:
raise ValueError(f"Symbol {symbol} not found")
response.raise_for_status()
return response.json()
api = DexScannerAPI()
routes = api.get_routes(min_spread=0.5)
symbol_data = api.get_symbol("ETH")# Get all DEX routes
curl -s "https://api.example.com/api/dex/routes" | jq '.rows[0:5]'
# Get symbol data
curl -s "https://api.example.com/api/dex/symbol/ETH" | jq '.bestRoute'
# Get paginated symbols
curl -s "https://api.example.com/api/dex/symbols?limit=10&offset=0" | jq '.symbols'
# Get CEX-above opportunities
curl -s "https://api.example.com/api/dex/routes/cex-above?minVolume=500000" | jq '.count'Connect the route snapshot endpoint, filter by chain or spread, and show a live watchlist inside your own dashboard, bot, or execution panel.
Most integrations show symbol, chain, DEX price, CEX price, spread, liquidity, and CEX volume so traders can instantly see whether an edge is actually executable.
A strong docs page gives users a clear product surface: real endpoints, route data structure, and exact payloads they can plug into their own scanner in seconds.
Use the route feed to display every live spread your own scanner should show: symbol, chain, DEX, CEX, DEX price, CEX price, CEX volume, liquidity, flow, and timestamp.
In most integrations, a user can connect this feed in under two minutes, map the route row into a table, and instantly see all available spreads from the endpoint without rebuilding the underlying data collection stack.
If you want extra data, higher limits, or a custom payload for your own product, message the developer and request access details.
This API is designed for teams that want to show DEX to CEX spreads inside a private terminal, arbitrage dashboard, Telegram workflow, or execution monitor without rebuilding the route collection layer from scratch.
You can surface DEX venue, CEX venue, live spread, CEX volume, liquidity depth, market cap, route age, and symbol coverage in one consistent payload. That means a trader can open your interface and instantly see which opportunities are real, liquid, and worth monitoring.
For SEO and product clarity, a strong API page like this also helps users understand that the scanner is not just a UI. It is a data product they can connect directly into their own stack.
A simple integration usually starts with /api/dex/routes. Pull the rows, render symbol and venue columns, then highlight spread, liquidity, and CEX volume so the user sees execution quality immediately.
After that, add /api/dex/symbol/:symbol for a detail panel and /api/dex/routes/:symbol for route comparisons. With those two pieces, you already have enough to build a lean scanner, internal watchlist, or client-facing arbitrage feed.
If you need custom limits, dedicated coverage, or help wiring alerts and webhooks, use the access block above and message the developer directly.