Skip to content

API-Football Source Research

Status: implemented in pkg/source/api_football with supported-source docs at docs/supported-sources/api-football.md.

Primary docs:

Connection

ItemValue
Base URLhttps://v3.football.api-sports.io
Authx-apisports-key: <api-key> request header
World Cup identifiersleague=1, season=2026
Response envelopeget, parameters, errors, results, paging, response
PaginationEndpoint-specific. players uses page; some endpoints return one page for league/season filters.
Rate limitsPlan quota based. Free is 100 requests/day; Pro 7,500/day; Ultra 75,000/day; Mega 150,000/day.

API-Football states that all plans include all competitions and endpoints, with free plans limited by available seasons. For World Cup 2026, verify actual free-plan access with a live key before promising free production coverage.

Tier Map

PlanMonthly priceRequest quotaEndpoint availability
Free$0100/dayAll endpoints, but available seasons are limited.
Pro$197,500/dayAll competitions and endpoints.
Ultra$2975,000/dayAll competitions and endpoints.
Mega$39150,000/dayAll competitions and endpoints.

Main Table Coverage

Main tableCoveragePrimary endpointRequired tierNotes
TeamsYesGET /teams?league=1&season=2026Free or paid, subject to free season accessResponse includes team and a nested venue object.
StadiumsPartial/direct and fixture-derivedGET /venues, plus venues embedded in /fixtures and /teamsFree or paid, subject to free season accessThere is no World Cup stadium list filter; derive venue IDs from fixtures, then hydrate with /venues?id=... when venue IDs are present.
Group standingsYesGET /standings?league=1&season=2026Free or paid, subject to free season accessWorld Cup guide says this returns all 12 group tables.
MatchesYesGET /fixtures?league=1&season=2026Free or paid, subject to free season accessUse id or ids for detail refresh; ids accepts up to 20 fixture IDs separated by -.
PlayersYesGET /players?league=1&season=2026&page=1Free or paid, subject to free season accessPaginated. Also consider /players/squads?team=... for squad-shaped extraction.
Match eventsYesGET /fixtures/events?fixture=<fixture_id>Free or paid, subject to free season accessThe World Cup guide says fixture and event data updates every 15 seconds for live matches.

Endpoint Map

Competition Coverage

GET /leagues

Use this as the first call for a connector run to verify that league=1&season=2026 has the coverage flags expected for fixtures, events, lineups, fixture statistics, player statistics, standings, players, injuries, predictions, and odds.

ParameterRequiredTypeUse
idNointegerUse 1 for World Cup.
seasonNoYYYY integerUse 2026 for World Cup 2026.
teamNointegerFilter leagues by team ID.
nameNostringSearch by league name.
countryNostringFilter by country.
codeNo2-6 character stringFilter by country code.
typeNoleague or cupFilter by competition type.
currentNotrue or falseActive seasons only.
searchNostring, 3+ charsSearch league or country.
lastNointeger, 2 digits maxRecently added leagues/cups.

Recommended World Cup call:

http
GET /leagues?id=1&season=2026
x-apisports-key: <api-key>

Teams

GET /teams

ParameterRequiredTypeUse
idNointegerSingle team by API-Football team ID.
nameNostringSingle team by exact-ish name.
leagueNointegerUse 1 for World Cup teams.
seasonNoYYYY integerRequired with league for tournament teams.
countryNostringCountry name.
codeNo3-character stringTeam code.
venueNointegerTeams for a venue ID.
searchNostring, 3+ charsTeam or country search.

Recommended World Cup call:

http
GET /teams?league=1&season=2026

Ingestion shape: one teams row per response[], flattening the team object and optionally preserving the nested venue fields as team-home-venue metadata. Do not treat team-home venue as World Cup match stadium without cross-checking fixtures.

Stadiums / Venues

GET /venues

ParameterRequiredTypeUse
idNointegerHydrate one venue ID.
nameNostringFilter by venue name.
cityNostringFilter by city.
countryNostringFilter by country.
searchNostring, 3+ charsSearch name, city, or country.

