Get StartedDocs

Asking Questions

The /ask endpoint is the public surface of the API today. It accepts a natural language question and returns a written answer alongside the underlying stat values when the question resolves to a structured query.

The endpoint

GET https://api.statmuse.com/sports/{domain}/v1/ask?input={question}
Parameter In Description
domain path Sport code: nba, nfl, nhl, mlb, wnba, cfb, pga or fc.
input query Your question in plain English, up to 200 characters. URL-encode it.

The question is interpreted in the context of the domain you target. Asking who leads in passing yards against /sports/nfl/v1/ask and /sports/cfb/v1/ask resolves to two different answers.

The response shapes

Every 200 response carries a type discriminator. Inspect it before reading the rest of the body.

type When What you get
"stats" The question resolves to a structured stats query. Written answer + structured results.
"player" The question resolves to a player (e.g. a name alone). Written answer + the player’s identity.
"team" The question resolves to a team. Written answer + the team’s identity.
"unknown" The question is opinion, general knowledge or off-topic. Written answer only.

All shapes share input and answer. Every shape except unknown also carries query (the structured query the parser derived) and data (what resolves: result rows for stats, the identity for player and team).

Not every domain has every shape: team never occurs for pga because golf has no teams. And the set of type values will grow as the API capabilities expand, so branch on the values you know and treat any unrecognized type as you would unknown rather than failing.

For the precise per-domain schemas consult the API Reference.

The stats shape

type StatsAskResponse = {
  type: "stats";
  input: { original: string };
  answer: { text: string; markdown: string };
  query: {
    stats: string[];
    calculations?: { alias: string; formula: string }[];
  };
  data: {
    results: Array<{
      context: ContextItem[];
      stats: Record<string, { value: number | null; display: string }>;
      calculations?: Record<string, { value: number | null; display: string }>;
    }>;
  };
};

input

original is the client’s input, verbatim.

answer

A pre-written natural language answer in two formats:

  • text: plain text, suitable for any context (alt text, voice, embeddings).
  • markdown: the same answer with entity names linked to their StatMuse pages. Use this for display.

query

The structured query the parser produced. query.stats lists the stat keys you’ll find on each result row, useful as the column order for a table. query.calculations, when present, lists derived stats (e.g. points-per-game) that show up under result.calculations.

Note. query is intentionally minimal today. The structured query contract will expand as we expose lower-level APIs (NLP and stats-query) in the future. Treat fields outside stats and calculations as opaque for now.

data.results

One row per result. Each row has three parts:

  • context[]: identifiers describing the row: which player, team, season, opponent, game and so on. Each item is a tagged union (every item has its own type field). The set of context types is domain-specific; see the per-sport schemas in the API Reference.
  • stats: a map from stat key to { value, display }. value is the raw number (or null if the stat wasn’t recorded for that row); use it for math. display is pre-formatted ("2,484", "+918", etc.); use it for display.
  • calculations: present only when query.calculations is set. Same shape as stats; keys correspond to query.calculations[].alias.

Example

{
  "type": "stats",
  "input": {
    "original": "who led the nba in scoring in 2024-25"
  },
  "answer": {
    "text": "Shai Gilgeous-Alexander averaged the most points per game in 2024-25, with 32.7 per game.",
    "markdown": "[Shai Gilgeous-Alexander](https://www.statmuse.com/nba/player/shai-gilgeous-alexander-9773) averaged the most points per game in 2024-25, with 32.7 per game."
  },
  "query": {
    "stats": ["PointsPerGame", "GamesPlayed", "Points"]
  },
  "data": {
    "results": [
      {
        "context": [
          {
            "type": "player",
            "playerId": 9773,
            "longName": "Shai Gilgeous-Alexander"
          },
          {
            "type": "team",
            "teamId": 38,
            "shortName": "Thunder",
            "abbreviation": "OKC"
          },
          {
            "type": "seasonYear",
            "seasonYear": 2025,
            "display": "2024-25"
          }
        ],
        "stats": {
          "PointsPerGame": { "value": 32.68421053, "display": "32.7" },
          "GamesPlayed": { "value": 76, "display": "76" },
          "Points": { "value": 2484, "display": "2,484" }
        }
      },
      {
        "context": [
          {
            "type": "player",
            "playerId": 97,
            "longName": "Giannis Antetokounmpo"
          },
          {
            "type": "team",
            "teamId": 39,
            "shortName": "Bucks",
            "abbreviation": "MIL"
          },
          {
            "type": "seasonYear",
            "seasonYear": 2025,
            "display": "2024-25"
          }
        ],
        "stats": {
          "PointsPerGame": { "value": 30.3880597, "display": "30.4" },
          "GamesPlayed": { "value": 67, "display": "67" },
          "Points": { "value": 2036, "display": "2,036" }
        }
      }
    ]
  }
}

