Build a live score app
In this guide you will build a small live scoreboard: load today’s fixtures, poll the live endpoint every 60 seconds and print each score as it changes.
What you’ll build
A small program that lists today’s Premier League fixtures and keeps their scores up to date while matches are in play. It uses two endpoints:
GET /football/fixtures— today’s fixtures, loaded once at start-up.GET /football/fixtures/live— live scores, polled every 60 seconds.
The same pattern works for every sport with live data — swap in /basketball/livescores, /hockey/livescores and so on.
Before you start
- An API key — see API Keys.
- Node.js 18 or later (for the built-in
fetch), or Python 3 withrequests. - Your key in an environment variable, so it never appears in code:
export GOSPORTS_API_KEY=your_api_key_here1. Fetch today’s fixtures
Start with a tiny helper that adds your key to every request to https://api.gosportsapi.com/v1, then load today’s fixtures (dates are UTC). league_id=39 is the Premier League in these examples.
const API = "https://api.gosportsapi.com/v1";const headers = { "x-api-key": process.env.GOSPORTS_API_KEY };async function get(path, params = {}) { const res = await fetch(API + path + "?" + new URLSearchParams(params), { headers }); if (!res.ok) throw new Error("Request failed: " + res.status); return res.json();}const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD, UTCconst { data: fixtures } = await get("/football/fixtures", { league_id: 39, date: today,});// Keep fixtures by id so live updates can be merged inconst board = new Map(fixtures.map((f) => [f.id, f]));2. Get live scores
/football/fixtures/live returns only fixtures in play, in the same shape as /football/fixtures, with score and status.minute filled in:
{ "data": [ { "id": 1048207, "status": { "short": "LIVE", "minute": 67 }, "home": { "id": 50, "name": "Manchester City", "score": 1 }, "away": { "id": 40, "name": "Liverpool", "score": 1 } } ], "meta": { "page": 1, "per_page": 50, "total": 4 }}Merge each live fixture into the board by id. A finished match drops out of the live list, so when a fixture that was in play disappears, reload today’s fixtures once to get its final score.
const IN_PLAY = ["LIVE", "HT"];async function refresh() { const { data: live } = await get("/football/fixtures/live", { league_id: 39 }); const liveIds = new Set(live.map((f) => f.id)); const ended = [...board.values()].some( (f) => IN_PLAY.includes(f.status.short) && !liveIds.has(f.id), ); for (const fixture of live) board.set(fixture.id, fixture); if (ended) { // A match just finished: reload today to pick up its final score const { data } = await get("/football/fixtures", { league_id: 39, date: today }); for (const fixture of data) board.set(fixture.id, fixture); }}3. Poll every 60 seconds
Data freshness is about 30 seconds and the recommended polling interval is 60 seconds. Polling faster spends requests without getting you fresher scores. One request covers every live fixture in the league, however many are playing.
const POLL_MS = 60 * 1000; // recommended polling intervalconst DONE = ["FT", "PST", "CANC"];async function loop() { await refresh(); render(); const active = [...board.values()].some((f) => !DONE.includes(f.status.short)); if (active) setTimeout(loop, POLL_MS); // stop once every match is over}loop();Why setTimeout, not setInterval?
Scheduling the next poll after the previous one finishes means a slow response can never overlap the next request.
4. Render the scoreboard
Print one line per fixture: the score once it has started, otherwise the status.
function render() { console.clear(); for (const f of board.values()) { const score = f.home.score === null ? "vs" : f.home.score + "-" + f.away.score; const clock = f.status.short === "LIVE" ? f.status.minute + "’" : f.status.short; console.log(f.home.name.padEnd(18), score.padStart(3).padEnd(5), f.away.name.padEnd(18), clock); }}Manchester City 1-1 Liverpool 67’Arsenal vs Chelsea NSIn a web or mobile app, serve the board from a backend route instead of printing it — your key stays on the server. See Call the API from a server.
Next steps
- Handling live matches — poll only around kick-off and turn score changes into goal alerts.
- Caching — serve thousands of users from one request a minute.
- API reference by sport — the live endpoints for the other sports.