Recommended World Cup flow:

  1. Fetch GET /fixtures?league=1&season=2026.
  2. Extract unique fixture.venue.id values where non-null.
  3. Fetch GET /venues?id=<venue_id> per venue if the fixture object does not contain enough stadium fields.

The official World Cup guide emphasizes 16 stadiums, but the generic /venues endpoint does not expose league or season filters, so stadium extraction should be fixture-derived.

Group Standings

GET /standings

ParameterRequiredTypeUse
seasonYesYYYY integerUse 2026.
leagueNointegerUse 1 for all World Cup group tables.
teamNointegerFilter to a specific team.

Recommended World Cup call:

http
GET /standings?league=1&season=2026

Ingestion shape: flatten nested league.standings[][] into one row per team per group, preserving league.id, league.season, group, rank, team.id, points, goalsDiff, form, status, description, and the nested all/home/away records if present.

Matches

GET /fixtures

ParameterRequiredTypeUse
idNointegerSingle fixture. Detail response includes events, lineups, fixture stats, and player stats when available.
idsNoid-id-id, max 20Batch fixture details.
liveNoall or leagueId-leagueIdLive fixtures.
dateNoYYYY-MM-DDFixtures on one date.
leagueNointegerUse 1 for World Cup.
seasonNoYYYY integerUse 2026 with league/team/player filters.
teamNointegerFixtures for one team.
lastNointeger, 2 digits maxLast N fixtures.
nextNointeger, 2 digits maxNext N fixtures.
fromNoYYYY-MM-DDStart date.
toNoYYYY-MM-DDEnd date.
roundNostringRound name from /fixtures/rounds.
statusNostatus code(s)Examples include NS, FT, or combined values such as 1H-HT-2H-ET-P-BT-LIVE.
venueNointegerVenue ID.
timezoneNostringTimezone from /timezone; default response dates are usable as UTC-aware timestamps.

Recommended World Cup call:

http
GET /fixtures?league=1&season=2026

Rounds

GET /fixtures/rounds

Use this as support data for match filtering and bracket navigation.

ParameterRequiredTypeUse
leagueYesintegerUse 1.
seasonYesYYYY integerUse 2026.
currentNotrue or falseReturn only active round.
datesNotrue or falseInclude round dates.
timezoneNostringDate timezone.

Players

GET /players

ParameterRequiredTypeUse
idNointegerPlayer ID.
teamNointegerTeam roster/player stats for a season.
leagueNointegerUse 1 for all World Cup players.
seasonConditionallyYYYY integerRequired with id, league, or team.
searchNostring, 4+ charsRequires league or team.
pageNointegerPagination page; default 1.

Recommended World Cup call:

http
GET /players?league=1&season=2026&page=1

Pagination continues until paging.current == paging.total.

Player Squads

GET /players/squads

Use this when a squad-first model is preferred over the stats-heavy /players response.

ParameterRequiredTypeUse
teamNointegerCurrent squad for a team.
playerNointegerTeams associated with a player.

At least one of team or player is required.

Match Events

GET /fixtures/events

ParameterRequiredTypeUse
fixtureYesintegerFixture ID.
teamNointegerFilter to one team.
playerNointegerFilter to one player.
typeNostringEvent type filter.

Event types documented by API-Football include goals, cards, substitutions, and VAR. Details include normal goal, own goal, penalty, missed penalty, yellow card, red card, goal cancelled, and penalty confirmed.

Recommended ingestion flow:

  1. Fetch all World Cup fixtures.
  2. For historical or scheduled refresh, call /fixtures/events?fixture=<id> per fixture.
  3. For live refresh, call /fixtures?live=all or /fixtures?league=1&season=2026&status=..., then batch detail calls with ids.

Implementation Notes

  • Proposed URI: api-football://?api_key=<key>&league=1&season=2026.
  • Default league=1 and season=2026 for the World Cup use case.
  • Support base_url for tests.
  • Use page pagination for /players.
  • For live matches, respect the documented 15-second update cadence but avoid polling faster than the selected plan allows.
  • Store API-Football IDs as provider IDs; do not try to normalize team/player IDs across services in the first connector.