Documentation Index
Fetch the complete documentation index at: https://docs.simplefunctions.dev/llms.txt
Use this file to discover all available pages before exploring further.
Use the Real-Time Data API when you need raw market data for a terminal, dashboard, bot, or trading agent.
This surface is separate from simplefunctions.dev/api/public/*. The public API is for analytical objects and agent workflows. The data API is for fast market data.
Last verified: 2026-04-30.
Base URLs
REST:
https://data.simplefunctions.dev/v1
Current public WebSocket:
wss://app.simplefunctions.dev/ws
Do not use wss://data.simplefunctions.dev/v1/ws yet. It is the intended canonical data-domain WebSocket name, but current routing can return 426 Upgrade Required. Use wss://app.simplefunctions.dev/ws until the WS route is moved off Vercel or a direct WS CNAME is configured.
Data conventions
| Field | Convention |
|---|
| Prices | Probabilities in [0, 1], not cents. |
generated_at | Unix seconds. |
closeTime | Unix seconds. |
ts | Unix milliseconds. |
| Compression | Large REST responses are gzip-compressed by the origin. |
REST endpoints
| Endpoint | Use | Cache |
|---|
GET /v1/heartbeat | Health/status payload. | max-age=10 |
GET /v1/markets?q=&venue= | Top tracked markets or registry search. | max-age=3 |
GET /v1/markets/featured?n=50 | Heat-ranked featured markets. | max-age=3 |
GET /v1/markets/{ticker} | One market snapshot. | max-age=2 |
GET /v1/search?q=&limit=&venue=&strict= | Autocomplete-grade ticker/title search. | max-age=5 |
GET /v1/snapshot | Compact full active-universe price snapshot. | max-age=2 |
GET /v1/movers?window=&n=&minVol=&dir= | Top price movers over a recent window. | max-age=5 |
GET /v1/orderbook/{ticker} | Top-of-book/depth snapshot. | max-age=1 |
GET /v1/candles/{ticker}?tf=1h&limit=500 | OHLCV candles. | max-age=5 or 15 for 1d |
GET /v1/trades/{ticker}?limit=50 | Recent trade prints. | max-age=1 |
Heartbeat
curl "https://data.simplefunctions.dev/v1/heartbeat"
{
"markets_tracked": 9333,
"ws_clients": 3,
"top_volume_market": "KXPRESNOMD-28-GN",
"uptime_s": 12345,
"generated_at": 1777553300
}
Markets
curl "https://data.simplefunctions.dev/v1/markets"
curl "https://data.simplefunctions.dev/v1/markets?q=newsom&venue=kalshi"
curl "https://data.simplefunctions.dev/v1/markets/featured?n=50"
curl "https://data.simplefunctions.dev/v1/markets/KXPRESNOMD-28-GN"
Market object:
{
"ticker": "KXPRESNOMD-28-GN",
"venue": "kalshi",
"title": "Will Gavin Newsom be the Democratic Presidential nominee in 2028?",
"lastPrice": 0.26,
"volume24h": 12345,
"closeTime": 1853884800,
"bestBid": 0.25,
"bestAsk": 0.27,
"heat": 81.4
}
Search
curl "https://data.simplefunctions.dev/v1/search?q=newsom&limit=10"
curl "https://data.simplefunctions.dev/v1/search?q=rate%20cut&venue=kalshi&strict=0"
Parameters:
| Parameter | Values | Use |
|---|
q | string | Required query. |
limit | 1 to 50 | Result cap. Default 10. |
venue | kalshi, polymarket | Optional venue filter. |
strict | 1, 0 | strict=0 enables looser substring matching for short tokens. |
Response:
{
"query": "newsom",
"results": [
{
"ticker": "KXPRESNOMD-28-GN",
"venue": "kalshi",
"title": "Will Gavin Newsom be the Democratic Presidential nominee in 2028?",
"lastPrice": 0.26,
"volume24h": 12345,
"score": 400
}
]
}
Raw snapshot
curl "https://data.simplefunctions.dev/v1/snapshot"
Use this for bot cold-start. It intentionally omits title, close time, and heat to keep the payload small. Markets pinned outside [0.01, 0.99] are excluded.
{
"generated_at": 1777553300,
"count": 9000,
"markets": [
{
"ticker": "KXPRESNOMD-28-GN",
"venue": "kalshi",
"last": 0.26,
"bid": 0.25,
"ask": 0.27,
"vol24h": 12345
}
]
}
Movers
curl "https://data.simplefunctions.dev/v1/movers?window=1h&n=50&minVol=1000&dir=both"
Parameters:
| Parameter | Values | Use |
|---|
window | 1m, 5m, 15m, 1h, 4h, 24h, 1d | Move window. Default 1h. |
n | 10 to 200 | Result cap. Default 50. |
minVol | number | 24h volume floor. Default 1000. |
dir | up, down, both | Direction filter. Default both. |
/v1/movers is powered by in-memory tick/trade samples. After deploy or reconnect, short windows can return count: 0 until samples accumulate.
Orderbook, candles, trades
curl "https://data.simplefunctions.dev/v1/orderbook/KXPRESNOMD-28-GN"
curl "https://data.simplefunctions.dev/v1/candles/KXPRESNOMD-28-GN?tf=1h&limit=500"
curl "https://data.simplefunctions.dev/v1/trades/KXPRESNOMD-28-GN?limit=50"
Orderbook:
{
"ticker": "KXPRESNOMD-28-GN",
"bids": [[0.25, 1200]],
"asks": [[0.27, 700]],
"ts": 1777553300123
}
Candles:
{
"ticker": "KXPRESNOMD-28-GN",
"timeframe": "1h",
"candles": [
{ "t": 1777550400000, "o": 0.25, "h": 0.27, "l": 0.24, "c": 0.26, "v": 900 }
]
}
Trades:
{
"ticker": "KXPRESNOMD-28-GN",
"trades": [
{
"ticker": "KXPRESNOMD-28-GN",
"venue": "kalshi",
"price": 0.26,
"size": 10,
"side": "buy",
"ts": 1777553300123
}
]
}
WebSocket
const ws = new WebSocket('wss://app.simplefunctions.dev/ws')
ws.addEventListener('open', () => {
ws.send(JSON.stringify({
action: 'subscribe',
topics: [
'featured',
'ticker:KXPRESNOMD-28-GN',
'orderbook:KXPRESNOMD-28-GN',
'trade:KXPRESNOMD-28-GN',
'candle:KXPRESNOMD-28-GN:1m'
],
}))
})
ws.addEventListener('message', (event) => {
const frame = JSON.parse(event.data)
console.log(frame.type, frame)
})
Subscribe:
{
"action": "subscribe",
"topics": [
"featured",
"ticker:KXPRESNOMD-28-GN",
"orderbook:KXPRESNOMD-28-GN",
"trade:KXPRESNOMD-28-GN",
"candle:KXPRESNOMD-28-GN:1m"
]
}
Unsubscribe:
{
"action": "unsubscribe",
"topics": ["ticker:KXPRESNOMD-28-GN"]
}
Legacy single-topic subscribe is also accepted:
{ "action": "subscribe", "ticker": "KXPRESNOMD-28-GN" }
WebSocket topics
| Topic | Frame type | Use |
|---|
featured | featured | Top-50 heat-ranked list. |
ticker:{ticker} | ticker_info | Latest price/quote metadata. |
orderbook:{ticker} | orderbook | Sorted book snapshot. |
trade:{ticker} | trade | Trade prints from venue WS. |
candle:{ticker}:{tf} | candle | Candle updates for one timeframe. |
{ticker} | mixed | Legacy topic with ticker/orderbook/trade/candle fan-out. |
When subscribing to a ticker topic, the server may send initial cached ticker_info and orderbook frames if available.
Frame shapes
featured:
{
"type": "featured",
"markets": [],
"generated_at": 1777553300
}
ticker_info:
{
"type": "ticker_info",
"ticker": "KXPRESNOMD-28-GN",
"venue": "kalshi",
"title": "Will Gavin Newsom be the Democratic Presidential nominee in 2028?",
"last": 0.26,
"bid": 0.25,
"ask": 0.27,
"volume24h": 12345,
"closeTime": 1853884800
}
orderbook, trade, and candle use the same shapes as the REST examples above, with a top-level type.
Operational notes
- Public REST callers use
https://data.simplefunctions.dev/v1; the edge proxy injects the internal origin token.
- Direct origin routes at
https://app.simplefunctions.dev/api/data/v1/* are edge-token gated and return 403 without the internal token.
- Anonymous WebSocket connections are capped per IP.
- The server pings WebSocket clients every 30 seconds and closes stale connections after a failed pong.
- Kalshi and Polymarket are normalized into one ticker namespace, but not all fields are available from both venues.