---
title: "Full WTA (women's tennis) match payload (winner, total games, spread, aces, double faults, tiebreak, exact score)"
method: GET
path: "/v1/predictions/wta/{match_id}"
tags: ["predictions"]
---

# Full WTA (women's tennis) match payload (winner, total games, spread, aces, double faults, tiebreak, exact score)

`GET /v1/predictions/wta/{match_id}`

## 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/predictions/wta/{match_id}`
- Auth: none declared

Returns the full payload for a single WTA match — same contract as the ATP ``tennis`` sport. Player order (`player_one` / `player_two`) is **as observed** at data ingestion — NEVER winner-first canonicalised. All player-relative numbers (spread, exact_score classes and serve projections) are aligned to that ordering. Aces and double faults are available both per player and as derived match totals; the totals retain their existing API meaning. A played match adds `actual_aces` and `actual_double_faults` to each player, matched by NAME, so a projection can be scored against what that player really served. The seven sub-models (winner classifier, total/spread regressors, per-player aces/double-faults regressors, tiebreak classifier and exact-score multiclass) are independent — small cross-metric mismatches are by design. Every WTA match is best-of-three sets (Grand Slams included), so the exact-score distribution carries only the four bo3 classes. `tournament.date` is the tournament START day, not the specific match day. Returns **404** if the `match_id` is unknown.

## Path parameters

- `match_id` string, required

## Headers

- `authorization` string, nullable

## Response `200`

Successful Response

