SSE stream of contest updates for a series
const url = 'https://api.cotes.ai/v1/stream/contests?series=KXBTC15M';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.cotes.ai/v1/stream/contests?series=KXBTC15M' \ --header 'Authorization: Bearer <token>'Long-lived Server-Sent Events stream. Each event is:
event: <name>
id: <opaque>
data: <json>
| Event | data payload |
|---|---|
contest.opened |
Contest (live contest when first seen or a new ticker opens) |
signal.emitted |
SignalEmittedPayload (signal + parent contest) |
contest.settled |
Contest (settled snapshot) |
On connect, the stream may immediately emit contest.opened (and
signal.emitted for each Cotes AI signal already on the contest) for the current live contest.
id is opaque — do not parse it. The timestamp inside a signal.emitted
id is not byte-identical to that signal’s raised_at in data; correlate
on the JSON, not on the id.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Series prefix, e.g. KXBTC15M. Match is exact and case-sensitive on the prefix. A full ticker also resolves while that round is live, but use /v1/contests/{ticker} for a specific round.
Example
KXBTC15MResponses
Section titled “Responses”text/event-stream of named SSE frames. See operation description for
event names and JSON payload shapes.
Raw SSE byte stream. Parse with an EventSource client (or equivalent);
data is JSON matching Contest or SignalEmittedPayload.
Examples
contest.opened then signal.emitted
event: contest.openedid: KXBTC15M-26AUG061600-00:openeddata: {"ticker":"KXBTC15M-26AUG061600-00","state":"live","window":{"opens_at":"2026-08-06T19:45:00Z","expires_at":"2026-08-06T20:00:00Z"},"strike_price_dollars":64367.0,"settled_side":null,"settled_price_dollars":null,"signals":[]}
event: signal.emittedid: KXBTC15M-26AUG061600-00:2026-08-06T19:50:00.000002+00:00data: {"signal":{"ticker":"KXBTC15M-26AUG061600-00","raised_at":"2026-08-06T19:50:00.000002Z","side":"down","confidence":72.6,"entry_price_cents":52.0,"edge_cents":20.6,"outcome":"pending","model_version":"c5456da6"},"contest":{"ticker":"KXBTC15M-26AUG061600-00","state":"live","window":{"opens_at":"2026-08-06T19:45:00Z","expires_at":"2026-08-06T20:00:00Z"},"strike_price_dollars":64367.0,"settled_side":null,"settled_price_dollars":null,"signals":[{"ticker":"KXBTC15M-26AUG061600-00","raised_at":"2026-08-06T19:50:00.000002Z","side":"down","confidence":72.6,"entry_price_cents":52.0,"edge_cents":20.6,"outcome":"pending","model_version":"c5456da6"}]}}
event: contest.settledid: KXBTC15M-26AUG061600-00:settleddata: {"ticker":"KXBTC15M-26AUG061600-00","state":"settled","window":{"opens_at":"2026-08-06T19:45:00Z","expires_at":"2026-08-06T20:00:00Z"},"strike_price_dollars":64367.0,"settled_side":"down","settled_price_dollars":64312.75,"signals":[{"ticker":"KXBTC15M-26AUG061600-00","raised_at":"2026-08-06T19:50:00.000002Z","side":"down","confidence":72.6,"entry_price_cents":52.0,"edge_cents":20.6,"outcome":"win","model_version":"c5456da6"}]}Missing or invalid API key
object
Examplegenerated
{ "type": "https://example.com", "title": "example", "status": 1, "detail": "example"}Too many requests
object
Examplegenerated
{ "type": "https://example.com", "title": "example", "status": 1, "detail": "example"}