{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/datasportsapi/json-schema/datasportsapi-fixture-schema.json",
  "title": "Fixture",
  "description": "A single match. Every endpoint and every WebSocket snapshot returns it in this same shape.",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/datasportsapi-openapi.json#/components/schemas/Fixture",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "The fixture’s DataSportsAPI id."
    },
    "sport": {
      "type": "string",
      "description": "Slug of the sport, matching the values listed by /v2/sports."
    },
    "status": {
      "$ref": "#/$defs/Status",
      "description": "Current state of the match."
    },
    "startTime": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "description": "Kick-off time. Holds the scheduled start until the source logs the actual kick-off, which then takes its place (the live feed delivers it a few minutes after play begins). Identical across all endpoints and WebSocket deltas."
    },
    "league": {
      "anyOf": [
        {
          "$ref": "#/$defs/LeagueRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "Competition the fixture belongs to. It is null if the source places the fixture in a competition that has no matching league (observed in minor regional football, e.g. South Africa’s National Second Division on 2026-10-23); in that case season and round are null as well."
    },
    "season": {
      "anyOf": [
        {
          "$ref": "#/$defs/Season"
        },
        {
          "type": "null"
        }
      ],
      "description": "Season the fixture is part of."
    },
    "round": {
      "anyOf": [
        {
          "$ref": "#/$defs/Round"
        },
        {
          "type": "null"
        }
      ],
      "description": "Round of the fixture, for competitions organised in rounds."
    },
    "home": {
      "anyOf": [
        {
          "$ref": "#/$defs/TeamRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "The home team. Null until that slot is settled, e.g. while the source still shows a placeholder like \"WQF1\" (winner of quarter-final 1)."
    },
    "away": {
      "anyOf": [
        {
          "$ref": "#/$defs/TeamRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "The away team. Null until that slot is settled (for instance a \"WQF1\" placeholder from the source)."
    },
    "homeScore": {
      "$ref": "#/$defs/ScoreSide",
      "description": "Score of the home team."
    },
    "awayScore": {
      "$ref": "#/$defs/ScoreSide",
      "description": "Score of the away team."
    },
    "winner": {
      "anyOf": [
        {
          "$ref": "#/$defs/Winner"
        },
        {
          "type": "null"
        }
      ],
      "description": "Stays null until status.type is finished, and also when a fight ends as a no contest (`fightResult.method` noContest). When penalties decide the match, this is always the shoot-out winner regardless of the source (which, on a second leg, reports the team that won the 90 minutes). If the source omits the winner, or declares a draw in a sport where draws are impossible (finishes in regular time or overtime; cricket excluded), we derive it from the score."
    },
    "venue": {
      "anyOf": [
        {
          "$ref": "#/$defs/Venue"
        },
        {
          "type": "null"
        }
      ],
      "description": "Where the match is played, if known (frequently null in lower divisions). Populated on /fixtures/{id}, and in date lists when the source provides it. Round, team, player and live lists never include a venue, so a null there means \"omitted\" rather than \"unknown\" — fetch /fixtures/{id} to get it."
    },
    "clock": {
      "anyOf": [
        {
          "$ref": "#/$defs/Clock"
        },
        {
          "type": "null"
        }
      ],
      "description": "The match clock. Null if the source keeps no clock for this fixture, and after the match ends."
    },
    "firstToServe": {
      "anyOf": [
        {
          "$ref": "#/$defs/Side"
        },
        {
          "type": "null"
        }
      ],
      "description": "Deprecated (2026-10-23); mirrors `serving`. Because the source refreshes it each game / leg, it reflects who is serving (throwing) at the moment, not who served first. Use `serving` instead."
    },
    "serving": {
      "anyOf": [
        {
          "$ref": "#/$defs/Side"
        },
        {
          "type": "null"
        }
      ],
      "description": "Tennis, darts and other sports with a serve: which side is currently serving (throwing), refreshed by the source every game / leg. Null if the source gives no indication."
    },
    "servedFirst": {
      "anyOf": [
        {
          "$ref": "#/$defs/Side"
        },
        {
          "type": "null"
        }
      ],
      "description": "Darts: which side threw the opening dart of the match (`serving` is whoever is throwing now). Fixed for the whole match once play begins; null before that, when the source does not say, and in every other sport (only darts data carries it). Since 2026-11-11."
    },
    "homeSeed": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "For seeded events such as tennis draws or playoff brackets (basketball, …): the seed of the home side (\"1\", \"12\") or its entry status (\"WC\" wild card, \"Q\" qualifier, \"LL\" lucky loser, \"PR\" protected ranking, …), exactly as shown in the draw. Null for an unseeded side."
    },
    "awaySeed": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Seed or entry status of the away side; see homeSeed."
    },
    "note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Cricket: the match note supplied by the source, which becomes the result line at the end (\"Pakistan beat Sri Lanka by 37 runs\"). Intended for display only."
    },
    "battingSide": {
      "anyOf": [
        {
          "$ref": "#/$defs/Side"
        },
        {
          "type": "null"
        }
      ],
      "description": "Cricket: which side is currently at the crease. Null outside a live innings and in every other sport."
    },
    "fightResult": {
      "anyOf": [
        {
          "$ref": "#/$defs/FightResult"
        },
        {
          "type": "null"
        }
      ],
      "description": "MMA / boxing: how, in which round and at what time the fight ended. Null before status.type reaches finished, and when the source supplies no method."
    },
    "fightDiscipline": {
      "anyOf": [
        {
          "$ref": "#/$defs/FightDiscipline"
        },
        {
          "type": "null"
        }
      ],
      "description": "Combat sports: the bout’s discipline, when the source labels it (the `mma` sport includes boxing, kickboxing and Muay Thai cards as well). Only some cards are labelled (ONE, Queensbury, certain OKTAGON fights; never UFC or PFL), so a null value does not imply MMA."
    },
    "referee": {
      "anyOf": [
        {
          "$ref": "#/$defs/Referee"
        },
        {
          "type": "null"
        }
      ],
      "description": "Match official, if the source names one (football and a few other sports; in cricket, the match referee). Present on /fixtures/{id}; always null in lists, where it is omitted."
    },
    "homeManager": {
      "anyOf": [
        {
          "$ref": "#/$defs/ManagerRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "Manager or head coach of the home side for this match, if the source names one. Present on /fixtures/{id}; null in lists."
    },
    "awayManager": {
      "anyOf": [
        {
          "$ref": "#/$defs/ManagerRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "Manager or head coach of the away side; behaves like homeManager."
    },
    "surface": {
      "anyOf": [
        {
          "$ref": "#/$defs/Surface"
        },
        {
          "type": "null"
        }
      ],
      "description": "Tennis: the surface the match is played on. Present on /fixtures/{id} and in live lists; null in other sports."
    },
    "discipline": {
      "anyOf": [
        {
          "$ref": "#/$defs/MatchDiscipline"
        },
        {
          "type": "null"
        }
      ],
      "description": "Tennis: whether it is singles or doubles. Present on every fixture endpoint, in lists and in WebSocket snapshots; null in other sports and when the source specifies neither. Since 2026-11-11."
    },
    "toss": {
      "anyOf": [
        {
          "$ref": "#/$defs/CricketToss"
        },
        {
          "type": "null"
        }
      ],
      "description": "Cricket: the toss result, after it has taken place. Present on /fixtures/{id}; null in other sports."
    },
    "umpires": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        {
          "type": "null"
        }
      ],
      "description": "Cricket: the on-field umpires, named as the source writes them (frequently with a country code, e.g. \"Asif Yaqoob (PAK)\"). Null when none are listed and in other sports."
    },
    "tvUmpire": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Cricket: the TV (third) umpire, formatted as for umpires."
    },
    "previousLegFixtureId": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "description": "Two-legged ties and playoff series: the DataSportsAPI id of the preceding leg / game, when the source links the two. Look that id up on /fixtures/{id} to get the first-leg score."
    },
    "aggregateWinner": {
      "anyOf": [
        {
          "$ref": "#/$defs/Side"
        },
        {
          "type": "null"
        }
      ],
      "description": "Once the return leg of a two-legged tie is over: the side that went through. Taken from the source’s verdict when available; otherwise from `aggregated` (the higher total advances) or, if the aggregate is level, from the shoot-out. Null in every other case, including a level aggregate the source leaves unresolved (an away-goals rule). Compare `winner`, which refers to this match alone: when a second leg goes to penalties both fields name the shoot-out winner, but otherwise they can disagree (a side may win the second leg yet be eliminated). Filled on /fixtures/{id}; in lists and live snapshots it can be null."
    },
    "fightCard": {
      "anyOf": [
        {
          "$ref": "#/$defs/FightCard"
        },
        {
          "type": "null"
        }
      ],
      "description": "MMA / boxing: the bout’s section of the card, its running order and its weight class, if the source lists them."
    },
    "attendance": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "description": "Crowd figure, if the source reports one (observed for NBA and MLB games, frequently only after the game has started). Present on /fixtures/{id}; omitted (null) in lists."
    },
    "matchFormat": {
      "anyOf": [
        {
          "$ref": "#/$defs/MatchFormat"
        },
        {
          "type": "null"
        }
      ],
      "description": "Darts and esports: the format of the match (best of N sets / legs / games), if the source states it. Null in other sports."
    },
    "inningState": {
      "anyOf": [
        {
          "$ref": "#/$defs/InningState"
        },
        {
          "type": "null"
        }
      ],
      "description": "Baseball: the live game situation — inning, half, balls, strikes, outs and runners on base. Null when the game is not in progress or interrupted, and in other sports. Delivered live via WebSocket deltas."
    },
    "timeouts": {
      "anyOf": [
        {
          "$ref": "#/$defs/Timeouts"
        },
        {
          "type": "null"
        }
      ],
      "description": "Basketball: timeouts each side has left. Null outside an in-progress or interrupted game, and whenever the source does not track them. Delivered live via WebSocket deltas."
    },
    "downAndDistance": {
      "anyOf": [
        {
          "$ref": "#/$defs/DownAndDistance"
        },
        {
          "type": "null"
        }
      ],
      "description": "American football: the current down, distance and field position. Null when the game is not in progress or interrupted, and in other sports. Delivered live via WebSocket deltas. Available since 2026-11-09."
    },
    "varCheck": {
      "anyOf": [
        {
          "$ref": "#/$defs/VarCheck"
        },
        {
          "type": "null"
        }
      ],
      "description": "Football: an ongoing VAR review. Null when no review is under way, outside play and in other sports. Delivered live via WebSocket deltas. Available since 2026-11-09."
    },
    "bonus": {
      "anyOf": [
        {
          "$ref": "#/$defs/BasketballBonus"
        },
        {
          "type": "null"
        }
      ],
      "description": "Basketball: whether each side is in the bonus. Null outside an in-progress or interrupted game, and whenever the source does not report it. The source’s live feed never carries it, so it appears in REST responses and lists only. Available since 2026-11-09."
    },
    "finalResultOnly": {
      "type": "boolean",
      "description": "True if the source provides only the final result for this fixture, with no live score, clock or events during play (available since 2026-11-09)."
    },
    "durations": {
      "anyOf": [
        {
          "$ref": "#/$defs/Durations"
        },
        {
          "type": "null"
        }
      ],
      "description": "Sports played in sets or rounds: the length of every finished period (available since 2026-11-04). Null for sports the source does not time by period (football, basketball, …) and until the first period is over. Delivered live via WebSocket deltas."
    },
    "lineupsAvailable": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "description": "Becomes true when the source publishes lineups for the fixture, whether predicted or official (check `confirmed` on /v2/fixtures/{id}/lineups to tell them apart), and false if they are withdrawn. We set it the moment the source’s live feed announces lineups, or when a lineup we fetch contains players. Null means we have no information yet (no announcement observed, nothing fetched). WebSocket deltas carry it live — on fixture:{id} from before kick-off, and on the list channels once play starts. Available since 2026-11-04."
    },
    "lineupsConfirmed": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "description": "Becomes true when the official lineups are released (matching `confirmed` on /v2/fixtures/{id}/lineups); otherwise behaves like lineupsAvailable, with null meaning we have no information. Delivered live via WebSocket deltas. Available since 2026-11-04."
    }
  },
  "required": [
    "id",
    "sport",
    "status",
    "startTime",
    "league",
    "season",
    "round",
    "home",
    "away",
    "homeScore",
    "awayScore",
    "winner",
    "venue",
    "clock",
    "firstToServe",
    "serving",
    "servedFirst",
    "homeSeed",
    "awaySeed",
    "note",
    "battingSide",
    "fightResult",
    "fightDiscipline",
    "referee",
    "homeManager",
    "awayManager",
    "surface",
    "discipline",
    "toss",
    "umpires",
    "tvUmpire",
    "previousLegFixtureId",
    "aggregateWinner",
    "fightCard",
    "attendance",
    "matchFormat",
    "inningState",
    "timeouts",
    "downAndDistance",
    "varCheck",
    "bonus",
    "finalResultOnly",
    "durations",
    "lineupsAvailable",
    "lineupsConfirmed"
  ],
  "$defs": {
    "Bases": {
      "type": "object",
      "description": "Baseball: occupancy of each base.",
      "properties": {
        "first": {
          "type": "boolean",
          "description": "True when first base is occupied."
        },
        "second": {
          "type": "boolean",
          "description": "True when second base is occupied."
        },
        "third": {
          "type": "boolean",
          "description": "True when third base is occupied."
        }
      },
      "required": [
        "first",
        "second",
        "third"
      ]
    },
    "BasketballBonus": {
      "type": "object",
      "description": "Basketball: bonus (penalty situation) status for each side, as reported by the source (available since 2026-11-09).",
      "properties": {
        "home": {
          "type": "boolean",
          "description": "True when the home side is in the bonus, so the away side’s next team foul awards it free throws."
        },
        "away": {
          "type": "boolean",
          "description": "True when the away side is in the bonus."
        }
      },
      "required": [
        "home",
        "away"
      ]
    },
    "Clock": {
      "type": "object",
      "description": "Timing data for a match. Running clocks (football, rugby, …): compute elapsed = periodOffsetSeconds + (now − periodStartedAt) and minute = floor(elapsed / 60) + 1; once periodEndSeconds is passed, display periodEndSeconds / 60 followed by \"+\" and the extra minutes. This applies only while status.phase is inprogress. Stop clocks (basketball, handball, ice hockey, …): playedSeconds is the value at playedAt and advances only while `running` is true. Tennis, table tennis, badminton and esports (set / map sports) carry only `periodStartedAt` (start of the current set or map), and only if the source sends it — the clock as a whole is frequently null. A field is null whenever the source does not provide it for that sport; the entire clock is null when no clock exists and after the match ends. Lists other than /fixtures/{id} may include fewer clock fields (static values such as periodLengthSeconds can be null there).",
      "properties": {
        "periodStartedAt": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ],
          "description": "Moment the clock for the current period was started."
        },
        "periodOffsetSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Running clock: seconds already on the clock at the start of the period (2700 for the second half in football). Unit: seconds."
        },
        "periodEndSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Running clock: clock reading, in seconds, at which regulation time for the period runs out (2700 for the first half in football). Unit: seconds."
        },
        "maxExtraSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Running clock: upper bound on the added time the source’s display permits after periodEndSeconds. Unit: seconds."
        },
        "injuryTimeMinutes": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Stoppage time announced for the current period. Unit: minutes."
        },
        "playedSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Stop clock: time played in seconds, valid at `playedAt`. Unit: seconds."
        },
        "playedAt": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ],
          "description": "Timestamp at which `playedSeconds` was captured."
        },
        "running": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "description": "Stop clock: true while the game clock is ticking."
        },
        "runningUpdatedAt": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ],
          "description": "Time of the most recent change to `running`."
        },
        "periodLengthSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Stop clock: duration of a single regulation period. Unit: seconds."
        },
        "overtimeLengthSeconds": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Duration of a single overtime period. Unit: seconds."
        },
        "periodCount": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "How many regulation periods the match has (in combat sports, the scheduled rounds)."
        },
        "lastPeriodEndedAt": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ],
          "description": "End time of the latest completed period. During a break (half-time, between periods) this marks when the break started, so the break has lasted now − lastPeriodEndedAt. Used with football-style running clocks; null if the source sends nothing (before the first break, in other sports, or for data stored before 2026-11-04). Available since 2026-11-04."
        }
      },
      "required": [
        "periodStartedAt",
        "periodOffsetSeconds",
        "periodEndSeconds",
        "maxExtraSeconds",
        "injuryTimeMinutes",
        "playedSeconds",
        "playedAt",
        "running",
        "runningUpdatedAt",
        "periodLengthSeconds",
        "overtimeLengthSeconds",
        "periodCount",
        "lastPeriodEndedAt"
      ]
    },
    "Country": {
      "type": "object",
      "description": "A country record.",
      "properties": {
        "code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Two-letter code supplied by the source. ISO 3166-1 alpha-2, apart from XK for Kosovo and four codes for the UK home nations (England EN, Scotland SX, Wales WA, Northern Ireland NX). Null if unknown."
        },
        "name": {
          "type": "string",
          "description": "Country name in English."
        },
        "flag": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "null"
            }
          ],
          "description": "Flag image (PNG) hosted on our CDN. Null when there is no code or the image has not been uploaded yet. Available since 2026-11-04."
        }
      },
      "required": [
        "code",
        "name",
        "flag"
      ]
    },
    "CricketInnings": {
      "type": "object",
      "description": "A single cricket innings played by one side.",
      "properties": {
        "runs": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Total runs made."
        },
        "wickets": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Number of wickets that have fallen."
        },
        "overs": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Overs delivered, in cricket notation (49.5 means 49 overs plus 5 balls)."
        },
        "runRate": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Average runs scored per over."
        },
        "targetRunRate": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Run rate the chasing side needs to reach its target."
        }
      },
      "required": [
        "runs",
        "wickets",
        "overs",
        "runRate",
        "targetRunRate"
      ]
    },
    "CricketToss": {
      "type": "object",
      "description": "Cricket: outcome of the coin toss.",
      "properties": {
        "winner": {
          "anyOf": [
            {
              "$ref": "#/$defs/Side"
            },
            {
              "type": "null"
            }
          ],
          "description": "Toss winner; null if the team the source names matches neither participant."
        },
        "decision": {
          "anyOf": [
            {
              "$ref": "#/$defs/TossDecision"
            },
            {
              "type": "null"
            }
          ],
          "description": "The choice the toss winner made."
        }
      },
      "required": [
        "winner",
        "decision"
      ]
    },
    "DownAndDistance": {
      "type": "object",
      "description": "American football: current down, distance and field position as tracked by the source (available since 2026-11-09). The live feed pushes an update after every play; fields not included in an update keep their previous value.",
      "properties": {
        "down": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "The down in play (1–4); null on a kickoff and on the try that follows a touchdown."
        },
        "yardsToGo": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Yards needed for a first down (or to the goal line when goalToGo); null when there is no down."
        },
        "possession": {
          "anyOf": [
            {
              "$ref": "#/$defs/Side"
            },
            {
              "type": "null"
            }
          ],
          "description": "Side in possession of the ball."
        },
        "ballOn": {
          "anyOf": [
            {
              "$ref": "#/$defs/Side"
            },
            {
              "type": "null"
            }
          ],
          "description": "Half of the field the ball is in; combined with yardLine, \"home 35\" means the home side’s 35-yard line."
        },
        "yardLine": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Yard line within that half (50 is midfield)."
        },
        "goalToGo": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "description": "True if the goal line is the line to gain (the source calls it isGoalPossession)."
        },
        "playType": {
          "anyOf": [
            {
              "$ref": "#/$defs/DownPlayType"
            },
            {
              "type": "null"
            }
          ],
          "description": "Kind of play the ball is set up for: scrimmage play, kickoff or try."
        }
      },
      "required": [
        "down",
        "yardsToGo",
        "possession",
        "ballOn",
        "yardLine",
        "goalToGo",
        "playType"
      ]
    },
    "DownPlayType": {
      "type": "string",
      "enum": [
        "scrimmage",
        "kickoff",
        "conversion",
        "other"
      ],
      "description": "American football: what type of play the ball is spotted for.",
      "x-enumDescriptions": {
        "scrimmage": "A scrimmage play, for which downs count.",
        "kickoff": "A kickoff, which uses no down.",
        "conversion": "The try after a touchdown — a kick for the extra point or a two-point attempt — with no down in play.",
        "other": "Any play type missing from this list."
      }
    },
    "Durations": {
      "type": "object",
      "description": "Period lengths for sports played in sets or rounds (tennis, table tennis, badminton, volleyball, MMA, …), as timed by our data source.",
      "properties": {
        "periods": {
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/PeriodKey"
          },
          "additionalProperties": {
            "type": "number"
          },
          "description": "Duration in seconds of every COMPLETED period, using the same keys as ScoreSide.periods (in tennis period1 is the first set; in MMA / boxing the keys are the rounds). The period under way is excluded; its start is clock.periodStartedAt."
        },
        "totalSeconds": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Adds up `periods`: once the match has ended this is its playing time, not counting breaks between periods. Null when `periods` is empty. Unit: seconds."
        }
      },
      "required": [
        "periods",
        "totalSeconds"
      ]
    },
    "FightCard": {
      "type": "object",
      "description": "MMA / boxing: a bout’s placement on the event card.",
      "properties": {
        "section": {
          "anyOf": [
            {
              "$ref": "#/$defs/FightCardSection"
            },
            {
              "type": "null"
            }
          ],
          "description": "The part of the card (main card, prelims, …), if the source specifies it."
        },
        "order": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Position of the bout in the source’s numbering of the card; larger numbers come later, and the main event carries the largest."
        },
        "weightClass": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Weight class of the bout, using the source’s naming (\"light\", \"bantam\", \"feather\", …)."
        }
      },
      "required": [
        "section",
        "order",
        "weightClass"
      ]
    },
    "FightCardSection": {
      "type": "string",
      "enum": [
        "mainCard",
        "prelims",
        "earlyPrelims",
        "other"
      ],
      "description": "Which section of a fight card a bout belongs to.",
      "x-enumDescriptions": {
        "mainCard": "Part of the main card.",
        "prelims": "Part of the preliminary card.",
        "earlyPrelims": "Part of the early preliminary card.",
        "other": "A section without a mapping yet; we log the source’s value."
      }
    },
    "FightDiscipline": {
      "type": "string",
      "enum": [
        "mma",
        "boxing",
        "kickboxing",
        "muayThai",
        "grappling",
        "other"
      ],
      "description": "Which combat sport a fight belongs to.",
      "x-enumDescriptions": {
        "mma": "Mixed martial arts (MMA).",
        "boxing": "A boxing bout.",
        "kickboxing": "A kickboxing bout.",
        "muayThai": "A Muay Thai bout.",
        "grappling": "A submission grappling match.",
        "other": "A discipline without a mapping yet; we log the source’s value."
      }
    },
    "FightMethod": {
      "type": "string",
      "enum": [
        "ko",
        "tko",
        "submission",
        "unanimousDecision",
        "splitDecision",
        "majorityDecision",
        "technicalDecision",
        "pointsDecision",
        "disqualification",
        "noContest",
        "other"
      ],
      "description": "The way a fight was decided.",
      "x-enumDescriptions": {
        "ko": "Knockout (KO).",
        "tko": "Technical knockout: the referee or the doctor stopped the fight.",
        "submission": "Win by submission.",
        "unanimousDecision": "A decision on which every judge agreed.",
        "splitDecision": "A decision on which the judges were divided.",
        "majorityDecision": "A majority decision: two judges favour the winner and the third scores it even. Paired with `winner: \"draw\"` it is a majority draw instead, with two judges scoring a draw (observed in real boxing data on 2026-10-19).",
        "technicalDecision": "Decided on the scorecards following a stoppage.",
        "pointsDecision": "Boxing: a decision on points (PTS in the source), scored solely by the referee as in British small-hall bouts. A drawn bout carries `winner: \"draw\"`.",
        "disqualification": "One fighter was disqualified.",
        "noContest": "Ruled a no contest.",
        "other": "A method we do not classify yet; we log the source’s code."
      }
    },
    "FightResult": {
      "type": "object",
      "description": "MMA / boxing: the way a completed fight was settled.",
      "properties": {
        "method": {
          "$ref": "#/$defs/FightMethod",
          "description": "The winning method."
        },
        "round": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Round in which the fight finished."
        },
        "roundTimeSeconds": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Elapsed time in that round when the fight was halted (KO, TKO, submission, disqualification, …), if the source records it. Null for every decision (unanimous, split, majority, technical, drawn ones too): nothing stopped the fight, and the source’s figure cannot be trusted there. Unit: seconds."
        }
      },
      "required": [
        "method",
        "round",
        "roundTimeSeconds"
      ]
    },
    "FinishType": {
      "type": "string",
      "enum": [
        "regular",
        "overtime",
        "penalties",
        "goldenSet",
        "walkover",
        "retired",
        "defaulted"
      ],
      "description": "The way a completed match was settled.",
      "x-enumDescriptions": {
        "regular": "Settled in regulation time; this is also the normal ending for any sport played in sets, frames or games.",
        "overtime": "Settled in overtime, extra time or extra innings (shown upstream as “AET”).",
        "penalties": "Settled by a penalty shoot-out (shown upstream as “AP”).",
        "goldenSet": "Settled by a golden set, in volleyball.",
        "walkover": "Result awarded with no match played.",
        "retired": "A side withdrew partway through the match (tennis).",
        "defaulted": "A side was defaulted or disqualified."
      }
    },
    "InningState": {
      "type": "object",
      "description": "Baseball: the current game situation — inning, half, count, outs and runners. It contains no batter or pitcher because the source does not provide them here; find the current at-bat’s in /points `atBats`. The source’s live feed refreshes this state roughly once a minute rather than after each pitch, so the count may trail the game by up to a minute.",
      "properties": {
        "inning": {
          "type": "integer",
          "description": "Current inning (10, 11, … indicate extra innings)."
        },
        "half": {
          "type": "string",
          "enum": [
            "top",
            "bottom"
          ],
          "description": "top: the away team is batting; bottom: the home team is batting."
        },
        "battingSide": {
          "$ref": "#/$defs/Side",
          "description": "Side at bat, derived from the half."
        },
        "balls": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Number of balls in the current count."
        },
        "strikes": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Number of strikes in the current count."
        },
        "outs": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Outs recorded in the half-inning; 3 means the half has just finished."
        },
        "bases": {
          "$ref": "#/$defs/Bases",
          "description": "Occupancy of each base."
        }
      },
      "required": [
        "inning",
        "half",
        "battingSide",
        "balls",
        "strikes",
        "outs",
        "bases"
      ]
    },
    "LeagueRef": {
      "type": "object",
      "description": "A league or competition. /v2/leagues/{id} and every league list return this same shape.",
      "properties": {
        "id": {
          "type": "integer",
          "description": "The league’s DataSportsAPI id."
        },
        "name": {
          "type": "string",
          "description": "Name of the league or competition."
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Slug for use in URLs."
        },
        "sport": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Slug of the sport, matching the values listed by /v2/sports."
        },
        "category": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "How the source groups the league: by country (\"England\"), region (\"International\", \"North America\", \"World\"), tour (\"ATP\", \"WTA\") or game (esports: \"Counter Strike\"). It is not necessarily a country; use `country` for that."
        },
        "country": {
          "anyOf": [
            {
              "$ref": "#/$defs/Country"
            },
            {
              "type": "null"
            }
          ],
          "description": "Country of the league when its category is a country; null for regions, tours and games."
        },
        "image": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "null"
            }
          ],
          "description": "League logo hosted on our CDN; null if the league has no image."
        },
        "priority": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "The source’s prominence ranking for the competition, handy for ordering leagues: a higher value means a bigger competition (for example 719 for the Champions League, 704 for the Premier League, 702 for LaLiga, 519 for Primeira Liga), and 0 means unranked. It is filled only where the source supplies it: on the league embedded in a fixture and in the /v2/fixtures?date&sport day lists. Everywhere else — league profiles, directories, search — it is null, as it is on rows saved before 2026-11-04. Available since 2026-11-04."
        }
      },
      "required": [
        "id",
        "name",
        "slug",
        "sport",
        "category",
        "country",
        "image",
        "priority"
      ]
    },
    "ManagerRef": {
      "type": "object",
      "description": "Compact reference to a team’s manager (head coach), embedded in other objects.",
      "properties": {
        "id": {
          "type": "integer",
          "description": "The manager’s DataSportsAPI id."
        },
        "name": {
          "type": "string",
          "description": "Name of the manager or head coach."
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Slug for use in URLs."
        },
        "shortName": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Abbreviated name such as \"F. Hurzeler\"."
        },
        "image": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "null"
            }
          ],
          "description": "Manager photo hosted on our CDN. Null if no image exists or it has not been uploaded yet. Available since 2026-11-04."
        }
      },
      "required": [
        "id",
        "name",
        "slug",
        "shortName",
        "image"
      ]
    },
    "MatchDiscipline": {
      "type": "string",
      "enum": [
        "singles",
        "doubles"
      ],
      "description": "Tennis: whether a match is singles or doubles.",
      "x-enumDescriptions": {
        "singles": "A single player per side.",
        "doubles": "Two players on each side (men’s, women’s or mixed, as the league indicates)."
      }
    },
    "MatchFormat": {
      "type": "object",
      "description": "Length of the match in sets / legs / games, if the source states it.",
      "properties": {
        "bestOfSets": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Darts: number of sets in the format (\"best of 5 sets\"); 1 indicates a legs match without sets."
        },
        "bestOfLegs": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Darts: legs per set if `bestOfSets` > 1, otherwise legs in the whole match (\"best of 7 legs\")."
        },
        "bestOfGames": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Esports: how many games (maps) the series is played over (\"best of 3\")."
        }
      },
      "required": [
        "bestOfSets",
        "bestOfLegs",
        "bestOfGames"
      ]
    },
    "PeriodKey": {
      "type": "string",
      "pattern": "^(?:period[1-9][0-9]*|inning[1-9][0-9]*|extra[12]|overtime|penalties)$",
      "description": "periodN: Regulation period number N. What a period is depends on the sport: a half in football, rugby, handball, futsal, minifootball and bandy; a quarter in basketball, American football and water polo; a period in ice hockey and floorball; a set in tennis, volleyball, table tennis, badminton and padel; an inning in baseball; a round in combat sports; a map / game in esports; a leg / frame block in darts and snooker. inningN: Cricket only: innings number N. extra1: Football and futsal: the opening half of extra time. extra2: Football and futsal: the closing half of extra time. overtime: Every overtime period summed into one value (American football, basketball, handball, ice hockey, water polo, …). In baseball it holds the runs scored in extra innings, and only when the source provides no inning-by-inning split (period10, …). penalties: The penalty shoot-out, which appears only as a `status.period` value; its score is kept in ScoreSide.penalties, not under a `periods` key."
    },
    "Referee": {
      "type": "object",
      "description": "The match official (for cricket, the match referee) and the career totals the source records for them. For a per-match rate, divide a total by `games`.",
      "properties": {
        "id": {
          "type": "integer",
          "description": "The referee’s DataSportsAPI id."
        },
        "name": {
          "type": "string",
          "description": "Name of the referee."
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Slug for use in URLs."
        },
        "country": {
          "anyOf": [
            {
              "$ref": "#/$defs/Country"
            },
            {
              "type": "null"
            }
          ],
          "description": "Country of the referee, if the source supplies it."
        },
        "games": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Number of matches the source has logged with this referee in charge, across the whole career and all competitions."
        },
        "yellowCards": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Yellow cards issued across those matches. Null in sports that have no cards (cricket)."
        },
        "redCards": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Direct red cards issued across those matches. Null in sports that have no cards."
        },
        "yellowRedCards": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Dismissals for a second yellow across those matches. Null in sports that have no cards."
        },
        "image": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "null"
            }
          ],
          "description": "Referee photo hosted on our CDN. Null if no image exists or it has not been uploaded yet. Available since 2026-11-04."
        }
      },
      "required": [
        "id",
        "name",
        "slug",
        "country",
        "games",
        "yellowCards",
        "redCards",
        "yellowRedCards",
        "image"
      ]
    },
    "Round": {
      "type": "object",
      "description": "One round within a league season.",
      "properties": {
        "number": {
          "type": "integer",
          "description": "Round number from the source. Treat it as an opaque key rather than a sequence: cups count rounds by how many entrants remain (32 for a tennis \"Round of 64\"), and playoff rounds get large values (636). Use it with /v2/leagues/{id}/fixtures. The source gives some competitions no round structure — NBA and NHL regular seasons, NCAA, one-off tennis or MMA events; their fixtures may still have a round, but /rounds comes back empty and filtering by round yields nothing, so query them by date."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Name of the round, if it has one (\"Quarterfinals\", \"Playoff round\")."
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Tells apart rounds that share a number across different phases. When present, include it in /fixtures requests."
        },
        "prefix": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "An additional qualifier (e.g. \"Qualification\"); send it to /fixtures along with slug."
        }
      },
      "required": [
        "number",
        "name",
        "slug",
        "prefix"
      ]
    },
    "ScoreSide": {
      "type": "object",
      "description": "Score of one team.",
      "properties": {
        "current": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "The headline score you would see on a scoreboard: goals, points, sets won (tennis / volleyball) or runs (cricket, baseball), counting extra time / overtime. Shoot-out goals are excluded and reported in `penalties` instead — except in ice hockey, where the shoot-out winner is given one extra goal (3-3 after overtime becomes 3-4). Before the start, and for fixtures whose coverage was canceled, it is null."
        },
        "periods": {
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/PeriodKey"
          },
          "additionalProperties": {
            "type": "number"
          },
          "description": "The score split by period and keyed by PeriodKey — goals per half, quarter or period; games per set in tennis; points per set in volleyball and table tennis; runs per inning in baseball. Extra periods are included too: football and futsal use `extra1` / `extra2`; American football, basketball, handball, ice hockey, water polo and others use `overtime`; baseball extra innings run from `period10` upwards (`overtime` only if the source reports extra-innings runs as one total). When the source’s breakdown is complete the values sum to `current`; it is occasionally incomplete (some baseball leagues omit innings, a few futsal matches lack a half), and ice hockey decided by a shoot-out is intentionally one goal short (see `current`). Esports uses one key per game (map), with a title-dependent meaning: Counter-Strike stores 1 for each map a side won and 0 for the rest (maps not played count as 0, through period5 in a best of 3); in League of Legends it is the side’s kill count in game N, so the values do not sum to `current`, which counts games won. Each game’s winner and score are on /fixtures/{id}/games. Empty when the source gives no breakdown."
        },
        "tieBreaks": {
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/PeriodKey"
          },
          "additionalProperties": {
            "type": "number"
          },
          "description": "Tennis: points won in each set’s tie-break, using the same keys as `periods` (e.g. { \"period2\": 7 })."
        },
        "normalTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Score when regulation time ended, if the source provides it."
        },
        "penalties": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Goals converted in a penalty shoot-out. In ice hockey the shoot-out winner gets 1 here and the loser 0, in line with the single goal added to `current`."
        },
        "aggregated": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Combined score across both legs of a two-legged tie."
        },
        "series": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Playoff series: number of games this side has won in the series to date (basketball, baseball, ice hockey, water polo)."
        },
        "point": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Tennis: score within the current game — \"0\" | \"15\" | \"30\" | \"40\" | \"A\", or a plain number (\"0\"–\"N\") during a tie-break. Darts: the points the side still has to score in the current leg (\"501\" when a leg starts). Null when play is neither in progress nor interrupted."
        },
        "redCards": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Football: number of red cards this side has received, counting second yellows."
        },
        "innings": {
          "type": "object",
          "propertyNames": {
            "$ref": "#/$defs/PeriodKey"
          },
          "additionalProperties": {
            "$ref": "#/$defs/CricketInnings"
          },
          "description": "Cricket: each innings of this side, keyed inning1…N. Empty in other sports."
        },
        "hits": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Baseball: hit total, i.e. the H in the R/H/E line."
        },
        "errors": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Baseball: error total, i.e. the E in the R/H/E line."
        }
      },
      "required": [
        "current",
        "periods",
        "tieBreaks",
        "normalTime",
        "penalties",
        "aggregated",
        "series",
        "point",
        "redCards",
        "innings",
        "hits",
        "errors"
      ]
    },
    "Season": {
      "type": "object",
      "description": "One season of a league.",
      "properties": {
        "id": {
          "type": "integer",
          "description": "The season’s DataSportsAPI id."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Full season name, such as \"Premier League 26/27\"."
        },
        "year": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Display label in the source’s format: \"26/27\" or \"2026/2027\" when the season spans two years, \"2026\" for a calendar-year season. Use startYear / endYear for sorting and filtering."
        },
        "startYear": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Year in which the season begins (2026 for both \"26/27\" and \"2026\"); null if the label cannot be parsed."
        },
        "endYear": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Year in which the season finishes (2027 for \"26/27\"; equal to startYear for a calendar-year season); null if the label cannot be parsed."
        }
      },
      "required": [
        "id",
        "name",
        "year",
        "startYear",
        "endYear"
      ]
    },
    "Side": {
      "type": "string",
      "enum": [
        "home",
        "away"
      ],
      "description": "One of the two sides in a fixture.",
      "x-enumDescriptions": {
        "home": "The side listed as home in the fixture.",
        "away": "The side listed as away in the fixture."
      }
    },
    "Status": {
      "type": "object",
      "description": "The state of a match.",
      "properties": {
        "type": {
          "$ref": "#/$defs/StatusType",
          "description": "High-level state, computed from `phase` (mapping in the StatusPhase table)."
        },
        "phase": {
          "$ref": "#/$defs/StatusPhase",
          "description": "Detailed state, computed from `code`."
        },
        "code": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "The source’s raw status code (the data dictionary lists every value); `phase`, `period` and `finish` give you its meaning ready-made."
        },
        "description": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Human-readable English label taken from our status table (status codes in the data dictionary) and adapted to the sport, for example \"Halftime\", \"2nd half\", \"After penalties\", \"After extra time\" (football), \"After extra innings\" (baseball), \"After overtime\" (basketball, ice hockey, …), \"1st innings\" (cricket) or \"Coverage canceled\". For a code we do not recognise, the source’s own wording is passed through. Use it for display, never for branching logic."
        },
        "period": {
          "anyOf": [
            {
              "$ref": "#/$defs/PeriodKey"
            },
            {
              "type": "null"
            }
          ],
          "description": "Period currently being played, or the one just completed during a break. Null before the start and after the end."
        },
        "finish": {
          "anyOf": [
            {
              "$ref": "#/$defs/FinishType"
            },
            {
              "type": "null"
            }
          ],
          "description": "The way the result was reached. Only set when `type` is finished; null otherwise."
        }
      },
      "required": [
        "type",
        "phase",
        "code",
        "description",
        "period",
        "finish"
      ]
    },
    "StatusPhase": {
      "type": "string",
      "enum": [
        "notstarted",
        "delayed",
        "inprogress",
        "break",
        "awaitingResult",
        "interrupted",
        "suspended",
        "willcontinue",
        "postponed",
        "canceled",
        "abandoned",
        "finished"
      ],
      "description": "Detailed match state, as a scoreboard would display it.",
      "x-enumDescriptions": {
        "notstarted": "Scheduled and not yet under way.",
        "delayed": "The start time has passed but play has been delayed.",
        "inprogress": "A period is in play; status.period identifies which one.",
        "break": "A planned stoppage within the match, such as half-time, the gap between sets, waiting for extra time or penalties, or a cricket lunch / tea / drinks interval.",
        "awaitingResult": "Play has ended but the result has not been announced yet (for example a combat-sports judges’ decision).",
        "interrupted": "Halted unexpectedly; play should restart.",
        "suspended": "Halted by the organiser and possibly resumed on another day.",
        "willcontinue": "A match lasting several days, currently paused between days.",
        "postponed": "Rescheduled for a later date.",
        "canceled": "Called off before the start, or removed.",
        "abandoned": "Began but was stopped for good without a result.",
        "finished": "Completed; status.finish explains how the result was reached."
      }
    },
    "StatusType": {
      "type": "string",
      "enum": [
        "notstarted",
        "inprogress",
        "interrupted",
        "willcontinue",
        "postponed",
        "canceled",
        "finished"
      ],
      "description": "High-level state of a match, meant for filtering.",
      "x-enumDescriptions": {
        "notstarted": "Has not begun yet: still scheduled, or its start has been delayed.",
        "inprogress": "Under way, breaks included (for example half-time, or a fight waiting for its decision).",
        "interrupted": "Halted partway through (weather, crowd, …); play is expected to restart.",
        "willcontinue": "A match spread over several days, currently between days (for cricket Tests, the end of day N).",
        "postponed": "Rescheduled for a later date; the fixture id stays the same.",
        "canceled": "The match is not going to be played (canceled, abandoned or removed).",
        "finished": "Completed and has a result."
      }
    },
    "Surface": {
      "type": "object",
      "description": "Tennis: the type of court used for the match.",
      "properties": {
        "type": {
          "$ref": "#/$defs/SurfaceType",
          "description": "Surface category of the court."
        },
        "indoor": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "description": "True for an indoor court and false for an outdoor one; null if the source does not specify."
        },
        "name": {
          "type": "string",
          "description": "Surface label as worded by the source, such as \"Hardcourt outdoor\". For display only."
        }
      },
      "required": [
        "type",
        "indoor",
        "name"
      ]
    },
    "SurfaceType": {
      "type": "string",
      "enum": [
        "hard",
        "clay",
        "grass",
        "carpet",
        "other"
      ],
      "description": "Surface of a tennis court.",
      "x-enumDescriptions": {
        "hard": "A hard court.",
        "clay": "A clay court, red or green.",
        "grass": "A grass court.",
        "carpet": "Carpet, a synthetic indoor surface.",
        "other": "A surface we do not classify yet; `name` holds the source’s text."
      }
    },
    "TeamRef": {
      "type": "object",
      "description": "Compact team reference embedded in other objects (fixtures, standings, players, leaders).",
      "properties": {
        "id": {
          "type": "integer",
          "description": "The team’s DataSportsAPI id."
        },
        "name": {
          "type": "string",
          "description": "Name of the team. Individual sports (tennis, table tennis, darts, MMA, …) also model each competitor as a team — a single player, or a doubles pair."
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Slug for use in URLs."
        },
        "shortName": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Abbreviated display name, if the source provides one."
        },
        "code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Abbreviation of 1–4 characters as used on scoreboards (e.g. \"ARS\", \"LA\"); generated artificially for individual sports."
        },
        "image": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "null"
            }
          ],
          "description": "Team logo hosted on our CDN; null if the team has no image."
        }
      },
      "required": [
        "id",
        "name",
        "slug",
        "shortName",
        "code",
        "image"
      ]
    },
    "Timeouts": {
      "type": "object",
      "description": "Basketball: remaining timeouts for each side, as tracked by the source.",
      "properties": {
        "homeRemaining": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Timeouts still available to the home side."
        },
        "awayRemaining": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Timeouts still available to the away side."
        },
        "perTeam": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Timeouts each side is allotted for the game (7 in the NBA)."
        }
      },
      "required": [
        "homeRemaining",
        "awayRemaining",
        "perTeam"
      ]
    },
    "TossDecision": {
      "type": "string",
      "enum": [
        "bat",
        "bowl"
      ],
      "description": "The choice made by the side that won a cricket toss.",
      "x-enumDescriptions": {
        "bat": "Elected to bat first.",
        "bowl": "Elected to bowl (field) first."
      }
    },
    "VarCheck": {
      "type": "object",
      "description": "Football: an ongoing video (VAR) review (available since 2026-11-09).",
      "properties": {
        "side": {
          "anyOf": [
            {
              "$ref": "#/$defs/Side"
            },
            {
              "type": "null"
            }
          ],
          "description": "Side whose incident (a goal, a penalty, a card) is being reviewed, if the source specifies it; null when it does not name one."
        }
      },
      "required": [
        "side"
      ]
    },
    "Venue": {
      "type": "object",
      "description": "A stadium or arena: where a fixture takes place, or a team’s home ground.",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "The venue’s DataSportsAPI id; null if the source supplies the venue without an id."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Name of the stadium or arena."
        },
        "city": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "City where the venue is located."
        },
        "country": {
          "anyOf": [
            {
              "$ref": "#/$defs/Country"
            },
            {
              "type": "null"
            }
          ],
          "description": "Country where the venue is located."
        },
        "capacity": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "description": "Number of seats."
        }
      },
      "required": [
        "id",
        "name",
        "city",
        "country",
        "capacity"
      ]
    },
    "Winner": {
      "type": "string",
      "enum": [
        "home",
        "away",
        "draw"
      ],
      "description": "Outcome of a fixture that has finished.",
      "x-enumDescriptions": {
        "home": "Victory for the home side.",
        "away": "Victory for the away side.",
        "draw": "Neither side won; the fixture was drawn."
      }
    }
  }
}