The player shape

Returned when the question resolves to a player rather than a stats query, typically a name-only question like tiger woods or kareem abdul-jabbar.

type PlayerAskResponse = {
  type: "player";
  input: { original: string };
  answer: { text: string; markdown: string };
  query: { playerId: number };
  data: {
    player: { playerId: number; longName: string };
  };
};

data.player is the player’s identity: the same { playerId, longName } fields the player context items carry in stats results. Additional profile sections will be added alongside data.player over time; new fields there are additive, so ignore what you don’t recognize.

{
  "type": "player",
  "input": {
    "original": "Kareem Abdul-Jabbar"
  },
  "answer": {
    "text": "Kareem Abdul-Jabbar played 20 seasons for the Lakers and Bucks. He averaged 24.6 points, 11.2 rebounds, 3.6 assists and 2.6 blocks in 1,560 regular-season games.",
    "markdown": "[Kareem Abdul-Jabbar](https://www.statmuse.com/nba/player/kareem-abdul-jabbar-2) played 20 seasons for the [Lakers](https://www.statmuse.com/nba/team/los-angeles-lakers-franchise-15/history) and [Bucks](https://www.statmuse.com/nba/team/milwaukee-bucks-franchise-39/history). He averaged 24.6 points, 11.2 rebounds, 3.6 assists and 2.6 blocks in 1,560 regular-season games."
  },
  "query": { "playerId": 2 },
  "data": {
    "player": { "playerId": 2, "longName": "Kareem Abdul-Jabbar" }
  }
}

The team shape

Returned when the question resolves to a team, such as arsenal 2023 or houston rockets. Never returned for pga.

type TeamAskResponse = {
  type: "team";
  input: { original: string };
  answer: { text: string; markdown: string };
  query: { teamId: number };
  data: {
    team: { teamId: number; shortName: string; abbreviation: string };
  };
};

data.team is the team’s identity: the same { teamId, shortName, abbreviation } fields the team context items carry in stats results. As with players, richer sections will be added alongside data.team over time.

{
  "type": "team",
  "input": {
    "original": "Arsenal 2023"
  },
  "answer": {
    "text": "Arsenal were 2nd in the Premier League in 2022-23, with a record of W26 D6 L6.",
    "markdown": "[Arsenal](https://www.statmuse.com/fc/team/2022-23-arsenal-6/2023) were 2nd in the Premier League in 2022-23, with a record of W26 D6 L6."
  },
  "query": { "teamId": 6 },
  "data": {
    "team": { "teamId": 6, "shortName": "Arsenal", "abbreviation": "ARS" }
  }
}

The unknown shape

Returned when the question doesn’t resolve to any structured shape: opinion questions, general knowledge, history StatMuse doesn’t cover. Only input and answer are present.

{
  "type": "unknown",
  "input": {
    "original": "Where did LeBron go to high school?"
  },
  "answer": {
    "text": "LeBron James attended high school at St. Vincent-St. Mary (OH).",
    "markdown": "[LeBron James](https://www.statmuse.com/nba/player/lebron-james-1780) attended high school at St. Vincent-St. Mary (OH)."
  }
}