websocket entitlement, included with Sharp and Max
and some active grants/legacy plans. REST rate limits and monthly request quota
do not meter WebSocket frames. Streaming availability is separate from REST
endpoint availability.
Connect
PreferAuthorization: Bearer <workspace-api-token> during the HTTP upgrade.
Browser clients that cannot set headers can use ?token=...; the Authorization
header takes precedence. Protect the URL as a credential. Reads require
api.read scope. Authentication and plan failures occur before upgrade as HTTP
401/403; token-store failures can return 500.
There is one active connection per token and organization. A new connection
supersedes the previous one. Share that connection inside your own service if
several consumers need the same feed.
Subscribe and unsubscribe
Send one JSON frame per channel:unsubscribe with the same channel; the server replies unsubscribe.ok.
Duplicate subscriptions are idempotent. Failed subscriptions use
subscribe.error and reason, including invalid_channel,
too_many_subscriptions, or rate_limited.
IDs can contain dots. Use the returned canonical ID in its entirety. A valid
channel name is not evidence that data currently exists for that channel.
Bookmaker visibility applies to pushed odds/prop data too.
Events and recovery
data is the channel-specific event payload; it is not the REST response
envelope. Event IDs are monotonic per connection, not durable replay cursors.
The server does not send an initial REST snapshot when confirming a subscription.
Use REST to initialize your state and apply subsequent events.
A gap frame includes channel, optional missed_count, from_id, to_id,
and ts. Counts/IDs are best-effort and can be omitted. A gap signals dropped
events or a restarted upstream stream. Refetch the affected resource through
REST and continue; there is no customer replay/resume API. On reconnect,
resubscribe and refresh state.
Heartbeat and limits
Every 20 seconds the server sends{"type":"ping"}. Reply with
{"type":"pong"} within 10 seconds. These are JSON application frames.
The current implementation allows 100 subscriptions per connection and limits
incoming frames with a 250-frame burst bucket refilling at 20 frames/second.
Inbound messages are limited to 4 KiB. Slow consumers can overflow the bounded
send queue and receive gap notifications.
Open connections revalidate token/access approximately every minute. Some
entitlements are captured at connection time, so reconnect after plan changes.
Use jittered backoff for transient disconnects; avoid a reconnect contest
between two services that repeatedly supersede each other.