---
title: "How well the Champions League player models track one player"
method: GET
path: "/v1/players/champions/{player}/prediction-performance"
tags: ["players"]
---

# How well the Champions League player models track one player

`GET /v1/players/champions/{player}/prediction-performance`

## 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/players/champions/{player}/prediction-performance`
- Auth: none declared

Per-player track record of our UEFA Champions League player projections, for matches the player STARTED. `player` accepts the display name ("Vinicius Junior") or its slug ("vinicius-junior"). Returns CRPS skill against a naive baseline (role rate x expected minutes) on shots and shots on target, the anytime-scorer Brier skill as a secondary, goalkeeper saves for keepers, and one summary per covered season.

This response is AGGREGATE ONLY: there is no per-match array here, unlike the NBA and Euroleague player endpoints. Champions League player surfaces publish season-level accuracy of our own forecasts and never a per-match statistics feed.

Seasons are the UEFA season ENDING year as a string: `2026` is the 2025-26 campaign. `source` distinguishes the frozen out-of-sample holdout (2022-2026) from live reconciliation (from 2026-27). `mode` reports the serving mode the record was scored in: `t75` means the confirmed team sheet was out. Coverage starts at 8 started appearances in a season, a full league phase, below which the estimate is noise.

## Path parameters

- `player` string, required

## Query parameters

- `season` string, nullable: UEFA season ending year, e.g. 2026 for the 2025-26 campaign

## Headers

- `authorization` string, nullable

## Response `200`

Successful Response

- ChampionsPlayerPerformanceResponse
  - `player` string, required
  - `player_id` string, required: UEFA player id, the stable join key. A STRING with two width families (legacy 3-8 digits, modern 9) — never cast to an integer.
  - `team` string, nullable
  - `country` string, nullable
  - `role` string, nullable: GOALKEEPER | DEFENDER | MIDFIELDER | FORWARD
  - `season` string, required: UEFA seasonYear, the season ENDING year: '2026' = 2025-26
  - `season_label` string, required
  - `source` string, required: 'backtest' = frozen-protocol holdout (the whole season is out-of-sample); 'production' = live predictions reconciled after the matchday. A season is served from exactly one source.
  - `mode` string, required: Serving mode the record was scored in. 't75' = the confirmed team sheet is out. Pre-match and T-75 score different row populations and are never pooled, so one mode is served.
  - `matches` integer, required
  - `started` integer, required: Started appearances (the scored population)
  - `minutes` integer, nullable
  - `predictability_score` number, nullable: Mean CRPS skill of shots + shots on target x 100. Higher = more predictable for our models. NULL for goalkeepers, who have no shot rows and are measured on saves instead.
  - `score_se` number, nullable: Standard error of predictability_score, same x100 units. A conservative bound (the two badge skills are treated as perfectly correlated). Always read the score with this.
  - `stats` ChampionsStatPerformance[], required
    - `stat` string, required: shots | sot | saves
    - `label` string, required
    - `started` integer, required: Started appearances the stat was scored on
    - `avg_expected` number, nullable
    - `avg_actual` number, nullable
    - `crps_model` number, nullable
    - `crps_naive` number, nullable: Naive baseline = role rate x expected minutes, level-matched on the fit era, with its own fitted dispersion. Stored rather than re-derived: it is a negative binomial over a minutes mixture, so no closed-form Poisson reproduces it.
    - `skill` number, nullable: 1 - crps_model / crps_naive. Positive = our model tracks this player better than the baseline.
    - `skill_se` number, nullable: Standard error of `skill` (ratio-estimator delta method). Published because the skill is a ratio of small numbers and its variance is far wider for low-volume players, so a rank without it reads as precision the measurement does not have.
    - `in_score` boolean, required: Whether this stat counts toward predictability_score
  - `scorer` ChampionsScorerPerformance, required
    - `brier_model` number, nullable
    - `brier_naive` number, nullable
    - `skill` number, nullable: 1 - brier_model / brier_naive on the anytime-scorer market
    - `goals` integer, nullable
    - `expected_goals` number, nullable
  - `seasons` ChampionsSeasonSummary[], required: Every served season for this player, oldest first
    - `season` string, required
    - `season_label` string, required
    - `team` string, nullable
    - `started` integer, required
    - `predictability_score` number, nullable

## 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/02014aee733d?raw)
