Growing Discord community — direct access to the developer, live coverage & picks. Join the Discord Join now →
Matches Leagues Predictions The Edge Money News Stats Coverage
Docs / Football API free

Teams, players & transfers#

Teams#

GET /api/v2/teams/
Param Type Description
country_code string ISO country code, e.g. AR
league_id / season_id int Teams competing in a league/season
in_competition bool Only teams currently in an active competition
is_women bool Women's teams
name string Name search
limit / offset int Pagination
GET /api/v2/teams/{id}/           # profile: venue, coach, colours, country
GET /api/v2/teams/{id}/squad/     # current squad, ordered by position then shirt number
GET /api/v2/teams/{id}/fixtures/  # date_from, date_to, league_id, status
GET /api/v2/teams/{id}/social/    # curated tweets/videos (type filter)
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/api/v2/teams/755/fixtures/?status=upcoming&limit=5"

Squad availability#

Every player in the squad response carries their current availability:

Field Type Description
availability string available · injured · doubtful · suspended
injury_type string Reason, e.g. Knee Injury. Empty when available or unpublished
injury_expected_return date Expected return, or null

For an injured flag, test availability == "injured" — a boolean would fold doubtful and suspended into "not injured".

The status is refreshed several times a day from the team news published for each side's next fixture. available is the default value, so it means not currently listed as missing rather than confirmed fit, and a club with no upcoming fixture in a covered competition is not re-checked until it has one.

Players#

GET /api/v2/players/
Param Type Description
name string Name search
team_id int Current club
national_team_id int Current national-team squad
nationality_code string ISO code, e.g. AR
position string G · D · M · F
limit / offset int Pagination
GET /api/v2/players/{id}/                # bio, market value, skills
GET /api/v2/players/{id}/stats/          # per-match log — season_id, team_id, league_id, date_from/to
GET /api/v2/players/{id}/transfers/      # transfer history with fees
GET /api/v2/players/{id}/career/         # season-by-season summary
GET /api/v2/players/{id}/national-team/  # international record
GET /api/v2/players/{id}/social/         # tweets/videos

The full workflow with examples: Get a football player profile.

Transfers feed#

GET /api/v2/transfers/
Param Type Description
league_id int Either club has played in this league
player_id int One player's transfer history
team_id int In or out of this club
from_team_id / to_team_id int Direction-specific
date_from / date_to date Transfer date window
min_fee int Minimum fee (EUR)
has_fee bool Only transfers with a disclosed fee
ordering string Sort field, prefix - for descending

league_id takes the id from /api/v2/leagues/ and matches a transfer when either side of the move is a club from that league — so an Argentine club selling to Europe and buying from Europe both show up:

GET /api/v2/transfers/?league_id=85&limit=10

Unknown parameters are rejected. This endpoint answers 400 if you pass a filter it does not recognise, listing what it accepts. A typo like ?league=85 fails loudly instead of quietly returning the unfiltered global feed.

Note: the dataset includes forward-dated moves (announced loans/returns that haven't happened yet). For a "latest transfers" widget, always cap date_to at today.

Transfer ledger#

The feed answers who moved. The ledger answers what it cost.

GET /api/v2/transfers/ledger/?team_id=…
GET /api/v2/transfers/ledger/?league_id=…      # every club in the league, max 40
Param Type Description
team_id int One club. Mutually exclusive with league_id
league_id int Every club in that league
date_from date Window start (ISO)
date_to date Window end. Never reaches past today whatever you pass

Each club comes back with incoming and outgoing blocks — moves, how many were permanent, loans, free and undisclosed, the fees that were published, and the average age — plus gross_spend_eur, gross_income_eur, net_spend_eur, loan_dependency_pct, squad_size, turnover_pct, age_in and age_out.

Three things decide these numbers, and you should know them before quoting one:

Money only counts where a fee was published. A move with no figure lands in undisclosed, not as a zero. Summing the blanks as zeroes reports a tenth of what the big leagues actually spend. free is the separate, known case of a fee of nothing.

A loan return is not a signing. A player coming back from a loan is the same player returning to where he already belonged. Counting him as an arrival inflates the arrivals of every club that lends anyone out, and the raw feed gives you no warning that it happened.

turnover_pct is measured against today's squad. We do not keep historical squad sizes, so a long window can exceed 100%. That is not a bug — it means the club moved more players than it currently holds.

Transfer routes#

GET /api/v2/transfers/routes/?team_id=…&min_moves=3
Param Type Description
team_id / league_id int Scope, same rules as the ledger
date_from / date_to date Window
min_moves int Minimum moves for a pair to count (default 2)
limit int Default 50, max 200

The club pairs that repeat, ranked: moves, loans, fees_eur and up to five of the players who walked it.

Only moves with a real club at both ends are counted. "No team" is how the dataset spells free agency, not a destination, and it is excluded — without that it is the busiest route of almost every club on earth.

A club's own academy does count as a route, so the top line for a big club is often its own under-21s. That is the same question asked of the one feeder it controls.

World Cup squads#

GET /api/v2/worldcup/squads/              # team, group, status, has_player
GET /api/v2/worldcup/squads/{team_id}/

Tournament squad lists with per-player status — built for tournament hub pages.

Images#

Badges and photos come from ids, no extra calls: /img/team/{id}/, /img/player/{id}/?sor=true&bg=transparent — see Working with images.

View this page as Markdown · Found a mistake? Tell us