Real-time updates (SSE)
Live leaderboards and odds are available as Server-Sent Events (SSE) streams, so you can show scores update without polling. Two streams exist:
| Stream | Endpoint | Event name |
|---|---|---|
| Leaderboard | GET .../events/{eventSlug}/leaderboard/stream | leaderboard |
| Odds | GET .../events/{eventSlug}/odds/stream | odds |
Each stream's payload is identical to its non-streaming JSON counterpart
(.../leaderboard and .../odds) — so you can render from one shape whether you
fetched once or subscribed.
Wire format
The response is Content-Type: text/event-stream. On connect you get a comment
line, then a named event per update:
: connected
event: leaderboard
data: {"leaderboards":[ ... ]}
event: leaderboard
data: {"leaderboards":[ ... ]}
The leaderboard stream also accepts ?includeOdds=true to fold a winOdds
column into each row.
Consuming it
In the browser, use EventSource and listen for the named event (not the
default message):
const es = new EventSource(
"https://api.front9.io/api/public/v1/orgs/acme/events/spring-classic-2026/leaderboard/stream"
);
es.addEventListener("leaderboard", (e) => {
const data = JSON.parse(e.data);
render(data.leaderboards);
});
es.onerror = () => {
// EventSource auto-reconnects; close it when the user leaves the page.
};
Odds work the same way — listen for the odds event.
Tips
- Prefer the stream over polling for anything live — it's one connection and doesn't eat your rate-limit budget.
- Close the connection (
es.close()) when the view unmounts. - Odds may be
unavailable. Before an event has scores, an odds payload can arrive with"status": "unavailable"and amessage. Render accordingly. - For one-off reads (server-side rendering, snapshots), just call the plain
.../leaderboardor.../oddsendpoint instead.