API
Overview
Everything the terminal shows is served by one HTTP API, and its public half needs no key: markets, prices, history, trades, the leaderboard and live updates. Responses are JSON. The complete, machine-readable description is the OpenAPI document at /openapi.json.
https://r8rate.dev/api/v1- Reads are open. No sign-up and no key. While R8 is invite-only, a caller without access gets
403 GATE_REQUIRED. - Rate limits are per IP address, per minute: 600 reads and 60 writes. A quote is a
POST, so it counts as a write. Every response carriesX-RateLimit-LimitandX-RateLimit-Remaining; past the limit you get429. - Numbers are exact. Amounts are integer strings in the asset’s smallest unit (USDC has 6 decimals, SOL 9). Prices, consensus, TVL and volume are fractions,
{"num": "…", "den": "…"}, so nothing is lost to floating point. - Sides are numbered:
0is the first side,1the second, in the order of the market’ssideLabels.
Endpoints
Paths are relative to /api/v1.
| Endpoint | Parameters | Returns |
|---|---|---|
GET /markets | tag, limit (≤200), offset | The board, newest first, a page at a time; nextOffset is null on the last page. |
GET /markets/search | q, limit (≤50), offset | Markets whose question, ticker, tags or handle match q. |
GET /markets/{marketId} | — | One market: prices, consensus, supply, TVL, 24h volume. |
GET /markets/{marketId}/chart | resolution (1m, 1h, 1d), from, to | Price and TVL history; from and to are in epoch seconds. |
GET /markets/{marketId}/holders | limit (≤200), offset | Who holds each side. |
GET /markets/{marketId}/stats | — | Volume and trade counts. |
GET /activity | marketId, principalId, limit (≤200), before… | Recent trades, newest first, for one market or one trader. Without either, limit is required, is at most 50, and the read does not page. |
GET /leaderboard | rangeHours, limit (≤200) | Traders ranked by profit, open positions included, cash in dollars at the trade’s time. |
GET /tags | — | The tags markets are filed under. |
POST /chain/quote | JSON body | What a buy, sell or swap would give right now. Moves nothing. |
Examples
The newest markets
curl "https://r8rate.dev/api/v1/markets?limit=20"Returns {"items": [...], "nextOffset": 20}. Each item has the market’s id, question, sideLabels, prices, consensusYes, tvl and volume24h.
Search
curl "https://r8rate.dev/api/v1/markets/search?q=solana&limit=10"One market’s trades, page by page
curl "https://r8rate.dev/api/v1/activity?marketId=<market id>&limit=50"The answer ends with nextBefore, or null on the last page. To read the next page, send its four fields back as beforeTime, beforeMarketId, beforeSeq and beforeEventId.
A quote
What 10 USDC buys on the first side. amount is in atoms, so 10 USDC is 10000000.
curl -X POST "https://r8rate.dev/api/v1/chain/quote" \
-H "content-type: application/json" \
-d '{"marketId": "<market id>", "side": 0,
"operation": "buy", "amount": "10000000"}'The answer names the fee, the tokens you would receive and the consensus after the trade. A quote is a snapshot: the next trade on the market changes it.
Live updates
Two Server-Sent Events streams push changes as they happen, so there is no need to poll.
| Stream | What arrives |
|---|---|
GET /stream/markets | The whole board as snapshot events, then changes about every 10 seconds. |
GET /stream/markets/{marketId} | One market, about every second. |
curl -N "https://r8rate.dev/api/v1/stream/markets"A heartbeat event arrives every 15 seconds. To resume after a dropped connection, send the last event id back as the Last-Event-ID header. Each client may hold up to 10 streams at once.
Trading through the API
Coming soon. Today every trade is signed by the trader’s own wallet in the terminal; programmatic trading with API keys is on the way.