Skip to content

Streaming (SSE)

GET /v1/stream/contests?series={series} is a long-lived Server-Sent Events stream. Authenticate with the same API key as REST.

Terminal window
curl -N -H "Authorization: Bearer $COTES_API_KEY" \
-H "Accept: text/event-stream" \
"https://api.cotes.ai/v1/stream/contests?series=KXBTC15M"

Browsers cannot set Authorization on the built-in EventSource API. Use fetch with a stream reader, or proxy the stream from your backend.

Each frame looks like:

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)
unauthorized Problem detail — terminal, see below

On connect, you may receive the current live contest and its existing Cotes AI signals before new events arrive.

Your key and your account’s entitlement are re-checked on every poll tick, not just when the stream opens. Revoke a key or let a subscription lapse while a stream is running and the feed ends with a final unauthorized event:

event: unauthorized
data: {"type":"https://api.cotes.ai/problems/unauthorized","title":"Unauthorized","detail":"API key revoked or account no longer entitled."}

The event exists so the close is distinguishable from a dropped connection. Treat it as terminal — reconnecting fails the same way until the key or the subscription is sorted out, so a client that blindly retries will spin.