---
title: "Title forecasts from Monte Carlo simulations"
method: GET
path: "/v1/simulations/{sport}"
tags: ["simulations"]
---

# Title forecasts from Monte Carlo simulations

`GET /v1/simulations/{sport}`

## Request

- Base URL: `https://api.predixsport.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.predixsport.com/v1/simulations/{sport}`
- Auth: none declared

Latest forecast snapshot per active event. Tennis (ATP) and wta (women's tennis): each player carries `p_title` (share of 20,000 simulated tournaments won) and `p_reach` per round. NBA: each team carries `p_champion` (share of 10,000 simulated seasons won) and `p_reach` per stage (play-in, playoffs, conference semifinals/finals, finals, champion), plus a predicted playoff `bracket` with per-series win probabilities and series-score distributions (4-0 … 4-3). EuroLeague: each club carries `p_champion` (share of 10,000 simulated seasons won) and `p_reach` per stage (play-in, playoffs, final_four, finals, champion), plus the predicted `bracket` — Play-In, best-of-5 quarterfinals (3-0 … 3-2) and the neutral-site Final Four. Football: one forecast per domestic league across 12 leagues — 5 top flights (Serie A, Premier League, La Liga, Bundesliga, Ligue 1) and 7 second divisions (Championship, League One, League Two, Segunda División, Ligue 2, 2. Bundesliga, Serie B) — each club carries `p_champion`, expected final points/position (`expected_points`, `mean_rank`) and `p_reach` per TABLE BAND (top flights: champions_league, europa_league, relegation, plus relegation_playoff where the league has the slot; second divisions: auto_promotion, playoff_win, promoted, relegation, barrage_up/down where the format has them). Band sizes in `structure` (integer bands) and `structure_detail` (second-division seed/format layout). Football seasons are sampled as full scorelines, so draws and goal difference are modelled; there is no bracket — the final league table IS the outcome. Champions League: one forecast per season — each club carries `p_champion`, expected league-phase points/position (`expected_points`, `mean_rank`, both CONDITIONAL on reaching the league phase) and `p_reach` per stage on the fixed Swiss ladder (`playoff`, `top8`, `r16`, `quarter`, `semi`, `final`, `champion`). `playoff` means reached the knockout play-off round OR BETTER — a top-24 league-phase finish, so it includes the clubs that finish top 8 and skip it, and `playoff` >= `r16` always; `top8` is the separate direct-entry branch and is a subset of `r16`. Read `mode` and `provisional` before the numbers: on a `pre_draw` board (July/August, before UEFA's draw) the FIELD ITSELF is simulated, so `teams` covers the whole entrant universe — confirmed clubs plus clubs still playing qualifying, split by `entrant_status` and priced with `p_league_phase` — and is larger than 36; on a `fixtures` board it is the 36 drawn clubs with played matches pinned. Forecasts refresh on every prediction run: completed games are locked in and the remainder is re-simulated, so probabilities sharpen continuously. Snapshots older than `days` are considered archived and excluded.

## Path parameters

- `sport` 'nba' | 'euroleague' | 'football' | 'tennis' | 'wta' | 'champions', required

## Query parameters

- `tournament` string: Tennis / WTA only: narrow to one tournament slug (e.g. `stuttgart`, `roland_garros`). Ignored for NBA and EuroLeague (one season-level forecast).
- `league` 'serie_a' | 'premier_league' | 'la_liga' | 'bundesliga' | 'ligue_1' | 'championship' | 'league_one' | 'league_two' | 'segunda_division' | 'ligue_2' | 'bundesliga_2' | 'serie_b'
- `days` integer: Freshness window in days on the forecast snapshot date.
- `team` string: Football and NBA: narrow the per-team rows to one club or franchise — football accepts the stored short name (`Man United`), display name (`Manchester United`) or slug (`manchester-united`); NBA accepts the franchise name (`Boston Celtics`) or slug (`boston-celtics`). Ignored for other sports.

## Headers

- `authorization` string, nullable

## Response `200`

Successful Response

