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 carries X-RateLimit-Limit and X-RateLimit-Remaining; past the limit you get 429.
  • 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: 0 is the first side, 1 the second, in the order of the market’s sideLabels.

Endpoints

Paths are relative to /api/v1.

EndpointParametersReturns
GET /marketstag, limit (≤200), offsetThe board, newest first, a page at a time; nextOffset is null on the last page.
GET /markets/searchq, limit (≤50), offsetMarkets whose question, ticker, tags or handle match q.
GET /markets/{marketId}—One market: prices, consensus, supply, TVL, 24h volume.
GET /markets/{marketId}/chartresolution (1m, 1h, 1d), from, toPrice and TVL history; from and to are in epoch seconds.
GET /markets/{marketId}/holderslimit (≤200), offsetWho holds each side.
GET /markets/{marketId}/stats—Volume and trade counts.
GET /activitymarketId, 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 /leaderboardrangeHours, 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/quoteJSON bodyWhat 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.

StreamWhat arrives
GET /stream/marketsThe 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.