17:30,
closes at 17:45, and resolves Up or Down against a frozen open
price the oracle pins seconds after the window starts. An exactly
unchanged price resolves Up.
Windows are machine-minted, never hand-listed. A series (BTC15M)
describes the recurring schedule; a factory materialises one market per
window on that grid, and groups a whole UTC day of them under one event.
outcomeLabels is ["Up", "Down"] — Up is outcome index
0 (the YES slot), Down is index 1.
Series on the event
A crypto Up/Down event carries acryptoSeries block; every other event
carries null. It is the entry point — navigate the series, not the
event’s markets[] array, because a day at 15-minute cadence is ~96
markets and the event nests only the windows around now: the tradeable
ones on GET /api/events, plus the windows awaiting settlement and the
three latest-ending settled (RESOLVED or VOIDED) windows on
GET /api/events/{slug}. A finished day on GET /api/events?status=closed
nests the same: every window still awaiting settlement and at most three
settled ones — except a day whose windows were all VOIDED before they
ended, which nests all of them while GET /api/events/{slug} returns 404.
The day’s full history is
GET /api/crypto-series/{id}/windows?state=all&from=2026-07-29&to=2026-07-30
— see Navigating a series. Check each market’s
status before trading.
Operator state (enabled / paused / delay counters / grace settings) is
deliberately not projected — this is the public surface.
The cryptoWindow block
On a window market, cryptoWindow carries the window facts. It is
null on every other market, including long-dated crypto markets.
A window market carries both
crypto (with
productType: "UP_DOWN_WINDOW") and cryptoWindow. Long-dated crypto
markets carry crypto only. cryptoWindow !== null is the reliable
“this is an Up/Down window” test.
Navigating a series
MarketSummary shape the markets endpoints
return, cryptoWindow included — so one renderer serves the list and
the detail page.
hasMore distinguishes a truncated page from end-of-data — a capped
chip strip is otherwise indistinguishable from a short day.
Buckets are computed from the window bounds against the current time,
not from lifecycle status. A window can be CLOSED while its period
is still current (settlement lag). current is normally one window
but is not guaranteed to be — treat it as a list.
Public endpoint,
600 req/min per IP, Cache-Control: public, max-age=5
— current flips on the minute, so anything longer would serve a stale
active window right after a rollover.
Window lifecycle
Settlement latency is decided by the challenge window that applies to
the market. A window armed for the fast on-chain path — its resolution
source registered and locked on chain — carries its own per-market
challenge window, normally zero, and then finalizes right after the
proposal. A window that is not armed uses the platform-wide challenge
window and resolves correspondingly later. Read
resolution.challengeWindowClosesAt rather than assuming either — it
is the exact instant finalize becomes legal. See
Settlement flow.
Live data
The chart line and the settlement price can come from different
Chainlink products on a window market. The frozen open and the live
tick come from Data Streams, and the
1min / 10m curves are built
from those recorded live ticks; the 1h-and-wider curves — and any
stretch of a 1min / 10m curve the ticks don’t cover — are built
from one-minute candlestick data. The two feeds track the same asset
but are not byte-identical, so a candle-built line can sit a few
dollars off the open line at the boundary instant. The curve is a
display surface — settlement binds cryptoWindow.openPrice.