Skip to content

SSE stream of contest updates for a series

GET
/v1/stream/contests
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.

series
required
string
>= 1 characters

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
KXBTC15M

text/event-stream of named SSE frames. See operation description for event names and JSON payload shapes.

Media typetext/event-stream

Raw SSE byte stream. Parse with an EventSource client (or equivalent); data is JSON matching Contest or SignalEmittedPayload.

string
Examples
ExamplesampleFrames

contest.opened then signal.emitted

event: contest.opened
id: KXBTC15M-26AUG061600-00:opened
data: {"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.emitted
id: KXBTC15M-26AUG061600-00:2026-08-06T19:50:00.000002+00:00
data: {"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.settled
id: KXBTC15M-26AUG061600-00:settled
data: {"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

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
detail
required
string
Examplegenerated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example"
}

Too many requests

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
detail
required
string
Examplegenerated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example"
}
Retry-After
integer
X-RateLimit-Limit
integer
X-RateLimit-Remaining
integer