SimpleFunctions

Real-Time Prediction Market Data.

Sub-second WebSocket and REST feed — Kalshi and Polymarket, normalized.

Live orderbook, trade prints, OHLC candles, ticker streams, and a heat-ranked featured list of what is moving right now — across both venues, through a single real-time prediction market data API. Built for agents, quants, dashboards, and research workflows.

Oil painting in 17th-century Dutch Golden Age realist style — Dutch settlers landing at New Amsterdam discover a colossal modern data center on the shore

First arrival — the wonder the Dutch felt landing in 1626, applied to discovering 9000+ live prediction markets.

Who uses the real-time data API?

Trading agents, dashboards, quants, backtest researchers, and risk engines — each subscribing to a different slice of the same normalized live feed.

Trading agent / quant bot

Subscribe to ticker + orderbook for active positions, run signal logic on tick callbacks

wss://data.simplefunctions.dev/v1/ws

Market dashboard / app

Featured top-N + per-market WebSocket for chart + book panel

GET /v1/markets/featured + WS

Backtest researcher

Pull historical candles by timeframe; reconstruct tick replay from trade prints

GET /v1/candles + GET /v1/trades

Risk engine

Poll heartbeat + featured every minute; alert on heat regime shift

GET /v1/heartbeat + GET /v1/markets/featured

AI world-model loop

Featured stream as compact context for an LLM agent — what is hot right now

WS subscribe featured

REST endpoints

Edge-cached, normalized, with precomputed heat. All paths under thehttps://data.simplefunctions.dev/v1/base.

Endpoint
Description
Cache
GET /v1/markets

All tracked markets with precomputed heat score

max-age=3, swr=10
GET /v1/markets/featured?n=20

Top-N by heat — what is moving right now

max-age=3, swr=10
GET /v1/markets/{ticker}

Single market snapshot with full metadata

max-age=2, swr=5
GET /v1/orderbook/{ticker}

Live depth — bids, asks, timestamp

max-age=1
GET /v1/candles/{ticker}?tf=1h&limit=500

OHLC candles for any timeframe

max-age=15 (1d) / 5 (others)
GET /v1/trades/{ticker}?limit=50

Recent trade prints, newest first

max-age=1
GET /v1/heartbeat

System status — markets tracked, ws clients, uptime

max-age=10

WebSocket topics

One connection,wss://data.simplefunctions.dev/v1/ws, fans out to any combination of topics. Frames are JSON.

Topic
Frame shape
Cadence
ticker:{ticker}
{type, ticker, last, bid, ask, volume24h, venue}

On change

orderbook:{ticker}
{type, ticker, bids, asks, ts}

Throttled 1 Hz

trade:{ticker}
{type, ticker, price, size, side, ts}

On every print

candle:{ticker}:{tf}
{type, ticker, timeframe, candle}

On bar update

featured
{type, markets, generated_at}

60 s tick + rank-change

Heat scoring

A single 0–100 number per market that combines liquidity, contestation, and recent volatility. Featured rankings are heat-sorted; you can also re-sort client-side from the per-market heat field.

Component
Weight
Calculation

Volume

0.40

ln(volume + 1) / ln(1e7 + 1) — log-scaled 24 h volume

Spread

0.35

1 − (spread / 0.05) — tighter spread = hotter

Close to 0.5

0.15

Markets near coin-flip get a boost

Uncertainty

0.10

Recent probability volatility

Featured response — example

Top-N markets by heat across both venues. Re-broadcast on thefeatured WebSocket topic when rank composition changes.

GET https://data.simplefunctions.dev/v1/markets/featured?n=20JSON · 200
{
  "generated_at": "2026-04-30T07:50:42Z",
  "markets": [
    {
      "ticker":      "KXFEDDECISION-26DEC-CUT100",
      "venue":       "Kalshi",
      "title":       "Fed rate cut > 100 bps by Dec 2026",
      "yes_price":   0.32,
      "bid":         0.31,
      "ask":         0.33,
      "volume_24h":  3284100,
      "open_interest": 1520400,
      "heat":        87.4,
      "ts":          "2026-04-30T07:50:41Z"
    },
    { "...": "19 more, sorted by heat desc" }
  ]
}

