Build a live score app
Every match in play right now, with the minute, the score and the corner count. One API call fills the whole screen.
The finished scoreboard
Sample output: the matches in play at one moment, as the API returned them. The sample was captured with an Ultra key, which returns every league; a free key returns the top-5 leagues.
| Min | League | Home | Score | Away | Corners |
|---|---|---|---|---|---|
| 77' | Lebanon League | Shabab Al-Sahel | 0–0 | Tadamon Sour | 2–3 |
| 77' | ASEAN Club Championship | Johor Darul Ta'zim | 4–0 | Svay Rieng FC | 2–3 |
| 80' | ASEAN Club Championship | Port FC | 1–0 | Persib Bandung | 9–2 |
| 75' | Montenegro Prva Liga | Otrant-Olympic Ulcinj | 2–2 | OFK Mladost DG | 4–1 |
| 76' | Bhutan Premier League | Thimphu City | 0–2 | Paro FC | 4–4 |
| 77' | Iraq Premier League | Al Ramadi SC | 1–3 | Al Nasiriyah | 7–4 |
| 73' | Iraq Premier League | Al-Jaish SC | 1–0 | Naft Al-Basra | 1–1 |
| 77' | Iraq Premier League | Peshmerga Sulaymaniya SC | 0–2 | Al Etisalat SC | 7–3 |
| 80' | Lebanon League | Akhaa Ahli Aley | 0–2 | Al Nejmeh | 0–9 |
| 78' | Oman U21 Championship | Dhofar U21 | 0–1 | Al-Nasr Salalah U21 | 1–5 |
10 of the 36 matches in play at 13:37 UTC on 8 October 2026. Sample captured from
GET /v1/fixtures?status=live&per_page=500
· See today's matches live →
The API calls behind it
-
1
GET /v1/fixtures?status=live&per_page=500Every match in play right now, on one page: minute, score, corners and cards per row. Reference →
What it takes to run
- The free plan returns live matches from the top-5 leagues — no card needed.
- One request per refresh. The script refreshes at most once a minute, however many people have the page open.
- That is at most 60 requests an hour; the free plan allows 60 requests / hour.
- Pro at $5/mo widens it to 130+ competitions at 10 requests / min.
The code
Install the client, save the script, run it with your key.
npm install fivedollarfootballconst http = require('node:http');
const { Client } = require('fivedollarfootball');
const client = new Client(process.env.FIVEDOLLARFOOTBALL_API_KEY);
const esc = (s) => String(s).replace(/[&<>]/g, (c) => `&#${c.charCodeAt(0)};`);
let cache = { at: 0, html: '' };
async function scoreboard() {
// Ask the API at most once a minute, however many visitors there are.
if (Date.now() - cache.at < 60_000) return cache.html;
// One call: every match in play right now.
const { data: matches } = await client.fixtures({ status: 'live', perPage: 500 });
const rows = matches.map((m) => `<tr>
<td>${m.status_code === 'half' ? 'HT' : m.status_code + "'"}</td>
<td>${esc(m.league.name)}</td>
<td align="right">${esc(m.teams.home.name)}</td>
<td><b>${m.goals.home} - ${m.goals.away}</b></td>
<td>${esc(m.teams.away.name)}</td>
<td>${m.corners.home} - ${m.corners.away}</td>
</tr>`);
cache.at = Date.now();
cache.html = `<meta http-equiv="refresh" content="60">
<h1>Live scores (${matches.length})</h1>
<table cellpadding="6">
<tr><th>Min</th><th>League</th><th>Home</th><th></th><th>Away</th><th>Corners</th></tr>
${rows.join('')}
</table>`;
return cache.html;
}
http.createServer(async (req, res) => {
try {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(await scoreboard());
} catch (err) {
res.end(`Could not load scores: ${esc(err.message)}`);
}
}).listen(3000, () => console.log('Scoreboard on http://localhost:3000'));
FIVEDOLLARFOOTBALL_API_KEY=fb_live_your_key node server.jsThe full project is on GitHub: 5dollarfootball-api/football-live-score-app →
Take it further
- Add include: ['events'] to get each match's goal, corner and card timeline in the same call.
- Add include: ['stats'] for attacks, shots and possession per match.
- Pass league: id to show one competition only.
- Call client.fixtures() with no status for the whole day: fixtures, live matches and results.
- Pass lang: 'es' (or any of 21 languages) for localized team and league names.
The data behind this example
Frequently asked questions
Yes. It makes one request per refresh and refreshes at most once a minute, which is 60 requests an hour at most. The free plan allows 60 requests / hour, returns the top-5 leagues and needs no card.
A key in browser JavaScript can be read by anyone who opens the page. The script keeps the key in a server process and sends the browser only the rendered scoreboard, and its one-minute cache means a thousand visitors still cost one request a minute.
All of them. With status=live the page size goes up to 500, so a single page holds every match in play and the list cannot shift between two page requests.
Start building for free
Get a working API key in under a minute. No credit card, no sales call.