Before any recipe, fetch the leagues your plan can read and keep the list:
GET /v2.2/leagues/?api_key=API_KEY&t=list&page=1
It is paginated (100 per page, meta.pages), and it is the only reliable way
to know which competitions the account covers; every feed below is already
filtered to those leagues.
Livescore screen
Plans: every plan for the feeds; events and stats need a Standard or World
Cup plan.
Today's matches, grouped by league. Page through
meta.pages; a busy day has several hundred matches.GET /v2.2/livescores/?api_key=API_KEY&t=today&utc=2&page=1Live loop. Poll the live feed on a fixed cadence (30 to 60 seconds) and merge each snapshot into the list from step 1 by match
id. Embedding the timeline and team statistics avoids extra calls per match.GET /v2.2/livescores/?api_key=API_KEY&t=live&include=events,statsMatch detail when the user opens a match: one call with the datasets you show, plus lineups and bench on demand.
GET /v2.2/fixtures/?api_key=API_KEY&t=info&id=2589310&include=events,stats GET /v2.2/fixtures/?api_key=API_KEY&t=match_lineups&id=2589310 GET /v2.2/fixtures/?api_key=API_KEY&t=match_bench&id=2589310Render state from
status, not from the scores:0not started,1in play withstatus_period(1st Half,2nd Half) andtime.minute,11half time,3finished,31finished after penalties,4postponed,5cancelled. The full list is in Statuses.Details that make the screen look right:
teams.home.kit_colorsfor shirt colours,coverage.has_lineupsto decide whether to show a lineups tab,time.timestampto format the kickoff in the viewer's zone, andscores.ht_score/ft_score/et_score/ps_scorefor the period scores.
const base = 'https://api.soccersapi.com/v2.2';
const apiKey = process.env.SOCCERSAPI_API_KEY;
if (!apiKey) throw new Error('Missing SOCCERSAPI_API_KEY');
function requestUrl(params) {
const url = new URL(`${base}/livescores/`);
url.search = new URLSearchParams({ api_key: apiKey, ...params });
return url;
}
async function todayMatches(utc = 0) {
const all = [];
for (let page = 1, pages = 1; page <= pages; page++) {
const res = await fetch(requestUrl({ t: 'today', utc, page }));
const body = await res.json();
if (!res.ok) throw new Error(body.meta?.msg || body.message || res.status);
all.push(...body.data);
pages = body.meta.pages;
}
return all;
}
async function liveSnapshot() {
const res = await fetch(requestUrl({ t: 'live', include: 'events,stats' }));
if (!res.ok) throw new Error(`SoccersAPI ${res.status}`);
return (await res.json()).data;
}
import os
import requests
BASE = "https://api.soccersapi.com/v2.2"
API_KEY = os.environ["SOCCERSAPI_API_KEY"]
def today_matches(utc=0):
matches, page, pages = [], 1, 1
while page <= pages:
r = requests.get(f"{BASE}/livescores/", params={"api_key": API_KEY, "t": "today", "utc": utc, "page": page}, timeout=15)
body = r.json()
if r.status_code != 200:
raise RuntimeError(body.get("meta", {}).get("msg") or body.get("message") or r.status_code)
matches += body["data"]
pages = body["meta"]["pages"]
page += 1
return matches
Where to watch
Plans: Standard, World Cup and Broadcast.
Matches on TV for a date, with the channels embedded in each match. Paginated like every feed.
GET /v2.2/broadcast/?api_key=API_KEY&t=schedule&d=2026-08-30&include=tvs&utc=2&page=1Each match carries
tvs[]withid,name,typeandcountry. Keep the channels whosecountry.ccmatches the viewer's country.Channels of one match, for a match page you already have from another feed.
broadcast?t=match_tvsreturns every channel worldwide with its country;fixtures?t=info&include=broadcastdoes the same inside the match object.GET /v2.2/broadcast/?api_key=API_KEY&t=match_tvs&id=2589310 GET /v2.2/fixtures/?api_key=API_KEY&t=info&id=2589310&include=broadcastChannel pages. The channel catalogue by country, one channel's profile with its logo and website, and the matches it shows over the next two weeks.
GET /v2.2/broadcast/?api_key=API_KEY&t=list&country_id=15 GET /v2.2/broadcast/?api_key=API_KEY&t=info&id=31 GET /v2.2/fixtures/?api_key=API_KEY&t=tv&tv_id=31Fixture lists that already carry TV data. If your product fetches fixtures anyway, add
include=broadcasttoschedule,season,round,infoorsortinstead of calling the broadcast route again.
coverage.has_tvs on a match tells you whether broadcast data exists for it,
so you can hide the "where to watch" block instead of showing it empty.
Odds
Plans: Standard, World Cup and Odds. Odds are strings in the format selected
with odds_format (decimal by default, fractional, american).
Pre-match odds for a list of matches: embed them in the fixture list. Add
bookmaker_ids=9,2to return only bookmakers 9 and 2, in that order.GET /v2.2/fixtures/?api_key=API_KEY&t=info&id=2589310&include=odds_prematch&bookmaker_ids=9,2odds_prematch[]has one entry per market (1X2, Full Time Result,Over/Under, Goal Line,Asian Handicap, and the first-half and corners variants) withbookmakers[], each carryingodds.data:home,draw,awayfor 1X2,over,underand thehandicapline for goal lines, andlast_update.All odds of one match, or the history of one bookmaker for it.
GET /v2.2/fixtures/?api_key=API_KEY&t=match_odds&id=2589310 GET /v2.2/fixtures/?api_key=API_KEY&t=match_odds_info&id=2589310&bookmaker_id=1In-play odds on the live feed or on a match detail. Each entry reports the
scoreandminutethe price refers to, so you can discard stale quotes. Usebookmaker_ids=9,3,1to select that bookmaker order, orbookmaker_ids=2to select one bookmaker.GET /v2.2/livescores/?api_key=API_KEY&t=live&include=odds_inplay&bookmaker_ids=9,3,1 GET /v2.2/fixtures/?api_key=API_KEY&t=info&id=2589310&include=odds_inplay&bookmaker_ids=2 GET /v2.2/fixtures/?api_key=API_KEY&t=match_oddsinplay&id=2589310The same filter applies to
include=odds_prematchon supported feeds and fixture operations. Withinclude=odds_prematch,odds_inplay, it filters and orders thebookmakers[]entries in both datasets.Catalogues for logos and market names.
GET /v2.2/bookmakers/?api_key=API_KEY&t=list GET /v2.2/markets/?api_key=API_KEY&t=list
Odds coverage varies by match and bookmaker; treat an empty bookmakers[] as
"no price yet", not as an error.
Competition page
Plans: Standard and World Cup for standings, leaders and statistics; every plan for the rest.
GET /v2.2/leagues/?api_key=API_KEY&t=info&id=583 # Premier League profile and current season
GET /v2.2/seasons/?api_key=API_KEY&t=info&id=21033 # Premier League 2026/27 structure
GET /v2.2/leagues/?api_key=API_KEY&t=standings&season_id=21033 # current table
GET /v2.2/rounds/?api_key=API_KEY&t=byseason&season_id=21033 # match days and current round
GET /v2.2/fixtures/?api_key=API_KEY&t=round&round_id=216028 # fixtures from the sampled round
GET /v2.2/fixtures/?api_key=API_KEY&t=season&season_id=21033 # full 2026/27 fixture list
GET /v2.2/leaders/?api_key=API_KEY&t=topscorers&season_id=21033 # also topassists, topcards
GET /v2.2/stats/?api_key=API_KEY&t=season&id=21033 # season totals
Standing rows carry overall, home and away records, status (zone label
such as Promotion or Relegation), result (for example Champions League)
and recent_form. Competitions with several tables return one row per table,
identified by group, and number_standings says how many there are.
Team page
GET /v2.2/teams/?api_key=API_KEY&t=info&id=20 # Chelsea profile and current seasons
GET /v2.2/teams/?api_key=API_KEY&t=squad&id=20&season_id=21033 # current Premier League squad
GET /v2.2/fixtures/?api_key=API_KEY&t=last_next&team_id=20 # recent and upcoming matches
GET /v2.2/stats/?api_key=API_KEY&t=team&id=20&season_id=21033 # 2026/27 team statistics
GET /v2.2/venues/?api_key=API_KEY&t=info&id=1166 # venue linked from the match object
GET /v2.2/coaches/?api_key=API_KEY&t=info&id=12680 # coach linked from the match object
Squads, sidelined players, transfers and trophies need a Standard or World Cup plan; profiles, lists and fixtures are available on every plan.