WebSocket quickstart

Subscribe to one or more topics in a single envelope. The server pushes JSON frames keyed by type.

JavaScript / TypeScriptbrowser + node
const ws = new WebSocket('wss://data.simplefunctions.dev/v1/ws')

ws.addEventListener('open', () => {
  ws.send(JSON.stringify({
    action: 'subscribe',
    topics: [
      'featured',
      'ticker:KXFEDDECISION-26DEC-CUT100',
      'orderbook:KXFEDDECISION-26DEC-CUT100',
    ],
  }))
})

ws.addEventListener('message', (e) => {
  const frame = JSON.parse(e.data)
  if (frame.type === 'featured') {
    console.log('top-N rank update', frame.markets.length)
  }
  if (frame.type === 'ticker') {
    console.log(frame.ticker, frame.last)
  }
})

FAQ

What is the SimpleFunctions real-time prediction market data API?

A sub-second WebSocket and REST data feed for Kalshi and Polymarket prediction markets. You get normalized orderbook, trade prints, OHLC candles, ticker streams, and a heat-ranked featured list of what is moving right now — across both venues, through a single endpoint.

How does the WebSocket work?

Connect to wss://data.simplefunctions.dev/v1/ws and subscribe to topics like ticker:{ticker}, orderbook:{ticker}, trade:{ticker}, candle:{ticker}:{tf}, or featured. The server pushes JSON frames as data arrives. Orderbook frames are throttled to 1 Hz; trade frames are pushed on every print.

What is the heat score?

A single-number 0-100 ranking that combines log-scaled 24 h volume (40%), bid-ask spread tightness (35%), proximity to 0.5 probability (15%), and recent probability volatility (10%). Use it to find what is liquid, contested, and moving — not just what is popular.

How does this differ from the Kalshi or Polymarket APIs directly?

You get one endpoint that normalizes both venues, precomputed heat ranking, and a featured stream that updates on rank-change rather than every tick. Calling Kalshi and Polymarket directly works, but you write the normalization, heat scoring, and featured-rank logic yourself.

Can I subscribe to multiple tickers in one WebSocket connection?

Yes. The subscribe envelope accepts a topics: string[] field. One connection can fan out to dozens of markets simultaneously.

How fresh is the data?

REST endpoints have max-age caches between 1 and 15 seconds depending on the resource — orderbook and trades cap at 1 second. WebSocket frames are pushed on the venue tick rate (typically sub-second) with orderbook throttled to 1 Hz to keep frames lean.

What about historical data?

GET /v1/candles/{ticker}?tf=1h&limit=500 returns up to 500 OHLC candles per request across timeframes from 1 m to 1 d. GET /v1/trades/{ticker}?limit=50 returns the most recent prints. For deeper backtest pulls, contact us — we can stream older candles.

Is the data API paid?

A free tier is available with reasonable per-minute rate limits for testing and small agents. Higher-throughput tiers are coming — talk to us if you need more capacity right now.

How do I authenticate?

Free tier requires no API key for low-volume requests. Higher tiers issue an X-SF-API-Key header you attach to REST and pass as ?key= on WebSocket upgrade. The Vercel edge handles per-user rate limits and per-key quotas before requests reach the origin.

Does the data API include LLM-summarized state?

No — this API is the raw, machine-readable layer. For a 15-min summarized world snapshot for LLM agents, see /world. For event probabilities and meaning attached, see /event-probability-api. The realtime data API is the underlying tick layer that powers them.

What runtime powers this?

A Go origin on Fly.io ingests Kalshi and Polymarket continuously, computes heat in-process, and serves REST + WebSocket. The Vercel edge proxies via data.simplefunctions.dev, injecting an edge token, handling rate limits, and CORS.

Can I use this in a browser app?

Yes. CORS is enabled on data.simplefunctions.dev. Use fetch() for REST and the standard WebSocket API for streams. No special SDK required — but a thin TypeScript SDK is on the roadmap.

Related surfaces