Streaming (SSE)
GET /v1/stream/contests?series={series} is a long-lived Server-Sent Events stream. Authenticate with the same API key as REST.
Connect
Section titled “Connect”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.
Event types
Section titled “Event types”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.
Losing authorization mid-stream
Section titled “Losing authorization mid-stream”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: unauthorizeddata: {"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.