Market Data
Public endpoints for market data. No authentication required for most endpoints.
Best Bid/Offer (BBO)
GET /v1/market-data/:market_id/bbo?outcome_index=0
Returns the best bid and ask for a market.
Response
{
"market_id": "...",
"outcome_index": 0,
"best_bid": "0.48",
"best_ask": "0.52",
"spread": "0.04",
"midpoint": "0.50",
"timestamp": 1709136000
}
spread is best_ask - best_bid; midpoint is (best_bid + best_ask) / 2; timestamp is the Unix-second snapshot. For depth sizes, query the order book at GET /v1/orders/book/:market_id.
Batch BBO
POST /v1/market-data/bbo
Get BBO for multiple markets in a single request (up to 50). The body is a JSON array of { market_id, outcome_index } objects — one entry per (market, outcome) tuple.
Request Body
[
{ "market_id": "market-id-1", "outcome_index": 0 },
{ "market_id": "market-id-2", "outcome_index": 0 }
]
| Field | Type | Required | Description |
|---|---|---|---|
market_id | string | Yes | Market UUID |
outcome_index | int | Yes | Outcome index (0 = Yes, 1 = No) |
Response
{
"markets": [
{
"market_id": "market-id-1",
"outcome_index": 0,
"best_bid": "0.48",
"best_ask": "0.52",
"spread": "0.04",
"midpoint": "0.50",
"timestamp": 1709136000
}
]
}
Spread
GET /v1/market-data/:market_id/spread?outcome_index=0
Returns the bid-ask spread for a market.
Response
{
"market_id": "...",
"outcome_index": 0,
"spread": "0.04",
"spread_bps": 400,
"best_bid": "0.48",
"best_ask": "0.52"
}
Midpoint
GET /v1/market-data/:market_id/midpoint?outcome_index=0
Returns the midpoint price between best bid and ask.
Response
{
"market_id": "...",
"outcome_index": 0,
"midpoint": "0.50"
}
Tick Size
GET /v1/market-data/:market_id/tick-size
Returns the minimum price increment for a market.
Response
{
"market_id": "...",
"tick_size": "0.01"
}
Fee Rate
GET /v1/market-data/:market_id/fee-rate
Scope: read:account (Authenticated)
Returns the maker and taker fee rates for the authenticated user in a specific market.
Response
{
"market_id": "...",
"maker_fee_bps": 0,
"taker_fee_bps": 50,
"maker_fee_pct": "0.00",
"taker_fee_pct": "0.50"
}
The *_bps fields are the on-chain integer values; the *_pct fields are pre-rendered percentage strings (basis points ÷ 100) for UI display.
Recent Fills (cross-market tape)
GET /v1/markets/fills/recent
Public — No authentication required.
Returns the most recent matched fills across every market, pseudonymized for public consumption. Powers the Sharp-money live tape on the Home page.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | int | Number of fills (default 50, max 200). |
since | string | RFC 3339 timestamp — return fills newer than this. |
min_size_usd | number | Inclusive lower bound on fill notional in USD. Default unset (no floor). Cap 1,000,000. |
Default-shape requests (limit=50, no since, no min_size_usd) share a 10s Redis cache. Any filter param bypasses the cache.
Response
Example values are illustrative; a cold-start exchange returns an empty
fillsarray.
{
"fills": [
{
"market_id": "…",
"market_title": "Will the Fed cut rates in June 2026?",
"outcome": "Yes",
"side": "BUY",
"size_usd": "1245.32",
"price_cents": "73",
"user_handle": "anon-1A2F",
"category": "Politics",
"filled_at": "2026-05-22T09:58:11Z"
}
],
"next_cursor": null
}
user_handle is either the trader's opted-in public username or a stable anon-XXXX pseudonym (same user → same anon across the tape and the Top Traders leaderboard). size_usd and price_cents are strings (not floats) to preserve precision; parse price_cents as an integer for American-odds rendering.
Changelog
- 2026-05-23: Removed
trade_idfrom the/v1/markets/fills/recentresponse payload (audit P2-6, PR #5820). External consumers using this field for client-side keying should switch to the(market_id, filled_at)tuple, which is unique per fill on the public tape.
Platform Pulse (24h aggregates)
GET /v1/markets/stats/pulse
Public — No authentication required.
Three rolling-24h platform aggregates plus a 24-bucket hourly tape. Powers the Home PulseHero band. 30s Redis-cached.
Response
Example values are illustrative; a cold-start exchange returns
0for every aggregate and a flat (all-zero)tape_24h.
{
"volume_24h_delta_pct": 0.182,
"active_traders_24h": 4129,
"settled_today_usd": "284512.00",
"volume_24h_delta": 0.182,
"traders_online_24h": 4129,
"settled_today_usdc": 284512.00,
"total_volume_24h": 1438201.55,
"active_markets": 312,
"active_markets_delta": 0.041,
"traders_online_delta": -0.018,
"tape_24h": [
{ "hour": "2026-05-21T10:00:00Z", "volume_usdc": 48211.10 }
]
}
All *_delta* fields are signed fractions (+0.182 = +18.2% vs the prior 24h block). Cold-start (prior window zero) returns 0, never Inf. tape_24h always carries exactly 24 hourly buckets, oldest first.
Category Spotlight
GET /v1/markets/stats/category-spotlight?window=7d
Public — No authentication required.
Top categories by trade volume over the requested window with a signed delta vs the prior window of equal length. Powers the Home BentoWall category-spotlight tile. 5min Redis-cached.
Example values are illustrative; a cold-start exchange returns an empty
categoriesarray.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
window | string | 7d (v1 supports only 7d). Default 7d. |
Response
{
"window": "7d",
"categories": [
{
"category": "AI",
"volume_usdc": 412305.18,
"volume_delta_pct": 0.143,
"market_count": 47
}
]
}
Results are sorted by volume_usdc desc and capped at 10. volume_delta_pct follows the same cold-start defense (0, never Inf) as /stats/pulse.
Top Traders Leaderboard
GET /v1/leaderboards/traders?window=7d&limit=10
Public — No authentication required.
Top traders by realized P&L over the requested window, pseudonymized for public consumption. Powers the Home Leaderboards region.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
window | string | 24h | 7d | 30d | all — default 7d. all is bounded server-side at 365d. |
limit | int | Default 10, max 100. |
Default-shape requests (limit=10) share a 30s Redis cache per window.
Response
Example values are illustrative; a cold-start exchange returns an empty
tradersarray.
{
"window": "7d",
"traders": [
{
"handle": "anon-9F2C",
"user_id": null,
"avatar_url": null,
"pnl_usdc": 1845.21,
"roi": 0.18,
"trade_count": 42
}
]
}
handle is the opted-in public username or a stable anon-XXXX pseudonym (consistent with the recent-fills tape). user_id is non-null only when the trader has opted into a public profile — returning it alongside an anon handle would defeat the pseudonym. roi is a fraction (0.18 = +18%).
Server Time
GET /v1/time
Public — No authentication required.
Returns the server's current Unix timestamp. Use this to synchronize your clock for HMAC signatures.
{
"time": 1709136000
}