- WTAMatchDetail: WTA (women's tennis) match detail — same contract as ATP tennis. Every WTA match is best-of-three sets (Grand Slams included), so the exact-score distribution only carries the four bo3 classes. ``key_factors`` is populated, as it is on the ATP tour. Serve projections are per player here too (one model per stat, two outputs): ``player_one`` and ``player_two`` each carry their own aces and double faults, and the match totals are derived by summing the two projections. Those per-player fields are null only for matches predicted before the August 2026 rollout.
  - `match_id` string, required
  - `sport` 'wta'
  - `date` string, date, required: Tournament-scheduled START day, NOT the actual match day. Shared by every match of the same tournament across all rounds. Use ``tournament.round`` to gauge how far into the tournament this match falls.
  - `season` string, required
  - `tournament` TournamentInfo, required
    - `name` string, required
    - `location` string, required
    - `surface` string, required
    - `type` string, required: Tournament category (e.g. grand_slam, masters_1000, atp_250).
    - `round` integer, nullable: Numeric round identifier as recorded by the data pipeline (higher = later round).
  - `player_one` TennisPlayerDetail, required: The ``player_one`` / ``player_two`` object of a tennis-family match detail: the win probability plus that player's OWN serve projections. The serve fields hang off the player they describe rather than sitting flat on the payload as ``expected_aces_player_one``. Same rule as the win probability (see ``src.models.predictions``): every player-relative number lives inside the object whose ``name`` it belongs to, so it cannot be mis-attributed. Populated for ATP ``tennis`` since migration 060 and WTA since migration 063. Null for matches predicted before the relevant rollout. ``actual_aces`` / ``actual_double_faults`` are the realized counts of a played match (migrations 061 / 064), matched to this object by player NAME rather than by slot: the reconciliation record carries the as-observed order of the LATEST data ingestion while the prediction carries the as-observed order of the day it was made, and pairing those by position would hand one player's serve numbers to the other whenever the two disagree.
    - `name` string, required
    - `win_probability` number, nullable: Probability of this player winning the match, in [0, 1].
    - `expected_aces` number, nullable: Expected aces served by THIS player. Sums with the other player's value to `expected_aces`.
    - `aces_distribution` object, nullable: Probability per ace count for this player, as {count: probability}.
    - `aces_cdf` object, nullable: Cumulative probability P(aces <= count) for this player.
    - `expected_double_faults` number, nullable: Expected double faults hit by THIS player. Sums with the other player's value to `expected_double_faults`.
    - `double_faults_distribution` object, nullable: Probability per double-fault count for this player, as {count: probability}.
    - `double_faults_cdf` object, nullable: Cumulative probability P(double faults <= count) for this player.
    - `actual_aces` integer, nullable: Aces THIS player actually served, once the match is played and reconciled. Compare with `expected_aces` and score the call against `aces_distribution`. Null while the match is ahead, and for matches played before the per-player rollout.
    - `actual_double_faults` integer, nullable: Double faults THIS player actually hit, once the match is played and reconciled. Same availability rule as `actual_aces`.
  - `player_two` TennisPlayerDetail, required: The ``player_one`` / ``player_two`` object of a tennis-family match detail: the win probability plus that player's OWN serve projections. The serve fields hang off the player they describe rather than sitting flat on the payload as ``expected_aces_player_one``. Same rule as the win probability (see ``src.models.predictions``): every player-relative number lives inside the object whose ``name`` it belongs to, so it cannot be mis-attributed. Populated for ATP ``tennis`` since migration 060 and WTA since migration 063. Null for matches predicted before the relevant rollout. ``actual_aces`` / ``actual_double_faults`` are the realized counts of a played match (migrations 061 / 064), matched to this object by player NAME rather than by slot: the reconciliation record carries the as-observed order of the LATEST data ingestion while the prediction carries the as-observed order of the day it was made, and pairing those by position would hand one player's serve numbers to the other whenever the two disagree.
    - `name` string, required
    - `win_probability` number, nullable: Probability of this player winning the match, in [0, 1].
    - `expected_aces` number, nullable: Expected aces served by THIS player. Sums with the other player's value to `expected_aces`.
    - `aces_distribution` object, nullable: Probability per ace count for this player, as {count: probability}.
    - `aces_cdf` object, nullable: Cumulative probability P(aces <= count) for this player.
    - `expected_double_faults` number, nullable: Expected double faults hit by THIS player. Sums with the other player's value to `expected_double_faults`.
    - `double_faults_distribution` object, nullable: Probability per double-fault count for this player, as {count: probability}.
    - `double_faults_cdf` object, nullable: Cumulative probability P(double faults <= count) for this player.
    - `actual_aces` integer, nullable: Aces THIS player actually served, once the match is played and reconciled. Compare with `expected_aces` and score the call against `aces_distribution`. Null while the match is ahead, and for matches played before the per-player rollout.
    - `actual_double_faults` integer, nullable: Double faults THIS player actually hit, once the match is played and reconciled. Same availability rule as `actual_aces`.
  - `predicted_total_games` integer, nullable: Rounded mean of the Poisson total-games regressor. Equivalent to `round(expected_total_games)` and aligned with the value shown on predixsport.com. Use `expected_total_games` for the un-rounded mean and `distributions.total_games` for the full PMF.
  - `expected_total_games` number, nullable: Mean (expected value) of the Poisson total-games regressor.
  - `predicted_result` string, nullable
  - `tiebreak` TennisTiebreakProjection
    - `probability_yes` number, nullable
    - `probability_no` number, nullable
    - `predicted` string, nullable
  - `exact_score` TennisExactScoreProjection
    - `predicted` string, nullable: Most likely set score in "X-Y" format relative to player_one.
    - `distribution` object, nullable: Probability per "X-Y" class. Masked to feasible outcomes for the tournament format.
  - `expected_aces` number, nullable: Expected total aces in the match: the sum of the two per-player projections carried by `player_one` and `player_two`, with `distributions.aces` the convolution of their distributions. The per-player fields are null for matches predicted before the per-player rollout on that tour, and the total keeps the meaning it has always had either way.
  - `expected_double_faults` number, nullable: Expected total double faults in the match. Same derivation as `expected_aces`, on both tours.
  - `expected_spread` number, nullable: Expected (player_one_games - player_two_games). Sign convention follows the as-observed player order — negative means player_two is favoured.
  - `distributions` TennisDistributions
    - `total_games` object, nullable
    - `spread` object, nullable
    - `aces` object, nullable
    - `double_faults` object, nullable
  - `cdfs` TennisDistributions
    - `total_games` object, nullable
    - `spread` object, nullable
    - `aces` object, nullable
    - `double_faults` object, nullable
  - `key_factors` KeyFactors: Concept-level attribution of the winner prediction. Computed with gradient-based attribution on the production neural network and aggregated into human concepts; the factors approximately sum to the gap between the served win probability and an even matchup. For football the factors compare the two sides directly (the draw probability is modelled separately). Absent on rows predicted before the explainability rollout (June 2026).
    - `schema_version` integer: Contract version of this payload.
    - `baseline_probability` number, nullable: Model probability for an average matchup — the reference point the factors move the prediction away from.
    - `factors` KeyFactor[]: Factors sorted by absolute impact (largest first).
      - `key` string, required: Stable identifier of the factor (e.g. 'surface', 'starting_five', 'attack').
      - `label` string, required: Human-readable factor name, as shown on predixsport.com.
      - `prob_points` number, required: How many win-probability percentage points this factor moves the prediction. Positive values favour the first side (player one / home team), negative values the second side.
      - `direction` string, required: What the factor favours: 'player_one'/'player_two' for tennis, 'home'/'away' for NBA and football winner attributions, 'under'/'over' for the football under/over 2.5 attribution.
      - `stable` boolean, required: True when the attribution sign is consistent across independent estimator runs. Treat unstable factors as indicative, not decisive.
      - `display` boolean: False for internal context buckets not shown on predixsport.com.
      - `share` number, nullable: This factor's share of the total absolute attribution (0-1).
      - `synthetic` boolean, nullable: True for fixed baseline terms (home advantage, league scoring environment) that reflect league-wide tendencies rather than this specific matchup.
      - `side` string, nullable: For per-team factors on outcome attributions (football under/over): which team the factor describes ('home'/'away'). Surfaces can substitute the actual team name into the label.
  - `actual` TennisActual: Realized result once the match has been played and reconciled (``{tennis|wta}_in_season_performance_frozen``). Absent until the match is played. ``winner`` is the actual winner's NAME, aligned to the as-observed player ordering — never inferred from player position.
    - `winner` string, nullable: Name of the player who actually won the match.
    - `total_games_played` integer, nullable: Total games played across all sets. Compare with predicted_total_games.

## 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)
