Runs on the free plan Node.js 1 API call

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. 1
    GET /v1/fixtures?status=live&per_page=500

    Every 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.
Compare plans

The code

Install the client, save the script, run it with your key.

npm install fivedollarfootball
const 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.js

The 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.

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.