# AI Sports Predictions API > Football data and AI match analysis in one API: fixtures, league coverage and standings, team and player statistics, squads, team comparison, injuries, lineups, head-to-head history, betting odds, AI match analysis and a daily ticket. Base URL: https://aisportspredictionsapi-production.up.railway.app OpenAPI spec: https://aisportspredictionsapi-production.up.railway.app/v3/api-docs/public ## Getting started 1. Get an API key. A free plan is available. 2. Send it on every request in the x-api-key header. 3. Start with `GET /fixtures` for today's matches. The fixture, team and league ids in the response are the keys you reuse across every other endpoint. ## How responses work Every data endpoint returns the same envelope. The one exception is `GET /daily-ticket/stats`, which returns a plain summary object. - parameters: the filters you sent - results: the number of items returned - errors: why a request produced no data, such as a missing filter or an unknown id - response: the data itself Most invalid filters do not produce an HTTP error status. The call returns 200 with results 0 and a populated errors array, so check errors before reading response. The cases that do return 400 are listed under Errors below. All match dates are ISO-8601 in UTC, with a matching unix timestamp field. ## Coverage and freshness The API covers the current season of 30 competitions across 8 countries: the major European leagues and domestic cups, the main international tournaments (World Cup and its qualifiers, Euro, Nations League, Champions League, Europa League, Conference League, Club World Cup) and the top divisions of Brazil, Argentina, the USA and Mexico. `GET /leagues` returns the full list with the league ids and country codes to filter by, read from our database, so it always matches what the API actually serves. Match data spans a rolling one-week window: the current day plus the next 6 days, with the last 2 days of finished matches still available. Anything older is removed. The daily ticket keeps 30 days of history. | Data | Updated | |---|---| | Live scores and match status | every 5 minutes | | Starting lineups | every 5 minutes on match day, published once official, typically 20 to 40 minutes before kickoff | | Betting odds | hourly for upcoming matches | | Standings | daily | | Fixtures, injuries, squads, team and player statistics, head-to-head | daily | | AI match analysis | refreshed as the underlying data updates, including a new pass once official lineups are announced | | Daily ticket | published on days whose fixtures offer safe enough picks; each leg settles within 30 minutes of its match finishing | ## MCP server The same football tools are also exposed over the Model Context Protocol, for use from an MCP-compatible AI client or agent such as Claude Desktop, Claude Code or Cursor. No integration code is needed. Point the client at the streamable-HTTP endpoint `POST /mcp` and send your API key in the `x-api-key` header, exactly as for REST. Each tool call counts as one request against the same per-plan quota. Most tools accept team names and resolve the ids internally, so "analysis for France vs Spain" is a single tool call. Free-plan tools: - `search_teams`: find teams by full or partial name and get their ids. - `get_leagues`: the covered leagues, optionally filtered by country. - `get_fixtures`: matches by league, team or date. - `get_team_next_match`: a team's next scheduled match, by team name. - `get_match_analysis`: the full AI analysis of one match, by fixture id or team names. Subject to the plan's analysis cap, see Rate limits below. - `get_standings`: the current league table for a competition. - `get_head_to_head`: past meetings between the two teams of a match. - `get_odds`: pre-match betting odds for a match. - `get_lineups`: starting elevens, substitutes and formations for a match, by fixture id or team names. - `get_injuries`: injuries and suspensions for a match or a team. - `get_squad`: a team's current squad, by team name. - `get_team_statistics`: season form and performance numbers for both teams of a match, by fixture id or team names. - `get_player_statistics`: players' season statistics, by player, team or fixture. - `get_team_comparison`: strength comparison of the two teams of a match, by fixture id or team names. Paid-plan tools: - `get_today_analyses`: every analysed match scheduled for today. - `get_daily_ticket`: the day's accumulator. Omit the date for today, or pass a date up to 30 days back. - `get_daily_ticket_history`: previously published tickets, newest first. - `get_daily_ticket_stats`: the win-rate track record. ## Rate limits Every plan enforces a daily and a per-minute quota, counted per API key and shared across REST and MCP. | Plan | Requests per day | Requests per minute | AI analyses per day | |---|---|---|---| | Free | 100 | 10 | 2 | | Professional | unlimited | 300 | unlimited | Exceeding a quota returns `429`. The per-minute allowance refills continuously over the minute; the daily allowance resets every 24 hours. On a 429, back off briefly and retry, or upgrade the plan for a higher allowance. Where a plan carries a separate analysis cap, it applies to the single-match AI analysis, meaning `GET /predict` and the `get_match_analysis` MCP tool. Each analysis also counts as one normal request. ## Errors - `400`: a required parameter is missing (fixture on `GET /predict`, league on `GET /standings`), or a daily-ticket argument is out of range. `GET /daily-ticket/history` rejects a single date bound, an inverted range and a span longer than 30 days; `GET /daily-ticket/stats` rejects a days value outside 1 to 30. - `401`: missing or invalid API key. - `403`: the plan does not include this endpoint. `GET /predict/today` and the daily ticket require a paid plan. The single-match AI analysis (`GET /predict`) is available on every plan. - `429`: rate limit exceeded, see Rate limits above. ## Endpoints ### Fixtures Football matches: kickoff details, competition, the two teams, goals and scores. These endpoints return match data only, without the AI analysis. For the written preview, recommended bets and success percentages, use the Predictions endpoints. Coverage spans the current day and the next 6 days, plus matches that finished in the last 2 days. Older matches are removed and cannot be retrieved. #### GET /fixtures List fixtures Matches selected by one main filter. At least one is required: - leagueId: every match in a competition. - teamId: every match a given team plays. - date: every match played on a single calendar day, across all competitions. leagueId and teamId cannot be combined with each other. date can be added on top of either one to narrow that league or team to a single day. Two optional refinements: - status: keep only matches in a given state, for example NS (not started), FT (finished) or LIVE (in play). - round: keep only one round of a competition. Valid only together with leagueId. Results cover the current day and the next 6 days, plus matches finished in the last 2 days. Match data only, no AI analysis. Each match carries a stable fixture `id` for the single-fixture endpoint, statistics, lineups and predictions. Parameters: - `leagueId` (query, integer, optional): League id. Returns every match in that competition. May be combined with date, round and status. Cannot be combined with teamId. - `teamId` (query, integer, optional): Team id. Returns every match that team plays. May be combined with date and status. Cannot be combined with leagueId. - `date` (query, string, optional): Single calendar day in YYYY-MM-DD format. On its own returns every match played that day across all competitions; combined with leagueId or teamId it narrows that league or team to the given day. - `status` (query, string, optional): Optional match state filter. One of: NS, TBD, 1H, HT, 2H, ET, BT, P, SUSP, INT, FT, AET, PEN, PST, CANC, ABD, AWD, WO, LIVE. - `round` (query, string, optional): Optional competition round (e.g. "Regular Season - 38"). Only valid together with leagueId. #### GET /fixtures/{id} Get a single fixture by id One match by its fixture id, in full detail: kickoff time and status, the competition, both teams, goals and the score broken down by period. Match data only, without the AI analysis. The `id` in the response is stable and can be reused to query that match's statistics, lineups and predictions. Parameters: - `id` (path, integer, required): Unique fixture id of the match you want. ### Leagues The football leagues covered by the API, as a list or one at a time by id. #### GET /leagues List covered leagues The leagues available through the API. Start here to see which competitions you can build on. - Call without a filter for the full list. - Pass country to narrow it to one country, for example `GB` for England, `IT` for Italy or `ES` for Spain. The accepted codes are listed on the `country` parameter below. They are two letters, except `WORLD` for international competitions and `SCO` for Scotland. Each league carries a stable `id`, its `country` as name and filterable code, and the `currentSeason` in play. Reuse the `id` for standings, fixtures and predictions. This endpoint is the coverage list. It is served from our database and reflects the competitions tracked right now, so an unfiltered call answers exactly what the API covers. An uncovered country code returns 200 with an empty `response` and the reason in `errors`. Parameters: - `country` (query, string, optional). One of: DE, ES, FR, GB, IT, NL, PT, RO, WORLD: Country code (case-insensitive; two letters, e.g. `GB`), or `WORLD` for international competitions and `SCO` for Scotland. Returns only the leagues played in that country. Omit it to list every covered league. #### GET /leagues/{id} Get a league by id One league by its stable `id`, the same id returned by the list endpoint. Returns the league's name, type, logo, country and current season. An id the API does not cover returns 200 with an empty `response` and the reason in `errors`. Parameters: - `id` (path, integer, required): Stable league id, as returned by the list endpoint. ### Standings League tables: the full standings of a competition, or a single team's row. #### GET /standings Get league standings The current table for a competition. Each row carries the team's `rank`, `points`, goal difference, recent `form` and its played, won, drawn and lost record split into overall, home and away. - Pass league on its own for every team's row, sorted by rank. Competitions played in several groups are returned as separate tables. - Add team to narrow the result to that team's row. The `league` id comes from `GET /leagues`. Each returned team `id` can be reused for fixtures and predictions. A league or team with no table returns 200 with an empty `response` and the reason in `errors`. A missing `league` parameter returns 400. Parameters: - `league` (query, integer, required): League id whose table you want, as returned by `GET /leagues`. Required. - `team` (query, integer, optional): Optional team id. When set, the response is narrowed to that single team's row within the league instead of the whole table. ### Predictions AI match analysis: a written preview, per-market win probabilities and betting tips. Analyses are produced only for fixtures on the current day. Going further ahead would mean working without the late information that decides a match, such as confirmed lineups, last-minute injuries and team news, so a prediction made days in advance would not hold up. For the same reason an analysis is refreshed as new data lands during the day. The most reliable version is the one built after the starting lineups are confirmed. The `lineupUsed` field tells you which of the two you are reading. #### GET /predict Get the AI analysis for a single fixture The full AI analysis of one fixture. Alongside the fixture, league, teams, goals and score, the `analysis` block holds: - matchSummary, formAnalysis, injuryImpact and riskAssessment, all in plain language. - keyInsights: the factors most likely to decide the match. - marketProbabilities: one entry per betting market, listing every selection with its odd and an estimated probability from 0 to 100, the recommended pick, a short justification for the market and a HIGH, MEDIUM or LOW confidence grade. - tips graded by appetite: safeBet, balancedBet, boldBet, a valueBet where the bookmaker looks mispriced, and a recommendedBet that is always present. Pass the `fixture` id from `GET /fixtures`. Analyses exist only for fixtures on the current day, so a match scheduled later has none yet. A fixture with no analysis returns 200 with an empty `response` and the reason in `errors`. A missing `fixture` parameter returns 400. Plans that carry a daily analysis cap return 429 once it is used up. The cap of each plan is in the Rate limits section of the introduction. Parameters: - `fixture` (query, integer, required): Fixture id to analyse, as returned by `GET /fixtures`. Required. #### GET /predict/today Browse today's AI analyses (paid plan) Every analysed fixture scheduled for today in one call, each carrying the same `analysis` block as `GET /predict`. Today is resolved in UTC, the same timezone every fixture date is returned in, so convert to local time as needed. With no filters you get the complete slate for the day. - status: keep only fixtures not yet started (NS) or already finished (FT). - league: keep only fixtures from one competition, id from GET /leagues. - team: keep only fixtures involving one team, id from GET /teams. - country: keep only fixtures from one country, given as the short code returned in countryCode by GET /leagues, for example GB, IT or ES. - lineupUsed: true returns only analyses built on confirmed starting lineups, false returns the earlier ones. `league` and `country` cannot be combined, since a league already fixes its country. Sending both returns 200 with the clash described in `errors`. Requires a paid plan. When no fixture matches, the call returns 200 with an empty `response` and the reason in `errors`. Parameters: - `status` (query, string, optional): Keep only fixtures with this status: `NS` (not started) or `FT` (finished). Omit to include every status. - `league` (query, integer, optional): Keep only fixtures from this competition, as returned by `GET /leagues`. Cannot be combined with country. - `team` (query, integer, optional): Keep only fixtures involving this team, as returned by `GET /teams`. - `country` (query, string, optional): Keep only fixtures from this country, given as its short code (e.g. `GB`, `IT`, `ES`) as returned in `countryCode` by `GET /leagues`. Cannot be combined with league. - `lineupUsed` (query, boolean, optional): `true` returns only analyses based on confirmed starting lineups; `false` returns the pre-lineup ones. Omit to include both. ### Daily Ticket A ready-made accumulator of the day's safest picks, each leg justified and combined into a single set of odds. Get today's ticket, look one up by date, browse the history and check the track record. All four endpoints require a paid plan. #### GET /daily-ticket Get today's daily ticket Today's accumulator: the selected legs, each with its match, kickoff, market, pick, odds and a short justification, plus the combined odds for the whole ticket. Every leg also carries live match state, refreshed on each call: `status` and `statusLong` (NS before kickoff, 1H / HT / 2H while playing, FT once over), `elapsed` for the minute being played, and `homeGoals` / `awayGoals` for the score so far. Each leg carries a `result` and the ticket a `status` of PENDING, WON, LOST or VOID. Both fill in as the matches finish, so the same ticket reflects progress through the day. Kickoff is given both as `kickoff`, an ISO date-time in UTC, and as `kickoffTimestamp` in epoch seconds, so it can be rendered in any time zone. A ticket is not published every day. When none is available the call returns 200 with `results` 0, a null `response` and the reason in `errors`. Takes no parameters. #### GET /daily-ticket/history List past daily tickets Previously published tickets, newest first, each with its legs, their kickoff times and final scores, and the ticket's final settlement status. - Pass both from and to for an inclusive date range of at most 30 days. - Omit both to get the full retained history, which is the last 30 days. - Add status, WON or LOST, to keep only winning or losing tickets. Works on its own or together with the date range. Provide either both date bounds or neither. A single bound, an inverted range or a span longer than 30 days returns 400. Parameters: - `status` (query, string, optional). One of: WON, LOST: Keep only tickets with this final outcome: WON or LOST. Omit to return both. - `from` (query, string, optional): Start of the range (inclusive), ISO date yyyy-MM-dd. Must be paired with 'to'. - `to` (query, string, optional): End of the range (inclusive), ISO date yyyy-MM-dd. Must be paired with 'from'. #### GET /daily-ticket/stats Get the recent track record Performance summary over a recent window: how many tickets were published, won, lost, voided and are still pending, plus `winRatePercent` computed over settled tickets only, as won / (won + lost). This is the one endpoint that does not use the standard envelope. It returns the summary object directly. A `days` value outside 1 to 30 returns 400. Parameters: - `days` (query, integer, optional): Size of the look-back window in days, from 1 to 30. Defaults to 30. #### GET /daily-ticket/{date} Get the daily ticket for a date The ticket published on a specific date, in the same shape as today's ticket. A date with no published ticket returns 200 with `results` 0, a null `response` and the reason in `errors`. History goes back 30 days. Parameters: - `date` (path, string, required): The ticket date, ISO date yyyy-MM-dd. ### Teams Football teams and their identity data: id, name and crest logo. #### GET /teams Find football teams Teams found in one of three ways. Use exactly one filter per request: - team: the exact team id, when you already know which team you want. - search: a full or partial club name. "manch" finds Manchester City and Manchester United. Case-insensitive, returns up to 20 matches ordered alphabetically. - league: every team competing in that league this season. The league filter is built from the competition's table, so it returns nothing for cup competitions and other formats that have no standings. For those, find the teams through `GET /fixtures` instead. Each team carries a stable `id` for fixtures, standings, statistics and predictions. Parameters: - `team` (query, integer, optional): Exact team id, when you already know which team you want. - `search` (query, string, optional): Full or partial team name. Case-insensitive, returns up to 20 alphabetical matches. - `league` (query, integer, optional): League id. Returns every team competing in that league this season. Works only for competitions that have a table. ### Team Statistics Season-to-date team form and performance numbers, as they stood for a given match. #### GET /teams/statistics Get team statistics for a match Aggregated season statistics for the teams of a match: form string, fixtures played, won, drawn and lost split by home and away, goals scored and conceded with over/under breakdowns, biggest streaks and wins, clean sheets, penalties and card totals. - fixture is required and returns both teams, home side first. - team is optional and narrows the result to that one team. The numbers describe each team's season up to that match, which is what you compare when judging home and away records or over/under tendencies. Parameters: - `fixture` (query, integer, optional): Match id to pull statistics for. Required. Returns both teams unless narrowed by team. - `team` (query, integer, optional): Team id. Optional filter that narrows the result to this single team within the match. ### Team Comparison The two teams of a match compared across the strength indicators that feed a prediction: current form, attack, defence, goal expectancy and head-to-head record. Each indicator is a home against away split, so it is readable at a glance before the full AI analysis. #### GET /comparison Compare the two teams of a fixture A strength comparison of the two teams of a match, taken by fixture id. Every indicator is a paired `home` and `away` value, usually a percentage: - form: recent results momentum. - att: attacking strength. - def: defensive solidity. - poisson_distribution: modelled goal expectancy. - h2h: historical balance of their past meetings. - goals: balance of goals scored against goals conceded. - total: overall combined rating. The `fixture` parameter is required. Parameters: - `fixture` (query, integer, optional): Unique fixture id of the match whose two teams you want compared. ### Squad A team's current squad: the full player list with shirt number, age and position. #### GET /squad Get a team's squad The current squad of one team: every player with their `id`, name, age, shirt number, position and photo, alongside the team's own `id`, name and crest logo. The `team` parameter is required. A missing `team`, or a team with no squad on file, returns 200 with an empty `response` and the reason in `errors`. Each player `id` can be reused for player statistics, and the team `id` for that team's fixtures, standings and statistics. Parameters: - `team` (query, integer, optional): Id of the team whose squad you want. Required. ### Players Players' season statistics, grouped by team. #### GET /players Get player season statistics Season statistics for players, grouped by team. Each player entry carries the player's profile and their statistic rows: appearances, goals, assists, passing, shots, tackles, duels, dribbles, fouls, cards, penalties and more. Use exactly one filter per request: - id: every statistic row for a single player. - team: all players belonging to that team. - fixture: all players of both teams taking part in that match. The figures are season aggregates, not single-match numbers. Parameters: - `id` (query, integer, optional): Exact player id. Returns every statistic row for that single player. - `team` (query, integer, optional): Team id. Returns the season statistics of all players in that team. - `fixture` (query, integer, optional): Fixture id. Returns the players of both teams taking part in that match. ### Lineups Starting elevens, substitutes and formations for a specific match. #### GET /fixtures/{id}/lineups Get match lineups The team sheets of one match, taken by fixture id. The response holds one entry per team with the team identity, the head `coach`, the `formation` played such as `4-3-3`, the `startXI` and the `substitutes`. Every player comes with a shirt number and a pitch position, enough to rebuild the full setup of both sides. Lineups become official shortly before kickoff, typically 20 to 40 minutes ahead, and are picked up within 5 minutes of publication. A match that has not released them yet returns 200 with an empty `response` and the reason in `errors`. Parameters: - `id` (path, integer, required): Match id whose lineups you want, as returned by `GET /fixtures`. ### Injuries Player injuries and suspensions for an upcoming match or a team. #### GET /injuries Get injuries and suspensions The players unavailable through injury or suspension, with the reason and their availability status. Call it in one of three ways: - fixture: every reported absentee for both teams in that match. - team: the current injury list for a single team. - fixture and team together: only that team's absentees in that match. At least one filter is required. Each item carries the player, their team, the related fixture and league, and the reason and type of the absence. The player and team ids can be reused for squads and statistics. Injuries are collected for the current day's fixtures, since they go stale within hours. No filter, or no matching absentees, returns 200 with an empty `response` and the reason in `errors`. Parameters: - `fixture` (query, integer, optional): Fixture (match) id. Returns every reported absentee for both teams in that match. - `team` (query, integer, optional): Team id. Returns the current injury and suspension list for that team. Can be combined with fixture to narrow the result to one team in a match. ### Head-to-Head The past meetings between the two teams of a match, each with kickoff details, competition, goals and final score. #### GET /fixtures/{id}/h2h Get head-to-head history for a fixture The earlier meetings between the two teams of a match, taken by fixture id and ordered from oldest to most recent. Each past meeting carries the same detail as a fixture: kickoff time and status, the competition, both teams, goals and the score breakdown. Match history only, without the AI analysis. Every returned match has a stable fixture `id` for statistics, lineups and predictions. Parameters: - `id` (path, integer, required): Fixture id of the match whose two teams you want the history for. ### Odds Pre-match betting odds for a fixture, grouped by betting market. #### GET /odds Get betting odds for a fixture The pre-match betting odds available for one fixture, grouped by market. The `fixture` id is the same one returned by the fixtures and predictions endpoints. - league: the competition the fixture belongs to. - fixture: the match the odds apply to. - markets: the betting markets, such as Match Winner, Over/Under or Both Teams To Score. - values: inside each market, every selection with its decimal odd, such as Home, Draw and Away. Odds are refreshed hourly for upcoming matches and are not published for matches that have already started. A missing `fixture`, or a fixture with no odds, returns 200 with `results` 0 and the reason in `errors`. Parameters: - `fixture` (query, integer, optional): Id of the fixture to fetch odds for. Required.