- union
  - TennisSimulationsResponse
    - `sport` 'tennis'
    - `count` integer, required: Number of tournaments returned.
    - `tournaments` TennisTournamentSimulation[], required
      - `tournament` string, required: Tournament slug (e.g. `stuttgart`).
      - `season` string, required: Season, 4-digit year for tennis.
      - `tournament_type` string, nullable: ATP: grand_slam | masters_1000 | atp_500 | atp_250. WTA: grand_slam | wta_1000 | wta_500 | wta_250.
      - `surface` string, nullable: hard | clay | grass.
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per day.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `n_simulations` integer, nullable: Number of simulated tournaments behind the probabilities.
      - `n_rounds` integer, nullable: Bracket depth (rounds).
      - `n_completed_rounds` integer, nullable: Fully decided rounds at forecast time.
      - `is_completed` boolean: True once the tournament has a champion.
      - `champion` string, nullable: Champion name, when the tournament is finished.
      - `players` TennisPlayerForecast[]: Sorted by p_title descending.
        - `player` string, required: Player display name.
        - `seed` integer, nullable: Seeding, when seeded.
        - `country` string, nullable: Country code as observed in the draw.
        - `qualifier_slot` boolean: True when this entry is an undetermined qualifier slot priced with field-average ratings rather than a known player.
        - `p_title` number, required: Probability of winning the tournament — the share of simulated tournaments this player won.
        - `p_reach` object: Probability of reaching each round, keyed by round name (e.g. {"Quarterfinals": 0.61, "Final": 0.18, "title": 0.07}). 1.0 = already there / guaranteed; 0.0 = eliminated.
        - `expected_wins` number, nullable: Expected number of matches won from here (simulation mean).
        - `rounds_won` integer, nullable: Matches already won in this draw (byes included).
        - `eliminated` boolean: True once the player is out of the tournament.
        - `atp_id` string, nullable: ATP player code (e.g. `S0AG`) — stable join key across endpoints.
  - WTASimulationsResponse
    - `sport` 'wta'
    - `count` integer, required: Number of tournaments returned.
    - `tournaments` WTATournamentSimulation[], required
      - `tournament` string, required: Tournament slug (e.g. `stuttgart`).
      - `season` string, required: Season, 4-digit year for tennis.
      - `tournament_type` string, nullable: ATP: grand_slam | masters_1000 | atp_500 | atp_250. WTA: grand_slam | wta_1000 | wta_500 | wta_250.
      - `surface` string, nullable: hard | clay | grass.
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per day.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `n_simulations` integer, nullable: Number of simulated tournaments behind the probabilities.
      - `n_rounds` integer, nullable: Bracket depth (rounds).
      - `n_completed_rounds` integer, nullable: Fully decided rounds at forecast time.
      - `is_completed` boolean: True once the tournament has a champion.
      - `champion` string, nullable: Champion name, when the tournament is finished.
      - `players` WTAPlayerForecast[]: Sorted by p_title descending.
        - `player` string, required: Player display name.
        - `seed` integer, nullable: Seeding, when seeded.
        - `country` string, nullable: Country code as observed in the draw.
        - `qualifier_slot` boolean: True when this entry is an undetermined qualifier slot priced with field-average ratings rather than a known player.
        - `p_title` number, required: Probability of winning the tournament — the share of simulated tournaments this player won.
        - `p_reach` object: Probability of reaching each round, keyed by round name (e.g. {"Quarterfinals": 0.61, "Final": 0.18, "title": 0.07}). 1.0 = already there / guaranteed; 0.0 = eliminated.
        - `expected_wins` number, nullable: Expected number of matches won from here (simulation mean).
        - `rounds_won` integer, nullable: Matches already won in this draw (byes included).
        - `eliminated` boolean: True once the player is out of the tournament.
        - `wta_id` string, nullable: WTA player id — stable join key across endpoints.
  - NBASimulationsResponse
    - `sport` 'nba'
    - `count` integer, required: Number of season forecasts returned.
    - `seasons` NBASeasonSimulation[], required
      - `season` string, required: Season by ending year (`2026` = 2025-26).
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per day.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `n_simulations` integer, nullable: Number of simulated seasons behind the probabilities.
      - `rs_complete` boolean: Regular season fully played.
      - `play_in_complete` boolean: Play-in tournament decided.
      - `is_completed` boolean: True once the season has a champion.
      - `champion` string, nullable: Champion franchise, when the season is finished.
      - `teams` NBATeamForecast[]: Sorted by p_champion descending.
        - `team` string, required: Full franchise name (e.g. `Boston Celtics`).
        - `conference` string, nullable: East | West.
        - `wins` integer, nullable: Regular-season wins to date.
        - `losses` integer, nullable: Regular-season losses to date.
        - `expected_rs_wins` number, nullable: Expected final regular-season wins (simulation mean).
        - `p_champion` number, required: Probability of winning the NBA title — the share of simulated seasons this team won.
        - `p_reach` object: Probability of reaching each stage, keyed by stage name (e.g. {"playoffs": 0.94, "conf_finals": 0.31, "champion": 0.12}; `play_in` = entering the play-in tournament). 1.0 = already there / guaranteed; 0.0 = ruled out.
        - `eliminated` boolean: True only on pinned facts: the team lost an observed playoff series or sits outside a decided playoff field.
      - `bracket` object, nullable: Predicted playoff bracket. Per conference and round, each series slot lists the most likely matchups with the probability the matchup occurs (`p`), each side's probability of winning the series (`win`), and the series score distribution (`scores`, e.g. `"4-1": 0.32` = wins the series 4-1 in 32% of the simulations where the matchup happens). Observed real series carry a `pinned` state.
  - EuroLeagueSimulationsResponse
    - `sport` 'euroleague'
    - `count` integer, required: Number of season forecasts returned.
    - `seasons` EuroLeagueSeasonSimulation[], required
      - `season` string, required: EuroLeague season code (`E2025` = the 2025-26 season).
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per day.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `n_simulations` integer, nullable: Number of simulated seasons behind the probabilities.
      - `rs_complete` boolean: Regular season (double round-robin) fully played.
      - `play_in_complete` boolean: Play-in round decided.
      - `is_completed` boolean: True once the season has a champion.
      - `champion` string, nullable: Champion club name, when the season is finished.
      - `champion_code` string, nullable: Champion club code, when the season is finished.
      - `teams` EuroLeagueTeamForecast[]: Sorted by p_champion descending.
        - `team` string, required: Full club name (e.g. `Real Madrid`).
        - `team_code` string, required: Three-letter EuroLeague club code (e.g. `MAD`).
        - `wins` integer, nullable: Regular-season wins to date.
        - `losses` integer, nullable: Regular-season losses to date.
        - `expected_rs_wins` number, nullable: Expected final regular-season wins (simulation mean).
        - `p_champion` number, required: Probability of winning the EuroLeague title — the share of simulated seasons this club won.
        - `p_reach` object: Probability of reaching each stage, keyed by stage name (`play_in`, `playoffs`, `final_four`, `finals`, `champion`; e.g. {"playoffs": 0.88, "final_four": 0.34, "champion": 0.08}). `play_in` = entering the play-in round. 1.0 = already there / guaranteed; 0.0 = ruled out.
        - `eliminated` boolean: True only on pinned facts: the club lost an observed series or sits outside a decided bracket.
      - `bracket` object, nullable: Predicted post-season bracket, keyed by slot id: `pi:a` / `pi:b` / `pi:c` (Play-In single games), `qf:1v8` / `qf:4v5` / `qf:3v6` / `qf:2v7` (best-of-5 quarterfinals), `ff:semi1` / `ff:semi2` and `ff:final` (neutral-site Final Four single games). Each slot lists the most likely matchups with the probability the matchup occurs (`p`), each side's win probability (`win`), and — for the best-of-5 quarterfinals only — the series-score distribution (`scores`, e.g. `"3-1": 0.28` = wins the series 3-1 in 28% of the simulations where the matchup happens). Team entities are full club names. Observed real games/series carry a `pinned` state.
  - FootballSimulationsResponse
    - `sport` 'football'
    - `count` integer, required: Number of league forecasts returned.
    - `leagues` FootballLeagueSimulation[], required
      - `league` string, required: League code. 12 leagues: 5 top flights (`serie_a`, `premier_league`, `la_liga`, `bundesliga`, `ligue_1`) and 7 second divisions (`championship`, `league_one`, `league_two`, `segunda_division`, `ligue_2`, `bundesliga_2`, `serie_b`).
      - `league_name` string, required: Display name (e.g. `Serie A`).
      - `season` string, required: Season code (`2025_2026` = 2025-26).
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per run.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `n_simulations` integer, nullable: Number of simulated seasons behind the probabilities.
      - `n_remaining` integer, nullable: League fixtures still to be played at snapshot time.
      - `season_complete` boolean: Every league fixture has been played.
      - `is_completed` boolean: True once the season has a champion.
      - `champion` string, nullable: Champion club name, when the season is finished.
      - `structure` object: Integer band sizes used for this forecast. Top flights key this on qualification/relegation, e.g. {"champions_league": 4, "europa_league": 2, "relegation": 3, "relegation_playoff": 0} (counts follow each league's real format and UEFA allocation). Second divisions carry the integer promotion/relegation band sizes here, e.g. {"auto_promotion": 2, "relegation": 3, "playout_max_gap": 3}; their playoff/play-out/barrage seed ranges and playoff format (non-integer values) live in `structure_detail`.
      - `structure_detail` object, nullable: Second-division-only: the full promotion/relegation format layout when it cannot be expressed as plain integer band sizes. Present for second divisions, null for top flights. Keys: `auto_promotion` (int), `playoff_seeds` ([lo, hi] table positions entering the promotion playoff, or null), `playoff_format` (e.g. `two_leg_final`, `serie_b`), `relegation` (int), `playout_seeds` ([lo, hi] for a relegation play-out, or null), `playout_max_gap` (int or null), `barrage_up_seeds` / `barrage_down_seeds` (promotion/relegation barrage position pairs, or null). Additive — read only the keys present.
      - `teams` FootballTeamForecast[]: Sorted by mean simulated final position (best first).
        - `team` string, required: Club name (e.g. `Inter`, `Man City`).
        - `played` integer, nullable: League matches played to date.
        - `points` integer, nullable: League points to date.
        - `wins` integer, nullable: Wins to date.
        - `draws` integer, nullable: Draws to date.
        - `losses` integer, nullable: Losses to date.
        - `goal_diff` integer, nullable: Goal difference to date.
        - `expected_points` number, nullable: Expected FINAL league points (simulation mean).
        - `expected_goal_diff` number, nullable: Expected final goal difference (simulation mean).
        - `mean_rank` number, nullable: Mean simulated final league position (1 = champion).
        - `p_champion` number, required: Probability of winning the league title — the share of simulated seasons this club finished first.
        - `p_reach` object: Probability of finishing in each table band, keyed by band name. Which bands are present depends on the league's format. Top flights: `champion`, `champions_league`, `europa_league`, `relegation`, plus `relegation_playoff` where the slot exists. Second divisions carry promotion bands instead: `champion`, `auto_promotion`, `playoff_zone`, `playoff_final`, `playoff_win`, `promoted`, `relegation`, `playout_zone`, `relegated_total`, `barrage_up`, `barrage_down` — again only those the league's format defines (e.g. {"auto_promotion": 0.41, "playoff_win": 0.12, "relegation": 0.0}). Band sizes are in the league-level `structure`.
  - ChampionsSimulationsResponse
    - `sport` 'champions'
    - `count` integer, required: Number of season forecasts returned.
    - `seasons` ChampionsSeasonSimulation[], required
      - `season` string, required: UEFA season year, which is the season ENDING year: `2027` = the 2026-27 campaign.
      - `season_label` string, required: Human-readable season (`2026-27`).
      - `run_date` string, required: Forecast snapshot date (YYYYMMDD). One snapshot per day.
      - `generated_at` string, nullable: Exact forecast generation timestamp (ISO 8601).
      - `mode` string, required: Which branch produced this board, and therefore how to read it. `pre_draw` (July/August): the league-phase draw does not exist yet, so the field itself is simulated — `teams` covers the whole entrant universe (confirmed clubs PLUS clubs still in qualifying, see `entrant_status`), typically well over 36 rows. `fixtures` (late August onwards): the real draw is known, played matches are pinned at their real scores and only the remainder is sampled — 36 rows, all confirmed.
      - `provisional` boolean: True while the FIELD is not final (i.e. on every `pre_draw` board). Not a data-quality flag: the probabilities are complete and already integrate over who wins the remaining qualifying ties. It tells you the club list can still change.
      - `status` string, nullable: Engine status string: `PROVISIONAL`, `LIVE` (league phase in progress) or `LEAGUE_PHASE_COMPLETE`. Prefer the typed `mode` and `provisional` fields for logic.
      - `n_simulations` integer, nullable: Number of simulated seasons behind the probabilities.
      - `n_scenarios` integer, nullable: Provisional forecasts only: distinct qualifying scenarios sampled (each is then played out over several simulated seasons).
      - `n_teams` integer, nullable: Clubs covered by this forecast.
      - `league_phase_played` integer, nullable: League-phase matches already played (post-draw forecasts).
      - `league_phase_remaining` integer, nullable: League-phase matches still to play (post-draw forecasts).
      - `match_model_note` string, nullable: Provenance of the match model behind the board: variant, calibration shrink and the seasons it was fitted on.
      - `headline` string, nullable: One-sentence framing published with a provisional board (how much of the field is already confirmed).
      - `teams` ChampionsTeamForecast[]: Sorted by p_champion descending.
        - `team` string, required: Club name as UEFA publishes it (e.g. `Bayern München`).
        - `team_id` integer, nullable: UEFA numeric team id — the stable join key across seasons. Null for a club that has not yet appeared in the source feed.
        - `country` string, nullable: UEFA 3-letter association code (`GER`, `FRA`, `ENG`).
        - `entrant_status` string: `confirmed` = the club is in the league phase (or already through to it). `pool` = the club is still playing qualifying and may not make the field at all — only ever present on a `pre_draw` (provisional) forecast.
        - `modal_pot` integer, nullable: Most frequent seeding pot (1-4) across the simulated scenarios. Null once the real draw exists (pots are then historical) and for a qualifying club that never reached the league phase.
        - `euro_elo` number, nullable: European Elo ladder rating at forecast time — the club-strength input behind these probabilities.
        - `coefficient` number, nullable: UEFA 5-year club coefficient used to seed the pots and the qualifying rounds. Present on provisional forecasts only.
        - `p_league_phase` number, nullable: Probability the club plays the league phase at all. 1.0 for a confirmed entrant and for every club once the draw is made; below 1.0 only for clubs still in qualifying.
        - `expected_points` number, nullable: Expected final league-phase points (simulation mean), CONDITIONAL on the club reaching the league phase — expected points for a club that is not playing is not a quantity. Compare with `p_reach`, which is unconditional.
        - `mean_rank` number, nullable: Mean simulated final league-phase position out of 36 (1 = top seed). Also CONDITIONAL on reaching the league phase.
        - `p_champion` number, required: Probability of winning the Champions League — the share of simulated seasons this club won. UNCONDITIONAL: a club still in qualifying carries its own elimination risk here. One measured caveat: club strengths are held fixed inside a simulated season, so a per-match edge compounds and an early (`pre_draw`) board likely overstates the favourites. Known engine limitation, under review.
        - `p_reach` object: Probability of reaching each stage, UNCONDITIONAL, keyed by stage name. The Swiss format fixes the ladder, so the same keys are always present: `playoff`, `top8`, `r16`, `quarter`, `semi`, `final`, `champion`. Two keys need reading carefully. `playoff` means *reached the knockout play-off round OR BETTER*, i.e. a top-24 league-phase finish (survived the league phase) — the clubs that finish top 8 and skip the play-off are counted in it too, so `playoff` >= `r16` always. `top8` is the separate direct-entry branch (a top-8 league-phase finish sends a club straight to the round of 16), so it is a SUBSET of `r16` and the one key that does not decrease monotonically along the list (e.g. {"playoff": 0.99, "top8": 0.41, "r16": 0.96, "quarter": 0.58, "champion": 0.12}).

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/predixsport/apis/predixsport-api.md) · [All operations](https://skmtc.dev/predixsport/apis/predixsport-api/llms.txt) · [OpenAPI document](https://skmtc.dev/predixsport/apis/predixsport-api/revisions/026afdfa7802?raw)
