Skip to content

GuidesMarket data

GET /api/{exchange}/fetchOHLCV serves historical price candles for one venue outcome. Stored-history coverage is proven for 16 venues: polymarket, kalshi, hyperliquid, opinion, limitless, predictfun, myriad, rain, gemini, predictstreet, pascal, xo, pred, novig, sxbet, and polymarket_us. The two dark venues (predictit, smarkets) report capabilities.history: false; that flag means coverage is unproven, not that fetchOHLCV must be empty. Proven coverage does not mean true venue candles either: xo, pred, sxbet, polymarket_us, and novig serve candles rolled up from Predictefy-owned points (source: derived, sourceType: rollup, isTrueCandle: false) — write-forward catalog points for xo, pred, sxbet, and polymarket_us, the order-book tape for novig. These are derived, not true venue candles, so check source, sourceType, and isTrueCandle. Capture and backfill are availability-dependent. Predictefy makes no uninterrupted-capture, per-venue freshness, or growing daily guarantee. Request the exact range you need. SX Bet serves captured, trade-derived candles only; it has no official-history source or catalog-price write-forward coverage.

Terminal window
curl -s "$PREDICTEFY_API_URL/api/polymarket/fetchOHLCV?outcomeId=OUTCOME_ID&resolution=1h&limit=500" \
-H "Authorization: Bearer pk_live_YOUR_KEY"
ParameterRequiredNotes
outcomeIdyes*The catalog outcomeId returned by market reads, or the venue-native id (id is accepted as an alias).
resolutionyes1s/5s/10s/30s: trade-derived for the six venues below. 1m/1h/1d: stored. 5m/15m/30m/4h/6h: aggregated (source: derived, sourceType: rollup).
start/endnoISO timestamp or epoch milliseconds.
limitnoUp to 5,000 candles per call — page longer ranges with start/end.
VenueSub-minute outcomeId formatExample
polymarketCLOB asset id11198861…
kalshiticker (YES view) / ticker-NO (NO view)KXBTC15M-…-00
hyperliquidfull HIP-4 asset id (venue coin uses #N)100001730 (#1730)
sxbetmarketHash#outcomeIndex0x3f…9a#0
myriadnetworkId:marketId:outcomeIdx42220:1320:0
pascal{symbol}#0 (the primary traded outcome)PMKT_CEO.26AUG31#0

REST-derived candles use these verbatim catalog formats (the venue-native id is also accepted):

VenueCatalog outcomeId formatExample
predictfunpredictfun:{marketId}:{indexSet}predictfun:32153:1
limitless{marketSlug}:{yes|no}draw-1784184108504:yes
geminiGEMI:{marketId}:{nativeOutcomeId}:{yes|no}GEMI:NGAS2607312100:GEMI-NGAS2607312100-HI3D2:yes

Sub-minute history is forward-only from the start of each venue’s capture coverage. Use start and end to probe the range you need; empty data means the requested range predates available capture, contains no trades, or crosses a capture gap. When the history is unavailable, the route returns retryable 503 HISTORY_UNAVAILABLE.

router is not supported for history — candles are venue-scoped.

Every candle carries provenance fields so you can distinguish true venue candles from derived ones:

{
"timestamp": 1780444800000,
"open": 0.61,
"high": 0.63,
"low": 0.6,
"close": 0.62,
"volume": null,
"source": "write-forward",
"sourceType": "point-derived",
"quality": "ok",
"isTrueCandle": false
}
  • source — official (venue history API), onchain, write-forward (availability-dependent recorder), or derived.
  • sourceType — true-candle vs point-derived / trade-derived / rest-derived / book-derived / rollup; rollup means query-time aggregation of stored finer candles.
  • quality — ok, partial, suspect, or mixed; mixed means the bucket aggregates inputs of differing quality. Known capture gaps report partial: known-damage honesty is part of the API contract.
  • volume is null where the source doesn’t provide it (most point-derived data).

REST-derived candles exist only for Gemini, Predict.fun, and Limitless. REST-derived candles are served only when stored and streamed candles are both absent; low-volume accrual is expected. They always report source: derived, sourceType: rest-derived, quality: partial, and isTrueCandle: false. Rollups over a uniformly partial REST base also report partial.

Candles are aggregates. GET /v1/history/books/events returns the lossless capture underneath them — the tape a backtest needs when the question is about book dynamics rather than closing prices.

Terminal window
curl -s "$PREDICTEFY_API_URL/v1/history/books/events?venue=polymarket&outcomeId=0xabc…&since=2026-09-01T00:00:00Z&until=2026-09-02T00:00:00Z" \
-H "Authorization: Bearer pk_live_YOUR_KEY"

venue, outcomeId, since, and until are all required: a call without the window returns 400 VALIDATION_ERROR. since and until accept an ISO timestamp or epoch milliseconds, and until must not precede since. outcomeId is the venue-native outcome id — the same value you would pass to fetchOrderBook, not the unified market id.

Rows come back ordered by receive time and sequence, and carry four kinds: snapshot, delta, gap, and heartbeat. The gap rows are the point: capture discontinuities are recorded rather than papered over, so a backtest can see where the tape is incomplete instead of silently treating a missing stretch as a quiet market.

Paging uses opaque cursors that continue the immutable tape strictly after the last returned (ts_recv, seq) key, so a cursor never re-reads or skips a row.

Both SDKs wrap it: client.fetchBookEvents({ venue, outcomeId, since, until }) in TypeScript and client.fetch_book_events(venue, outcome_id, since=start, until=end) in Python. Both window bounds are required either way. Each call returns one page and lifts the route’s cursor onto the page’s own next-cursor field, so paging reads like every other paged verb.

For bulk replay rather than book internals, GET /v1/history/replay returns one NDJSON page of top-of-book ticks, printed trades, or stored candles for a single outcome: one kind per request, each with its own keyset cursor, up to 20,000 rows a page over a window of at most 31 days, and every page metered as one history read. It accepts the canonical outcomeId or the venue-native id, and it is available on Builder and above since 2026-09-11 — a Free account gets 403 PLAN_REQUIRED naming Builder as the minimum plan. The Python SDK’s predictefy.backtest package pages it and merges the kinds into one ordered event stream; Backtest a strategy documents the row shapes, the cursor line, and what the engine assumes.

GET /v1/history/replay follows these plan limits (live since 2026-09-11):

PlanHistory replay window
FreeNot included
BuilderUp to the plan’s 12-month history window
ProUnlimited
EnterpriseUnlimited

Replay does not reach further back than the plan’s history window, the same rule as other history reads. Free receives 403 PLAN_REQUIRED, with Builder named as the minimum plan in the message; requests beyond a plan’s history window also return 403 PLAN_REQUIRED.

Every plan keeps the per-call ceilings of 20,000 rows a page and a 31-day window, including plans with an unlimited history window. Replay remains 5 credits per page. See the plan table.

The coverage matrix states only what is currently available:

VenueCurrent coverage
PolymarketDeep official, bounded set: one-year hourly coverage for a limited market set, plus availability-dependent forward capture. This is not all-market breadth.
KalshiDeep official: broad hourly backfill plus availability-dependent write-forward capture.
LimitlessREST-derived fallback: minute-and-up candles report quality: partial, plus availability-dependent write-forward capture. No stream capture, so sub-minute tiers are honest-empty.
Other write-forward venuesForward-only recording subject to per-venue capture and storage gaps; request the exact range rather than assuming continuous depth.
SX BetCaptured-tape/derived only: forward-only trade-derived candles. Minute-and-up tiers derive from the same tape. No official or catalog-price write-forward history is claimed.

History reads cost a flat 5 credits per query. Free reaches back 7 days and Builder 12 months; a request that starts or ends before your plan’s cutoff returns PLAN_REQUIRED. The other plan windows are listed under Pricing, credits & billing.