Tutorials

Build a Live Scores & Match Center

Real-time events, API integration, and UI patterns for scoreboards with complete code examples.

2025-10-21· 5 min read

Overview

In this tutorial, you'll learn how to build a live scores application using the API 4 Sports Football API. We'll cover fetching live matches, displaying match details, and implementing real-time updates.

Prerequisites

  • An API 4 Sports account with an active subscription
  • Your API key from the dashboard
  • Basic knowledge of JavaScript/Python

Fetching Live Matches

The /football/live endpoint returns all currently live matches with events, lineups, and statistics. This is your main endpoint for real-time scoreboards.

cURL Request

bash
curl -X GET "https://api.api4sports.com/api/football/live" \
  -H "X-Api-Key: your_api_key_here"

JavaScript Implementation

javascript
async function getLiveMatches() {
  const response = await fetch('https://api.api4sports.com/api/football/live', {
    headers: { 'X-Api-Key': process.env.API_KEY }
  });
  
  const data = await response.json();
  return data.result;
}

// Usage
const liveMatches = await getLiveMatches();
console.log(`${liveMatches.length} matches currently live`);

Python Implementation

python
import requests

def get_live_matches():
    url = "https://api.api4sports.com/api/football/live"
    headers = {"X-Api-Key": "your_api_key_here"}
    
    response = requests.get(url, headers=headers)
    data = response.json()
    return data.get("result", [])

# Usage
live_matches = get_live_matches()
print(f"{len(live_matches)} matches currently live")

Live Match Response

json
{
  "success": 1,
  "result": [
    {
      "match_id": 59409,
      "date": "2024-01-15",
      "time": "20:45",
      "country_name": "England",
      "league": "Premier League",
      "league_id": 207,
      "result": "2 - 1",
      "result_time": "67'",
      "live": true,
      "home_team": {
        "id": 96,
        "name": "Manchester United",
        "logo": "https://api.api4sports.com/logos/football/logo_teams/manchester-united.png"
      },
      "away_team": {
        "id": 97,
        "name": "Arsenal",
        "logo": "https://api.api4sports.com/logos/football/logo_teams/arsenal.png"
      },
      "home_formation": "4-2-3-1",
      "away_formation": "4-3-3",
      "stadium": "Old Trafford",
      "lineups": {
        "home": [
          { "player_name": "Marcus Rashford", "player_id": "1234", "number": 10, "position": "F" }
        ],
        "away": []
      },
      "statistics": [
        { "name": "Ball Possession", "home": "55%", "away": "45%" },
        { "name": "Shots on Target", "home": "8", "away": "5" }
      ],
      "events": [
        {
          "time": "45",
          "time_info": "+2",
          "info": "goal",
          "score": "1 - 0",
          "home_scorer": "Marcus Rashford",
          "home_assist": "Bruno Fernandes"
        }
      ]
    }
  ]
}

Getting Match Details

For detailed match information including comments, VAR decisions, and odds, use the match details endpoint.

Request with Options

bash
curl -X GET "https://api.api4sports.com/api/football/matches/59409/details?with_comments=true&with_vars=true&with_odds=true" \
  -H "X-Api-Key: your_api_key_here"

JavaScript - Get Match Details

javascript
async function getMatchDetails(matchId, options = {}) {
  const params = new URLSearchParams({
    with_comments: options.comments ?? true,
    with_vars: options.vars ?? true,
    with_odds: options.odds ?? true
  });
  
  const response = await fetch(
    `https://api.api4sports.com/api/football/matches/${matchId}/details?${params}`,
    { headers: { 'X-Api-Key': process.env.API_KEY } }
  );
  
  const data = await response.json();
  return data.result;
}

// Usage
const match = await getMatchDetails(59409);
console.log(`${match.home_team.name} vs ${match.away_team.name}`);
console.log(`Score: ${match.result}`);
console.log(`Events: ${match.events.length}`);

Match Details Response

