Public API
All endpoints are read-only JSON over HTTPS, versioned under /api/v1. Responses are wrapped as { data, meta }; meta carries generatedAt, methodologyVersion, cache TTL and a disclaimer. Numbers that carry monetary precision are strings. Errors are { error: { code, message } }.
Rate limits
Default 120 requests per minute per IP (configurable). Every response carries x-ratelimit-limit. Exceeding the limit returns HTTP 429 with x-ratelimit-remaining, x-ratelimit-reset and retry-after. Your remaining quota is deliberately absent from successful responses: they are cacheable, and a shared cache would hand one caller's count to everybody. A cached response also never reaches the limiter, so reads served from cache do not count against you. Responses are cacheable for 10–60 seconds (cache-control). CORS is open for GET.
Networks
SwapScope covers two networks that never see each other's orders: GLEEC on netid 6133 and Komodo on 8762. They are separate markets on the same coins, and no response ever mixes them.
There are two different places a netid appears, and they are not interchangeable.
- To choose a network, pass
?netid=6133or?netid=8762. Every price, pair, order-book and best-orders route takes it, and omitting it gives you GLEEC./api/v1/hindsightis the exception and answers for both unless you narrow it. - Coin symbols never carry a netid.
RXDis the same coin on both networks, so/api/v1/prices/RXD@8762is not a thing. Ask for/api/v1/prices/RXD?netid=8762instead. The same goes for a pair: the two coins are path segments and the network is the query, so it is/api/v1/pairs/RXD/LTC?netid=8762, never/api/v1/pairs/RXD/LTC@8762. - Pair ids in responses do carry it, and only on Komodo. A Komodo pair reads
rxd/ltc@8762and the same market on GLEEC readsrxd/ltcwith no suffix at all. So the absence of a suffix means 6133; it does not mean the network is unknown. If you are keying on pair ids, either keep the suffix or readnetwork.netidfrom the response, which is always present and always explicit.
The /api/coingecko/* endpoints are the one exception, and they work the other way round: that specification describes one exchange's markets, so they answer for GLEEC only. A ticker_id is always bare, a netid suffix in one is rejected rather than served, and ?netid= is rejected too rather than quietly ignored. For anything on 8762, use /api/v1.
Endpoints
| Endpoint | Description | Parameters | Example |
|---|---|---|---|
| GET /api/v1/assets | Ranked assets with USD reference price, route, confidence, freshness and volumes. | — | /api/v1/assets |
| GET /api/v1/assets/{symbol} | Asset detail: price, route, pairs, recent swaps, anomaly summary. {symbol} accepts a ticker (RXD) or canonical id (usdc-plg20). | — | /api/v1/assets/RXD |
| GET /api/v1/pairs | All enabled pairs with their latest pair-level reference price. | — | /api/v1/pairs |
| GET /api/v1/pairs/{base}/{quote} | Pair detail including full methodology details (rejections, weights, repricing support, thresholds), liquidity and recent swaps. Reversed directions are resolved to the canonical pair. | — | /api/v1/pairs/RXD/LTC |
| GET /api/v1/pairs/{base}/{quote}/trades | Completed swaps with eligibility and flags. | limit (1–500), start_time, end_time (unix seconds or ISO) | /api/v1/pairs/RXD/LTC/trades?limit=50 |
| GET /api/v1/pairs/{base}/{quote}/orderbook | Latest order-book snapshot and liquidity metrics. | depth (1–500) | /api/v1/pairs/RXD/LTC/orderbook?depth=20 |
| GET /api/v1/pairs/{base}/{quote}/candles | OHLCV candles. | interval (5m,1h,4h,1d,1w), kind (raw|filtered), limit, start_time, end_time | /api/v1/pairs/RXD/LTC/candles?interval=1h&kind=raw |
| GET /api/v1/prices | Every enabled asset's USD price in one request, with status, confidence, 24h change, the external anchor for comparison, and who made the price: the primary pair, its participant count, the largest participant's share and the market-level flags. Intended for bots polling many coins, and for a maker deciding whether a price is anyone's but his own. | symbols (comma-separated ids or tickers, max 200; a ticker matching several chains returns each) | /api/v1/prices?symbols=RXD,LTC,KMD |
| GET /api/v1/prices/{symbol} | Compact price object for an asset. | — | /api/v1/prices/RXD |
| GET /api/v1/prices/{symbol}/history | USD reference price over time, evenly sampled. Points carry the confidence and USD route in force at each moment, and a null price marks a period the methodology could not price rather than omitting it. | start_time, end_time (default 90 days, max 1095), points (10-2000) | /api/v1/prices/RXD/history?points=365 |
| GET /api/v1/prices/{symbol}/methodology | Full audit trail: route, thresholds, per-pair evaluation, external anchor comparison and version history. | — | /api/v1/prices/RXD/methodology |
| GET /api/v1/health | Service health (database, cache, worker freshness). | — | /api/v1/health |
| GET /api/v1/status/sources | Data-source and collector status with recent failures. | — | /api/v1/status/sources |
| GET /api/v1/best-orders/{symbol} | The best order standing on every route into or out of one coin, from the latest stored order book of each of its pairs, ranked by what each implies in dollars through the other coin's own reference price. Every row carries the moment its book was captured; an order may have been cancelled since. | side (buy|sell, default buy), netid | /api/v1/best-orders/BCH?side=buy |
| GET /api/v1/crossed | Order books where a bid stands above an ask, on either network, with what a taker could pull through the overlap. Nothing matches two makers against each other here, so both orders stand until somebody acts. | — | /api/v1/crossed |
| GET /api/v1/network-gaps | The same coin priced on both networks, with how far apart the two prices are and what is left after the taker fee each network charges. Nothing closes these differences: a taker on one network cannot take an order on the other. Read bothCurrent first, because most rows are two prices that stopped moving at different times rather than a live disagreement. | — | /api/v1/network-gaps |
| GET /api/v1/hindsight | Every successful swap revalued at today's prices, from the taker's side: top winners and losers, per-coin and per-pair totals, swap durations by pair, and failures by protocol error type. Cached 15 minutes. | — | /api/v1/hindsight |
| GET /api/v1/network/activity | Network-wide pair activity from the upstream aggregator, covering every pair on the network and flagging which ones SwapScope tracks. Context and discovery only; never an input to a reference price. | untracked (true to list only pairs SwapScope does not track) | /api/v1/network/activity?untracked=true |
| GET /api/coingecko/pairs | CoinGecko-style pair list (ticker_id, base, target, pool_id). | — | /api/coingecko/pairs |
| GET /api/coingecko/tickers | CoinGecko ideal-API tickers. last_price is the SwapScope reference price; last_trade_price, price_status, confidence_score and price_age_sec are added so integrators can filter stale markets. | — | /api/coingecko/tickers |
| GET /api/coingecko/orderbook | CoinGecko orderbook format. | ticker_id (RXD_LTC), depth | /api/coingecko/orderbook?ticker_id=RXD_LTC&depth=50 |
| GET /api/coingecko/historical_trades | CoinGecko historical trades. trade_id is the swap uuid. | ticker_id, type (buy|sell), limit, start_time, end_time | /api/coingecko/historical_trades?ticker_id=RXD_LTC&limit=50 |
Example
curl -s https://your-host/api/v1/prices/RXD | jq
{
"data": {
"id": "rxd",
"symbol": "RXD",
"price": {
"usd": "0.0000396",
"status": "reference",
"freshness": "live",
"confidence": { "score": 79, "level": "high" },
"route": "RXD → LTC → USD",
"externalAnchor": { "usd": "0.00003805", "providers": ["coingecko","coinpaprika"], "divergencePct": "4.1", "note": "comparison only" }
}
},
"meta": { "generatedAt": "...", "methodologyVersion": "1.0.0" }
}Numeric precision
Prices, rates, percentages and volume aggregates are published to 12 significant figures (6 for percentages). These values are computed by division, and the digits beyond that are an artifact of the arithmetic rather than anything the underlying swaps measured. Per-trade amounts and order-book quantities are settled quantities and are published exactly as recorded.
Field definitions
- status
- reference | indicative | stale | unavailable. Only `reference` is a confirmed, fresh price.
- freshness
- live | recent | low_confidence | stale | unavailable, from the age of the newest reliable trade.
- confidence.score / level
- 0–100 and High/Medium/Low/Stale/Unavailable. Components are included on detail endpoints.
- referencePrice
- Quote units per 1 base unit (string, full precision).
- referencePriceUsd / price.usd
- USD value through the published route; null when no route or unavailable.
- indicativePrice / indicativeSource
- Best current estimate when no reference exists (orderbook | trades | previous).
- lastTradePrice
- Newest completed swap price. Never the reference.
- rawVwap24h / filteredVwap24h
- Volume-weighted averages over all / eligible swaps.
- volume24h.rawUsd / reliableUsd / rejectedUsd
- Raw, reliable and excluded USD volume.
- priceAgeSec
- Age of the newest reliable trade in seconds.
- route / routeString
- Selected conversion route, e.g. RXD → LTC → USD, with per-hop rate, quality and age.
- externalAnchor
- External aggregator price for DEX-priced assets, comparison only; `used: false`.
- flags[].code
- Machine-readable anomaly code with severity, penalty and explanation. On the bulk feed, `flags` is the plain list of codes raised on the primary market.
- participants / largestParticipantSharePct
- Bulk feed: distinct parties behind the primary pair's price, and the largest one's share of its influence. A share near 100 means one party made the price.
- maker / taker.participant
- Truncated keyed hash of the DEX pubkey. Not an identity.
- methodologyVersion
- Version of the pricing methodology that produced the value.
- network / meta.network
- Which network the response answers for: `{ id, netid, label }`. See Networks above for how to select one and how pair ids carry it.
CoinGecko compatibility
The /api/coingecko/* endpoints follow the CoinGecko exchange-integration “ideal API” field names (tickers: ticker_id, base_currency, target_currency, pool_id, last_price, base_volume, target_volume, liquidity_in_usd, bid, ask, high, low; orderbook: bids/asks as [price, quantity]; historical_trades: trade_id, price, base_volume, target_volume, trade_timestamp, type). Extra SwapScope fields are additive. Integrators should treat markets with price_status ≠ reference as unpriced.