Guides / Build a live score app

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:

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 with requests.
  • Your key in an environment variable, so it never appears in code:
Terminal
export GOSPORTS_API_KEY=your_api_key_here

1. 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, UTC
const { data: fixtures } = await get("/football/fixtures", {
league_id: 39,
date: today,
});
// Keep fixtures by id so live updates can be merged in
const 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:

Response (trimmed)
{
"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 interval
const 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);
}
}
Output
Manchester City 1-1 Liverpool 67’
Arsenal vs Chelsea NS

In 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