json
{
  "success": 1,
  "result": {
    "match_id": 59409,
    "date": "2024-01-15",
    "time": "20:45",
    "league": "Premier League",
    "league_id": 207,
    "home_team": { "id": 96, "name": "Manchester United" },
    "away_team": { "id": 97, "name": "Arsenal" },
    "result": "2 - 1",
    "ft_score": "2 - 1",
    "result_h1": "1 - 0",
    "stadium": "Old Trafford",
    "referee": "Michael Oliver",
    "lineups": {
      "home": [{ "player_name": "Marcus Rashford", "number": 10, "position": "F" }],
      "away": []
    },
    "statistics": [
      { "name": "Ball Possession", "home": "55%", "away": "45%" }
    ],
    "events": [
      { "time": "45", "info": "goal", "score": "1 - 0", "home_scorer": "Marcus Rashford" }
    ],
    "comments": [
      { "time": "45", "text": "Goal! Manchester United 1-0", "state": 1 }
    ],
    "vars": [
      { "minute": "67", "player_name": "Marcus Rashford", "type": "Goal", "decision": "Goal Confirmed" }
    ],
    "odds": {
      "Match Winner": {
        "Home": { "bet365": "3.10", "Marathon": "3.16" },
        "Draw": { "bet365": "3.50" },
        "Away": { "bet365": "2.25" }
      }
    }
  }
}

Real-Time Update Strategy

For live scoreboards, implement polling with appropriate intervals based on match status:

  • Pre-match: Refresh every 15-30 minutes
  • In-play: Refresh every 5-10 seconds for live updates
  • Post-match: Finalize stats and stop polling

Polling Implementation

javascript
class LiveScorePoller {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.intervalId = null;
  }
  
  async fetchLiveMatches() {
    const response = await fetch('https://api.api4sports.com/api/football/live', {
      headers: { 'X-Api-Key': this.apiKey }
    });
    return (await response.json()).result;
  }
  
  start(callback, intervalMs = 10000) {
    // Initial fetch
    this.fetchLiveMatches().then(callback);
    
    // Start polling
    this.intervalId = setInterval(async () => {
      const matches = await this.fetchLiveMatches();
      callback(matches);
    }, intervalMs);
  }
  
  stop() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  }
}

// Usage
const poller = new LiveScorePoller(process.env.API_KEY);
poller.start((matches) => {
  console.log('Live matches updated:', matches.length);
  // Update your UI here
}, 10000); // Poll every 10 seconds

Fetching League Standings

Display current standings alongside live matches for context.

Get Standings Request

bash
curl -X GET "https://api.api4sports.com/api/football/leagues/207/standings?type=total" \
  -H "X-Api-Key: your_api_key_here"

Standings Response

json
{
  "success": 1,
  "result": [
    {
      "place": 1,
      "team_id": 96,
      "team": "Manchester United",
      "team_logo": "https://api.api4sports.com/logos/football/logo_teams/manchester-united.png",
      "played": 38,
      "wins": 25,
      "draws": 8,
      "losses": 5,
      "goals_for": 75,
      "goals_against": 30,
      "goal_difference": 45,
      "points": 83,
      "form": "WWDWL",
      "promotion": "Champions League"
    }
  ]
}

UI Patterns for Scoreboards

  • Sticky header with score and match clock
  • Event timeline with icons for goals, cards, substitutions
  • Responsive layout optimized for mobile first
  • Highlight score changes with subtle animations
  • Show live indicator badge for in-progress matches

Accessibility Considerations

Announce score changes to screen readers using ARIA live regions and ensure good color contrast for live update indicators.

Caching Strategy

  • CDN for static assets and team logos
  • Short TTL (5-10 seconds) for live match data
  • Longer TTL (1 hour+) for standings and historical data
  • Use stale-while-revalidate for smoother UX

Next Steps

Enhance your scoreboard with live odds integration. Check out the Build a Live Odds App tutorial for adding betting data to your application.