StrikerAPI
StrikerAPI v1.0.0
Soccer data and stats
From the developer
Declared capabilities
- Look up clubs, players and matches across many leagues
- Read league tables, schedules and results
- Read lineups, match events and shot maps
Cost & access
StrikerAPI does not sell anything through ChatGPT. The plugin is read-only: it has no checkout, purchase, subscription or credit top-up flow.
Declared limitations
- Place a wager: wagering is not supported
- Out of coverage: another sport
- Account and billing change: not supported
Onboarding example
Show the 2025-26 Premier League table.
Sources & dates
Developer declarations; not independently tested. Listing last checked Nov 7, 2026. Package observed Nov 6, 2026.
Description
From the marketplace listing
StrikerAPI connects ChatGPT and Codex to soccer data from StrikerAPI. It covers the Premier League, MLS, La Liga, Serie A, Bundesliga, Ligue 1, the UEFA competitions and other leagues, with lineups, match events, shot maps and expected goals. Ask for league tables, schedules and results, lineups, match events, player stats and leaders, team ratings, head-to-head history, shot maps with expected goals, sportsbook odds and player prop lines. The plugin looks the answer up with read-only tools and reports what the data says, including the season, date and source of each number. The first time you use it, you sign in with your StrikerAPI account. Limits: StrikerAPI is read-only. It cannot place wagers, accept or track bets, or edit your account. Odds and prop lines are shown as information about the market, not as advice. Data comes from public sources and the StrikerAPI pipeline and is not guaranteed to be error-free or current to the minute, so do not rely on it as the sole basis for financial decisions. Ratings shown are StrikerAPI's own Elo-style ratings, not official rankings. Not affiliated with any league or club. Bundled skills teach the model how to choose the right tool for a question and how to explain results.
Language: English · Automatically detected from descriptions.
Matches for “explain code”
Exact text from the indicated source. A mention alone does not establish support for your task.
Publisher full description
StrikerAPI connects ChatGPT and Codex to soccer data from StrikerAPI. It covers the Premier League, MLS, La Liga, Serie A, Bundesliga, Ligue 1, the UEFA competitions and other leagues, with lineups, match events, shot maps and expected goals. Ask for league tables, schedules and results, lineups, match events, player stats and leaders, team ratings, head-to-head history, shot maps with expected goals, sportsbook odds and player prop lines. The plugin looks the answer up with read-only tools and reports what the data says, including the season, date and source of each number. The first time you use it, you sign in with your StrikerAPI account. Limits: StrikerAPI is read-only. It cannot place wagers, accept or track bets, or edit your account. Odds and prop lines are shown as information about the market, not as advice. Data comes from public sources and the StrikerAPI pipeline and is not guaranteed to be error-free or current to the minute, so do not rely on it as the sole basis for financial decisions. Ratings shown are StrikerAPI's own Elo-style ratings, not official rankings. Not affiliated with any league or club. Bundled skills teach the model how to choose the right tool for a question and how to explain results.
Publisher description
StrikerAPI brings soccer data into ChatGPT and Codex with read-only tools and workflow skills: league tables, schedules and results, lineups, match events, player stats and leaders, team ratings, head-to-head history, shot maps with expected goals, sportsbook odds and player prop lines. Sign in with your StrikerAPI account.
Changes
No changes recorded yet. Follow this plugin to keep track of future changes.
First seen Oct 30, 2026. Last seen Nov 7, 2026.
Similar plugins
Find competitors to follow as you develop your plugin.
-
BirdieAPI brings golf data into ChatGPT and Codex with read-only tools and workflow skills: tournament schedules and leaderboards, scorec...
Shared terms: stat, accept, advice, basis
-
AcesAPI brings tennis data into ChatGPT and Codex with read-only tools and workflow skills: tournaments and draws, schedules and results,...
Shared terms: stat, accept, advice, basis
-
FastballAPI brings MLB baseball data into ChatGPT and Codex with read-only tools and workflow skills: standings, schedules and scores, pl...
Shared terms: stat, accept, advice, basis
-
FighterAPI brings MMA data into ChatGPT and Codex with read-only tools and workflow skills: event cards and schedules, fight results and ...
Shared terms: stat, accept, advice, basis
-
EndzoneAPI brings NFL football data into ChatGPT and Codex with read-only tools and workflow skills: standings, schedules and results, pl...
Shared terms: stat, accept, advice, basis
Keywords
Files & skills
File archives
Skill instructions
dispatch6.23 KB
---
name: dispatch
description: "Routes a soccer data or analytics request to the right 2-3 skills. Load this FIRST when a request comes in and you are unsure which of the 16 skills to activate. Prevents loading every skill when only two or three are needed. Do not use when the request already names one skill or one tool."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Skill Dispatch Guide
Match the request to a pattern below, load those skills, and stop. Always load `strikerapi-tool` alongside any skill that needs data; it owns tool names, credit costs and the `{"data": ...}` envelope.
## Persona detection
| Signal | Persona | Start with |
|--------|---------|-----------|
| "What is on this weekend?" / exploring | Explorer | `match-lookup`, `odds-explorer` |
| "Build me a model" / "predict scores" | Builder | `poisson-score-models`, `walk-forward-validation` |
| "Who is scoring?" / "scout this player" | Scout | `player-scouting`, `xg-analysis` |
| "Is my model any good?" | Validator | `walk-forward-validation`, `probability-calibration` |
| "I am new to soccer analytics" | Learner | `xg-analysis`, `elo-ratings` |
## Request patterns
### "What matches are on?" / "Results from last weekend" / "Show me the lineup"
`match-lookup` (list_games, get_schedule, get_game, get_lineups)
### "How is Arsenal doing?" / "Table" / "Home and away form"
`team-analysis` (get_standings, get_team_stats, get_head_to_head)
### "Tell me about Saka" / "Top scorers" / "Compare two forwards"
`player-scouting` (search_players, get_player, get_leaders)
### "What are the odds?" / "Best price on the draw" / "How did the line move?"
`odds-explorer`. If the question turns to true probabilities or margin, add `odds-analysis`.
### "Remove the vig" / "Implied probability" / "Shin" / "Fair odds for the draw"
`odds-analysis`
### "Preview Liverpool vs City"
`match-preview` (pulls form, xG, Elo, head to head and the line). Add `xg-analysis` for shot detail.
### "Shot map" / "xG table" / "Who is overperforming their xG?"
`xg-analysis`
### "Rate the teams" / "Elo" / "Who is strongest?"
`elo-ratings`
### "Predict the score" / "Poisson" / "Dixon-Coles" / "Over 2.5 probability"
`poisson-score-models`. Add `elo-ratings` if ratings are the input, `probability-calibration` before trusting the output.
### "Will Haaland score?" / "Anytime goalscorer" / "Price a scorer"
`goalscorer-prop-modeling`, with `player-scouting` for the player and `xg-analysis` for shot volume. Only seven competitions have prices.
### "Is my model calibrated?" / "Brier" / "Ranked probability score"
`probability-calibration`
### "Is cross-validation okay?" / "Did I leak the future?"
`walk-forward-validation`
### "Backtest this" / "Closing line value" / "Would this have made money?"
### "Which tool do I call?" / "What does this cost?" / "REST or MCP?"
`strikerapi-tool` only.
## Credit warning gates
Ask the user before any plan that costs more than about 200 credits. Common big ones: a season of `get_odds` (2 credits per match, 760 for a 380-match league), `get_game` in a loop (5 each), `get_events` in a loop (10 each), and `get_prop_history` for many players (10 each).
## When NOT to use this guide
Single-skill requests do not need routing. "Devig +290 / +250 / -118" goes straight to `odds-analysis`.
## What every answer should do
1. Say which competition and season the numbers cover. The default is the Premier League and the latest season.
2. State the credits spent.
3. Treat any edge as an estimate. Warn about variance, small samples and closing-line value, and never promise returns.
## The 16 skills at a glance
| Skill | Use it for |
|-------|-----------|
| `strikerapi-tool` | Tool names, credits, REST and MCP access, the `{"data": ...}` envelope |
| `match-lookup` | Fixtures, results, box scores, events, lineups |
| `team-analysis` | Table, form, xG for and against, head to head |
| `player-scouting` | Player ids, per-90 rates, leaders, match logs |
| `odds-explorer`Preview of the first 4,000 characters. Read full instructions →
elo-ratings8.18 KB
---
name: elo-ratings
description: "Reads and builds soccer Elo ratings: pulls StrikerAPI's club ratings, converts a rating gap and home bonus into expected score and win/draw/loss probabilities, and builds a custom Elo from match results with tuned K, home advantage, goal-difference scaling and season carryover. Use when the user asks who is strongest, wants ratings as of a date, wants win probabilities from ratings, or wants to build or tune an Elo system. Do not use for score-distribution models, see poisson-score-models. Do not use for league tables, see team-analysis."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Elo Ratings
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_ratings` (2 credits) returns the ratings; `list_games` (2 credits per call of up to 200 matches) supplies results for a custom build.
Elo summarizes a club's strength as one number updated after every result. It is a good baseline: stable, cheap, and hard to beat by much with simple models. It does not know about lineups, injuries, rest, or shot quality.
## When to Use
- "Who is the strongest team in the league?"
- "What did the ratings look like on 1 January?"
- "Turn this rating gap into win probabilities"
- Building or tuning a custom Elo for a league or for a model feature
## When NOT to Use
- Full scoreline distribution, totals, handicaps: `poisson-score-models`
- Current table and form: `team-analysis`
- Calibration of whatever you build: `probability-calibration`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `get_ratings` | Elo ratings, strongest first. `date` for as-of ratings, `limit` for count (default 50, max 200), `league` | 2 |
| `list_games` | Results for a custom build. `season`, `from`, `to`, `status`, `limit` up to 200, `offset` | 2 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_elo`, `get_team_rating` | `get_ratings` and pick the club's row |
| `get_rating_history` | Call `get_ratings` with different `date` values, or rebuild from `list_games` |
| `get_power_rankings` | `get_ratings` |
| Cross-league ratings | Not available. A rating moves only on its own competition's matches |
## The StrikerAPI Rating
The `get_ratings` response states its method: Elo from every final match in the competition, K of 20, a home advantage of 60 points (none at neutral venues), scaled by goal difference, and a third of the way back toward 1500 between seasons. A 400-point gap means 10-to-1 odds, and a 100-point gap is about a 64% expected score for the stronger side at a neutral venue.
```
get_ratings {"limit": 4}
```
```
as_of 2026-10-10
1 MNC Manchester City 1670.4 last game 2026-09-20
2 ARS Arsenal 1663.0 last game 2026-10-10
3 BHA Brighton 1586.5 last game 2026-10-10
4 LIV Liverpool 1578.0 last game 2026-09-20
```
Pass `league` for another competition. In MLS the same call, `get_ratings {"league": "mls", "limit": 2}`, returned Nashville SC (1651.7) and Inter Miami (1609.5) as of 2026-10-11. Those numbers are not comparable to the Premier League's: each competition has its own pool and its own 1500 anchor.
## Expected Score and Probabilities
Elo's expected score for the home side:
```
E_home = 1 / (1 + 10 ** (-(R_home - R_away + H) / 400)) H = 60 at a home venue, 0 if neutral
E_away = 1 - E_home
```
Expected score counts a draw as half a win. That is not a win probability. To split it into home, draw and away you need a draw model:
```
# Davidson model on the Elo scale
x = ln(10) * (R_home - R_away + H) / 400
p_home = exp( x / 2) / (exp(x / 2) + exp(-x / 2) + nu)
p_away = exp(-x / 2) / (exp(x / 2) + exp(-x / 2) + nu)
p_draw = nu / (exp(x / 2) + exp(-x / 2) + nu)
```
`nu` is one number that sets how often level teams draw. Fit it by maximum likelihood on past results for your league, then check calibration with `probability-calibration`. Draw rates diffePreview of the first 4,000 characters. Read full instructions →
goalscorer-prop-modeling11.5 KB
---
name: goalscorer-prop-modeling
description: "Models anytime goalscorer probabilities for soccer players and compares them with sportsbook prices: expected minutes and start probability, non-penalty xG per 90 with shrinkage, penalty duty, team goal expectation from the match market, one-sided price handling, voids, and backtests with get_prop_history. Use when the user asks who will score, whether a goalscorer price is fair, or how to build a scorer model. Available for the Premier League, MLS, La Liga, Serie A, Bundesliga, Ligue 1 and Champions League only. Do not use for team totals, see poisson-score-models."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Goalscorer Prop Modeling
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_player_props` (10 credits, or 0 with `estimate_only`) for the prices. `get_prop_history` (10 credits for up to 200 games) for one player's prices against results. `get_shot_map` (10) with `player` for shot quality. `get_player` (5) and `get_player_games` (5) for minutes and rates. `get_lineups` (5) for starters.
The anytime goalscorer market asks one question: will this player score at least once? It is the only player prop StrikerAPI carries. Prices are a Yes price per player, with no line. The structure of the market (one-sided, margin-heavy, voided when a player does not play) drives most of the method.
## Coverage
Anytime goalscorer prices exist for seven competitions: the Premier League (`soccer`), MLS (`mls`), La Liga (`laliga`), Serie A (`seriea`), the Bundesliga (`bundesliga`), Ligue 1 (`ligue1`) and the Champions League (`ucl`). Per the StrikerAPI README, the Premier League and MLS start in April 2024, Ligue 1 in May 2024, La Liga, Serie A and the Bundesliga in August 2024, and the Champions League in March 2025. DraftKings and FanDuel cover most matches, with Pinnacle and William Hill on some matches in 2026. There are no prices for the other ten competitions; other player markets (shots, assists, cards) do not exist.
## When to Use
- "What is the chance Haaland scores this weekend?"
- "Is +250 fair for this winger?"
- "Rank the likeliest scorers for a match"
- "How often did he score when priced under even money?"
## When NOT to Use
- Match results, totals, handicaps: `poisson-score-models`
- Player profiles without prices: `player-scouting`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `get_player_props` | Anytime goalscorer prices. `game_id` for every player in a game; or `player_id` with `from_date` (and `to_date`) for one player across games. `bookmaker`, `snapshot_type` (`closing` default or `opening`), `market`, `estimate_only` | 10 (game); 10 per game returned for a player |
| `get_prop_history` | One row per game: closing price (median across books, or one `bookmaker`), opening line, whether he scored, `result`, over rate. `from_date`, `to_date`, `limit` up to 200, `next_from_date` to continue | 10 for up to 200 games |
| `get_shot_map` | The player's shots with `xg`, `penalty`, `zone`, `body_part` | 10 |
| `get_player` | Per-season minutes, goals, xG, per-90 rates | 5 |
| `get_player_games` | Match log with minutes on and off | 5 |
| `get_lineups` | Starting XI and bench for a match | 5 |
| `search_players` | Player id | 1 |
For one player over many games, `get_prop_history` (10 credits for up to 200 games) is far cheaper than `get_player_props` with `player_id` (10 credits per game).
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_player_props` for shots, assists, cards, first scorer | Not available; only `player_goal_scorer_anytime` exists |
| `get_goalscorer_odds` | `get_player_props` |
| `get_penalty_takers` | Count `penalty: true` shots in `get_shot_map` with `player` |
| `get_expected_lineup`, `get_injuries` | Not available. `get_lineups` once teams are named |
## What a Price Row Looks Like
From `get_player_props {"game_id": "740968Preview of the first 4,000 characters. Read full instructions →
match-lookup7.28 KB
---
name: match-lookup
description: "Finds soccer fixtures and results and opens one match in full: score, box scores, xG, lineups, goals, cards, substitutions and VAR events, across 17 competitions. Use when the user asks who plays, what the score was, what happened in a match, who started, when a goal was scored, or for results by date, club, stage or season. Do not use for league tables or season averages, see team-analysis. Do not use for betting lines, see odds-explorer. Do not use for shot maps across many matches, see xg-analysis."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Match Lookup
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `list_games` (2 credits) finds matches. `get_schedule` (2) lists upcoming ones with a median line. `get_game` (5) opens one match. `get_lineups` (5) and `get_events` (10) go deeper.
You find the right match, then pull only as much detail as the question needs. Most mistakes here are wrong match ids, wrong competition, and paying 10 credits for events when the 5-credit box score already answered the question.
## When to Use
- "Who plays this weekend?" / "What are the fixtures for Arsenal?"
- "What was the score?" / "Results from last Saturday"
- "Who scored, and when?" / "Who came off the bench?"
- "What formation did they play?"
- Getting a `game_id` to feed another skill
## When NOT to Use
- League table, form, home and away records: `team-analysis`
- Season-long xG, shot maps for a club or player: `xg-analysis`
- Prices, line movement, best book: `odds-explorer`
- Player season totals and per-90 rates: `player-scouting`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `list_games` | Fixtures and results by `season`, `stage`, `date`, `from`/`to`, `team`, `status` | 2 |
| `get_schedule` | Upcoming fixtures, next `days` (1-30, default 7), median home/draw/away line | 2 |
| `get_game` | One match: score with shootout, both box scores, every player line, key events, each book's line | 5 |
| `get_lineups` | Formation, starting XI with positions, substitutes with minutes, unused bench | 5 |
| `get_events` | Every event in order. Filter with `kind`: goals, shots, cards, substitutions, set_pieces, fouls, all | 10 |
| `list_teams` | Club ids and abbreviations, to resolve a name | 1 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_match`, `get_fixture` | `get_game` for one match, `list_games` for many |
| `get_live_score` | Not available. `get_schedule` shows `status` and `status_detail` for matches today |
| `get_team_schedule` | `list_games` with `team` |
| `search_games` | `list_games` with `team`, `date`, `from`, `to` |
| `get_referee`, `get_injuries` | Not available |
## How It Works
**Step 1: Identify the competition.** The default is the Premier League. For anything else pass `league` (`mls`, `laliga`, `seriea`, `bundesliga`, `ligue1`, `ucl`, and so on). A `game_id` is competition-scoped: passing a Champions League id without `league` set to `ucl` will not find it.
**Step 2: Find the match.**
```
list_games {"team": "ARS", "season": 2025, "status": "final", "limit": 5}
```
- `status` is `scheduled` or `final`. Results come back newest first.
- `stage: "league"` is league-table games (regular season, group stage, league phase). `stage: "knockout"` is qualifying, knockout rounds and playoffs.
- Page with `offset`, using the `next_offset` the response returns. `limit` goes up to 200.
- `date`, `from` and `to` are UTC. An evening kickoff in the Americas can land on the next UTC date.
**Step 3: Pick the lightest call that answers it.**
| Question | Call |
|----------|------|
| Score, winner | The `home.score`, `away.score` and `result` (`H`, `D`, `A`) already in `list_games` |
| Team stats, xG, who played | `get_game` |
| Who scored and assisted | `get_game` `key_events`, or `get_events` with `kind: "goals"` |
| Shots with location | `get_events` with `kind: Preview of the first 4,000 characters. Read full instructions →
match-preview6.86 KB
---
name: match-preview
description: "Builds a pre-match preview for one soccer fixture by combining league position, form, xG for and against, Elo ratings, head to head, lineups when available and the market line, with a credit budget. Use when the user asks for a preview, a matchup breakdown, who is favored and why, or what to know before a specific fixture. Do not use for a post-match recap, see match-lookup. Do not use for a whole-slate card with many fixtures."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Match Preview
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> A full preview costs about 20 credits: `get_schedule` 2, `get_standings` 2, `get_team_stats` 5, `get_ratings` 2, `get_head_to_head` 2, plus `get_odds` 5 for each book's price. Add `get_lineups` 5 and `get_shot_map` 10 per club only when asked.
This is a compound skill. It does not introduce new data; it sequences the calls from `team-analysis`, `elo-ratings`, `odds-explorer` and `xg-analysis` in the cheapest order and assembles one readable page.
## When to Use
- "Preview Liverpool vs Manchester City"
- "What should I know before Saturday's Arsenal match?"
- "Who is favored and why?"
- Preparing a matchday post or newsletter
## When NOT to Use
- A match that already finished: `match-lookup`
- Season-long club review: `team-analysis`
- Ten fixtures at once: run this per fixture only after costing it; a weekend of 10 matches is about 200 credits
## Commands Used
| Step | Command | Credits |
|------|---------|---------|
| Find the fixture and its median line | `get_schedule` (with `team`) | 2 |
| Table position, home and away, form | `get_standings` | 2 |
| xG for and against, whole league | `get_team_stats` (no `team`) | 5 |
| Elo and its gap | `get_ratings` | 2 |
| Meetings in this competition | `get_head_to_head` | 2 |
| Each book's price | `get_odds` with `game_id` | 5 |
| Formations (only once published) | `get_lineups` | 5 |
| Shot profile | `get_shot_map` with `team` | 10 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_preview`, `get_prediction` | Assemble from the calls above. StrikerAPI provides no match forecast; any probability you state is your model's or the market's |
| `get_injuries`, `get_suspensions` | Not available. Say availability is unknown, or read `get_lineups` once lineups exist |
| `get_referee`, `get_weather` | Not available |
| `get_team_form` | The `form` field in `get_standings` |
## How It Works
**Step 1: Locate the fixture.**
```
get_schedule {"team": "LIV", "days": 7}
```
The row gives `game_id`, `starts_at`, venue, and `line` (median `home_ml`, `draw_ml`, `away_ml`, `total`, `home_handicap`, and `implied`).
**Step 2: Table and form.** One `get_standings` call; read both clubs' `rank`, `points`, `home`, `away`, `form`.
**Step 3: Underlying numbers.** One `get_team_stats` call without `team` returns all clubs. Take both clubs' `xg_for`, `xg_against`, `shots_for`, `shots_against`, and compute xG difference per match.
**Step 4: Ratings.** One `get_ratings` call (use `limit` of 50 or more so both clubs appear). The Elo difference plus the home bonus gives an expected score; see `elo-ratings` for the formula.
**Step 5: History.** `get_head_to_head` for the pair. Weight the last three or four meetings over the lifetime record, and say how many meetings that is.
**Step 6: The market.** The schedule `line.implied` values are the raw prices converted to probabilities, so they sum to more than 1. Remove the margin (see `odds-analysis`) before quoting them as the market's view. For a per-book view add `get_odds` with the `game_id`.
**Step 7: Lineups.** `get_lineups` only returns something useful once clubs have named their teams. Check the response before building anything on it. If it is empty, say lineups are not out.
## Worked Example
Premier League, 11 October 2026. The `get_schedule` example in the StrikerAPI docs shows Liverpool at home to MPreview of the first 4,000 characters. Read full instructions →
odds-analysis7.65 KB
---
name: odds-analysis
description: "Converts soccer odds between American, decimal and fractional formats and removes the bookmaker margin from three-way (home/draw/away) markets to get no-vig probabilities, using proportional, power and Shin methods, plus two-way devigging for totals and handicaps. Use when the user asks about devigging, implied probability, overround, fair odds, no-vig lines, the draw's true price, or the favorite-longshot bias. Do not use for browsing current odds, see odds-explorer."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Odds Analysis
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_odds` (5 credits for one match) returns each book's open and close with `close_prob`, the no-margin probabilities. `get_schedule` (2) returns a median line. For your own odds CSV the math below needs no credits.
## When to Use
- "What is the true probability of the draw at +250?"
- "Remove the vig from +290 / +250 / -118"
- Converting decimal 3.90 to American, or to a probability
- Comparing a soft book against Pinnacle or an exchange
- Working out how much margin a book charges
## When NOT to Use
- Browsing prices and finding the best one: `odds-explorer`
- Model calibration: `probability-calibration`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `get_odds` | Per-book three-way prices, handicap, total, open and close, `close_prob` with `overround` | 5 (one match) |
| `get_schedule` | Median line and raw `implied` for upcoming fixtures | 2 |
| `get_line_movement` | Pre-kickoff snapshots, for devigging the open | 10 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_fair_odds`, `get_no_vig_odds` | `close_prob` in `get_odds`, or compute below |
| `get_implied_probability` | Compute with the formulas here |
| `get_btts_odds`, `get_correct_score_odds` | Not available; only the three-way moneyline, goal handicap and total |
## Conversion
```
American +x -> decimal = 1 + x / 100 implied = 100 / (x + 100)
American -x -> decimal = 1 + 100 / x implied = x / (x + 100)
decimal d -> implied = 1 / d
fractional a/b -> decimal = 1 + a / b
```
Examples: `+290` is decimal 3.90 and implied 25.6%. `-118` is decimal 1.847 and implied 54.1%. Always say which format you are in; StrikerAPI returns American.
## Three-Way Devigging
Take implied probabilities `p_h`, `p_d`, `p_a`. Their sum `B` is above 1, and `overround = B - 1`.
### 1. Proportional (multiplicative)
```
fair_i = p_i / B
```
Fast and the default. It removes the same percentage from every outcome, which understates the favorite-longshot effect.
### 2. Power
Find the exponent `k` so that `sum(p_i ** k) = 1`, then `fair_i = p_i ** k`. It shrinks longshots more than proportional.
### 3. Shin
Models the margin as protection against a share `z` of insider money. Solve for `z` so the fair probabilities sum to 1:
```python
from math import sqrt
def shin(implied):
"""Shin devig for any number of outcomes. implied: list of raw implied probabilities."""
B = sum(implied)
def fair(z):
return [(sqrt(z * z + 4 * (1 - z) * x * x / B) - z) / (2 * (1 - z)) for x in implied]
lo, hi = 0.0, 0.4
for _ in range(100):
z = (lo + hi) / 2
if sum(fair(z)) > 1:
lo = z
else:
hi = z
return fair(z), z
```
Shin moves probability from longshots to favorites compared with proportional, and returns `z`, an estimate of the insider share, which behaves like a margin score.
### 4. Additive
`fair_i = p_i - (B - 1) / 3`. Can go negative on longshots. Do not use it on skewed markets.
## Worked Example
888sport's close for Crystal Palace v Arsenal, from `get_odds {"game_id": "740968"}`: home `+290`, draw `+250`, away `-118`.
```
implied: home 0.2564 draw 0.2857 away 0.5413 sum 1.0834 (overround 8.3%)
proportional: home 0.2367 draw 0.2637 awaPreview of the first 4,000 characters. Read full instructions →
odds-explorer8.24 KB
---
name: odds-explorer
description: "Compares soccer three-way moneylines (home, draw, away), goal handicaps and totals across sportsbooks, finds the best price on each outcome, reads overround and line movement, and checks opening versus closing lines. Use when the user asks about the odds on a match, the best price for a draw, which book is sharpest, or how a line moved before kickoff. Do not use for removing the margin or true probabilities, see odds-analysis. Do not use for goalscorer prices, see goalscorer-prop-modeling."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Odds Explorer
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_schedule` (2 credits) for the median line on upcoming fixtures. `get_odds` with `game_id` (5) for every book on one match, with `date` (10) for a day, with `season` (2 per match) for a block. `get_line_movement` (10) for pre-kickoff snapshots.
Soccer is a three-way market: home win, draw, away win. A two-outcome habit from other sports, such as comparing only the favorite and underdog, throws away the draw, which is about a quarter of matches. This skill reads the whole triple.
## When to Use
- "What are the odds on Liverpool against City?"
- "Which book has the best price on the draw?"
- "How much margin is each book charging?"
- "Did the line move toward the home side?"
- "What was the closing line for this finished match?"
## When NOT to Use
- Converting prices to fair probabilities: `odds-analysis`
- Anytime goalscorer prices: `goalscorer-prop-modeling`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `get_schedule` | Upcoming fixtures with `line`: books count, median `home_ml`, `draw_ml`, `away_ml`, `total`, `home_handicap`, `implied` | 2 |
| `get_odds` | Per-book three-way moneyline, handicap, total, with open and close, and for finished matches the outcome | 5 (`game_id`), 10 (`date`), 2 per match (`season`) |
| `get_line_movement` | Time series of each book's `home_ml`, `draw_ml`, `away_ml`, `home_handicap`, `total` before kickoff | 10 |
| `get_game` | Includes each book's opening and closing line inside a full match (5) | 5 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_live_odds` | `get_odds` for a match, `get_schedule` for the median line. No in-play prices |
| `get_best_odds` | Compare the `books` array from `get_odds` yourself |
| `get_btts_odds`, `get_corners_odds`, `get_card_odds` | Not available. The markets are three-way moneyline, goal handicap and goal total |
| `get_closing_line` | The `*_close` fields in `get_odds` |
| `get_public_betting` | Not available. Infer from movement only, cautiously |
## What the Prices Look Like
Moneylines are American odds. A home price of `+290` risks 100 to win 290. A price of `-118` risks 118 to win 100. The three prices for one book sum to more than 100% implied, and the excess is the overround.
`get_odds` returns, per match, a `books` array. Per book:
| Field | Meaning |
|-------|---------|
| `provider`, `source` | Book name; `the_odds_api` or `espn` |
| `home_ml_open`, `home_ml_close` (and `draw_`, `away_`) | Opening and closing moneyline. ESPN rows often have `null` opens |
| `close_prob` | No-margin home, draw and away probabilities plus `overround` |
| `home_handicap_*`, `total_*`, `over_odds`, `under_odds` | Goal handicap and total where posted. Many Odds API rows have `null` here |
| `captured_at` | When the row was captured. For ESPN rows on old matches it can be well after the match, so it is not a kickoff timestamp |
For a finished match there is also `outcome`: `result` (`H`, `D`, `A`), `median_total`, `median_home_handicap`, `over`, `home_covered`.
## How It Works
**Step 1: Get the match id.** `get_schedule` for upcoming, `list_games` (see `match-lookup`) for past.
**Step 2: Pull every book.**
```
get_odds {"game_id": "740968"}
```
**Step 3: Find the best price per outcome.** IndependentPreview of the first 4,000 characters. Read full instructions →
player-scouting7.26 KB
---
name: player-scouting
description: "Scouts soccer players: finds ids, builds per-season and per-90 profiles for goals, assists, shots, xG and goalkeeping, reads match logs and minutes, ranks league leaders and compares players. Use when the user names a player, asks who the top scorers or creators are, wants to compare forwards, or asks whether a player is finishing above his xG. Do not use for team tables, see team-analysis. Do not use for goalscorer prices, see goalscorer-prop-modeling. Do not use for shot-by-shot locations, see xg-analysis."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Player Scouting
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `search_players` (1 credit) to find the id. `get_player` (5) for the profile and per-season rates. `get_player_games` (5) for the match log. `get_leaders` (5) for league-wide rankings.
You find the right player, then judge him on rates and minutes rather than raw totals, and you say how much evidence you have.
## When to Use
- "Tell me about Erling Haaland" / "How has Saka's season gone?"
- "Top scorers by xG per 90"
- Comparing two players across seasons
- Checking whether a striker is over- or under-finishing
- Goalkeepers: saves and clean sheets
## When NOT to Use
- Goalscorer prices or props: `goalscorer-prop-modeling`
- Where a player's shots come from: `xg-analysis` (`get_shot_map` with `player`)
- A club's table position: `team-analysis`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `search_players` | Find a player by name (accents optional), optionally within `team`. Returns id, position, club, last season, appearances | 1 |
| `get_player` | Profile, per-season appearances, starts, minutes, goals, assists, shots, our xG, cards, goalkeeping, per-90 rates, last 10 matches | 5 |
| `get_player_games` | Match log newest first: opponent, score, minutes on and off, goals, assists, shots, xG, fouls, cards | 5 |
| `get_leaders` | Season leaders. `stat`: goals, assists, goal_contributions, shots, shots_on_target, xg, yellow_cards, red_cards, saves, clean_sheets. `per90`, `min_games`, `limit` | 5 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_player_stats` | `get_player` |
| `get_top_scorers` | `get_leaders` with `stat` set to `goals` |
| `compare_players` | Call `get_player` twice and compare per-90 rows |
| `get_player_xg` | `xg` fields in `get_player`, or `get_shot_map` with `player` |
| `get_market_value`, `get_injuries`, `get_transfers` | Not available |
| `get_assists_expected` (xA) | Not available. Assists are counted, expected assists are not provided |
## How It Works
**Step 1: Get the id.** `get_player` takes an ESPN player id, not a name.
```
search_players {"name": "Haaland"}
```
Returns `player_id` 253989, Forward, Manchester City, 137 appearances. A common surname returns several rows; narrow with `team`.
**Step 2: Pull the profile.**
```
get_player {"player_id": "253989"}
```
Each season row carries `appearances`, `starts`, `minutes`, `goals`, `assists`, `shots`, `shots_on_target`, `xg`, and the per-90 rates `goals_per90`, `assists_per90`, `shots_per90`, `xg_per90`.
**Step 3: Normalize and compare.** Totals reward minutes. Per-90 rewards role. Use both:
```
finishing gap = goals - xg (positive = above expectation)
shot quality = xg / shots
conversion = goals / shots
minutes share = minutes / (team matches x 90) (role security)
```
**Step 4: Check the sample.** A season of 2,000+ minutes carries real signal on shot volume and location. Goals over xG does not: the standard error of a season goal total around its xG is roughly the square root of the xG, so a striker on 20 xG can land anywhere from about 11 to 29 goals on luck alone. Treat a one-season gap under about 4 goals as noise. Persistent over-performance across three or more seasons is more credible, and the best strikers do hold Preview of the first 4,000 characters. Read full instructions →
poisson-score-models10.5 KB
---
name: poisson-score-models
description: "Builds soccer score models: independent Poisson goals from attack and defence strengths, the Dixon-Coles low-score correction with time decay, scoreline matrices, and the home/draw/away, over/under and handicap probabilities that fall out of them, validated against closing odds. Use when the user wants to predict scores, price totals or handicaps, fit team strengths, or turn xG or Elo into match probabilities. Do not use for rating-only win probabilities, see elo-ratings. Do not use for goalscorer probabilities, see goalscorer-prop-modeling."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Poisson Score Models
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `list_games` (2 credits per call, up to 200 matches) supplies scores. `get_team_stats` (5) supplies xG for and against. `get_odds` (5 per match, 2 per match by season) supplies the benchmark.
Goals in soccer are rare, roughly independent events, which is why a Poisson distribution fits them tolerably well. A score model predicts a goal rate for each side and turns the two rates into a full scoreline matrix. From that one matrix you get every market: home/draw/away, totals, handicaps and exact score.
## When to Use
- "What is the probability Arsenal win 2-1?" / "P(over 2.5)?"
- "Fit attack and defence strengths for the league"
- "Turn xG or Elo into match probabilities"
- Producing a model probability to compare with a devigged market
## When NOT to Use
- A single rating-based expected score: `elo-ratings`
- Anytime goalscorer pricing: `goalscorer-prop-modeling` (player-level, different structure)
- Evaluating a finished model: `walk-forward-validation`, `probability-calibration`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `list_games` | Scores by `season`, `status: "final"`, `limit` 200, `offset`; the training data | 2 |
| `get_team_stats` | `goals_for`, `goals_against`, `xg_for`, `xg_against` per match, all clubs | 5 |
| `get_ratings` | Elo input | 2 |
| `get_odds` | Closing three-way prices, handicap and total, for benchmarking | 5 or 2 per match |
| `get_schedule` | Fixtures to predict, with the median line | 2 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_prediction`, `get_forecast` | Fit the model yourself with the code below |
| `get_btts`, `get_correct_score_odds` | Not available. Both-teams-to-score and correct-score prices are not provided, so those outputs cannot be benchmarked here |
| `get_expected_lineup` | Not available |
## The Model
For home club `i` against away club `j`:
```
lambda_home = exp(attack_i + defence_j + home_advantage) goals the home side is expected to score
mu_away = exp(attack_j + defence_i) goals the away side is expected to score
P(home = x, away = y) = Poisson(x; lambda) * Poisson(y; mu) * tau(x, y)
```
`attack` is high for strong attacks. `defence` is high for leaky defences (it adds to the opponent's goals). Fix the average of each set to zero so the model is identified.
**Independent Poisson** sets `tau = 1`. It underestimates 0-0 and 1-1 and overestimates 1-0 and 0-1.
**Dixon-Coles** corrects the four low scores with a single parameter `rho`:
```
tau(0,0) = 1 - lambda * mu * rho tau(0,1) = 1 + lambda * rho
tau(1,0) = 1 + mu * rho tau(1,1) = 1 - rho
tau = 1 otherwise
```
`rho` is usually slightly negative: more 0-0 and 1-1 than independence implies.
**Time decay** weights each match by `exp(-xi * days_ago)`. A half-life of a year or so (`xi` near 0.0019 per day) is a common starting point; tune it.
## Fitting
Training data is cheap. A Premier League season is 380 matches: two `list_games` calls, 4 credits.
```python
rows = []
for off in (0, 200):
rows += call("list_games", season=2025, status="final", limit=200, offset=off)["games"]
```
Then fit by weighted maximum likelihood. Tested againsPreview of the first 4,000 characters. Read full instructions →
probability-calibration8.68 KB
---
name: probability-calibration
description: "Checks and fixes whether soccer model probabilities mean what they say: per-class reliability for home, draw and away, ranked probability score, log loss, multiclass Brier, and Platt, isotonic or temperature scaling for three-way outputs. Use when the user asks if their probabilities are calibrated, why the model is overconfident, how to fix the draw, or whether to trust a 60% number. Do not use for building the model, see poisson-score-models or elo-ratings. Do not use for the walk-forward split, see walk-forward-validation. Do not use for devigging, see odds-analysis."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Probability Calibration
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> Calibration works on your model's out-of-sample predictions plus outcomes. Outcomes come from `list_games` (2 credits per call); the market benchmark from `get_odds` (5 per match, 2 per match by season).
## When to Use
- "Are my win probabilities calibrated?"
- "The model is overconfident on favorites"
- "My draws are always too low"
- Picking between a raw model, a scaled model and the market
- Before computing any edge
## When NOT to Use
- Fitting the underlying model: `poisson-score-models`, `elo-ratings`
- Designing the out-of-sample split: `walk-forward-validation`
- Converting prices to probabilities: `odds-analysis`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `list_games` | Outcomes (`result` H, D or A, scores) | 2 per call |
| `get_odds` | Market close and `close_prob` as a benchmark | 5 or 2 per match |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_model_probabilities`, `get_predictions` | StrikerAPI provides none; you supply the model output |
| `get_calibration` | Compute it from the code below |
## Inputs
A table with one row per match, with out-of-sample predictions (never in-sample):
```
match_id, date, p_home, p_draw, p_away, result (result in {H, D, A})
```
Probabilities must sum to 1. Check it. Everything below assumes the predictions came from a walk-forward run.
## Metrics
```python
import numpy as np
def log_loss(P, y): # P: (n, 3) probabilities in order H, D, A; y: indices 0, 1, 2
return -np.mean(np.log(np.clip(P[np.arange(len(y)), y], 1e-12, 1)))
def brier(P, y):
O = np.eye(3)[y]
return np.mean(((P - O) ** 2).sum(axis=1))
def rps(P, y):
O = np.eye(3)[y]
cum_p, cum_o = P.cumsum(axis=1)[:, :2], O.cumsum(axis=1)[:, :2]
return np.mean(((cum_p - cum_o) ** 2).sum(axis=1) / 2)
```
| Metric | Reads as | Notes |
|--------|----------|-------|
| Log loss | Penalizes confident misses | Sensitive to extremes; clip |
| Multiclass Brier | Mean squared error on the triple | Robust |
| RPS | Ordered Brier on cumulative outcomes | Standard for soccer; lower is better |
Always report the same metric for the market (devigged close) on the same matches. The absolute number matters less than the gap.
## Reliability, Per Class
Calibration is checked for each class separately. For home win:
1. Bin matches by `p_home` (deciles, or fewer when n is small).
2. In each bin, compare the mean predicted probability to the observed home-win frequency.
3. Plot observed against predicted with a confidence interval (`sqrt(p (1 - p) / n)` per bin).
Repeat for the draw and away win.
```python
def reliability(p, hit, bins=10):
edges = np.quantile(p, np.linspace(0, 1, bins + 1))
idx = np.clip(np.digitize(p, edges[1:-1]), 0, bins - 1)
rows = []
for b in range(bins):
m = idx == b
if m.sum():
rows.append((p[m].mean(), hit[m].mean(), int(m.sum())))
return rows # (mean predicted, observed rate, count)
```
Expected calibration error is the count-weighted mean of the absolute gap; report it with the bin counts, since 380 matches in ten bins is 38 each and each bin's rate has a staPreview of the first 4,000 characters. Read full instructions →
strikerapi-tool8.11 KB
---
name: strikerapi-tool
description: "Default data source for the StrikerAPI skills. Routes every request for soccer results, lineups, box scores, events, shot maps, xG, Elo ratings, three-way sportsbook odds and anytime goalscorer prices to one of 19 tools across 17 competitions. Use when any other skill needs data, or when the user asks which tool to call, what a call costs, or how to hit the REST API."
metadata:
version: 1.0.0
author: StrikerAPI
user-invocable: false
---
# StrikerAPI Tool
> Connection: this plugin reaches the data through its MCP server, which the user connects with a normal OAuth sign-in. Never ask the user for an API key, token or password, and never put one in a tool argument.
Every other skill in this pack gets its data here. This skill owns the 19 tools, their credit costs, the response envelope, and the rules that keep a request cheap and correct.
- Full reference with example responses: https://strikerapi.com/docs
## The response envelope
Every REST response is wrapped as `{"data": ...}`. Unwrap it before reading fields. Over MCP the tool result carries the same payload.
## The 19 tools
| Tool | What it returns | Credits | Skills that use it |
|------|-----------------|---------|--------------------|
| `list_teams` | Club ids, abbreviations, colours for a season | 1 | team-analysis, match-lookup |
| `search_players` | Player ids by name, with position, club, last season | 1 | player-scouting, goalscorer-prop-modeling |
| `list_games` | Fixtures and results by season, stage, date, range or club | 2 | match-lookup, poisson-score-models, elo-ratings |
| `get_schedule` | Upcoming fixtures (1-30 days) with the median three-way line | 2 | odds-explorer, match-preview |
| `get_standings` | League table with deductions, home/away, form | 2 | team-analysis |
| `get_ratings` | Our Elo ratings, strongest first, current or as of a date | 2 | elo-ratings, match-preview |
| `get_head_to_head` | Two clubs' record and meetings in this competition | 2 | match-preview, team-analysis |
| `get_game` | One match: score, both box scores with xG, player lines, key events, each book's line | 5 | match-lookup, match-preview |
| `get_lineups` | Formations, starting XIs, substitutions with minutes, unused bench | 5 | match-lookup, goalscorer-prop-modeling |
| `get_player` | Profile, per-season totals and per-90 rates, last 10 matches | 5 | player-scouting |
| `get_player_games` | A player's match log, newest first | 5 | player-scouting, goalscorer-prop-modeling |
| `get_leaders` | Season leaders in goals, assists, xG, shots, cards, saves, clean sheets | 5 | player-scouting, xg-analysis |
| `get_team_stats` | Per-match averages for and against, including xG | 5 | team-analysis, xg-analysis |
| `get_line_movement` | Pre-kickoff snapshots of each book's line | 10 | odds-explorer |
| `get_events` | Ordered match events, shots with location and xG | 10 | match-lookup, xg-analysis |
| `get_shot_map` | Shots and zone totals for a club, player or match | 10 | xg-analysis, goalscorer-prop-modeling |
| `get_player_props` | Anytime goalscorer prices by book, opening or closing | 10 (0 with `estimate_only`) | goalscorer-prop-modeling |
`get_odds` is priced by how you call it: pass `game_id` for one match, `date` for a day, or `season` (optionally with `team`) for priced matches, 100 per page.
## Parameters shared by most tools
| Parameter | Meaning |
|-----------|---------|
| `league` | One of `soccer` (Premier League, the default), `mls`, `laliga`, `seriea`, `bundesliga`, `ligue1`, `ucl`, `championship`, `nwsl`, `ligamx`, `uel`, `uecl`, `eredivisie`, `primeira`, `scotland`, `brazil`, `argentina` |
| `season` | The year the season starts: `2025` is 2025-26. MLS, the NWSL, Liga MX, Brazil and Argentina use the calendar year |
| club arguments | A club id, abbreviation or name. Ids and abbreviations are safest |
| dates | `YYYY-MM-DD`, in UTC |
| paging | `limit` plus `offset`; the response carries `next_offset` |
ExcPreview of the first 4,000 characters. Read full instructions →
team-analysis7.22 KB
---
name: team-analysis
description: "Analyzes clubs: league table, points per game, home and away splits, form, goals and xG for and against, possession and discipline, head to head, and strength relative to the league. Use when the user asks how a club is doing, wants the table, compares two clubs, or asks whether a club is over- or under-performing. Do not use for a single match, see match-lookup. Do not use for player-level stats, see player-scouting. Do not use for building ratings, see elo-ratings."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Team Analysis
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_standings` (2 credits) for the table. `get_team_stats` (5) for per-match averages including xG, and it returns the whole league in one call when `team` is omitted. `get_head_to_head` (2) for meetings. `get_ratings` (2) for Elo.
You turn a table and a block of averages into a view of how good a club actually is, separating what the points say from what the underlying numbers say.
## When to Use
- "How is Chelsea doing?" / "Show me the Bundesliga table"
- "Is this club lucky?" (points versus xG)
- Home and away splits, recent form
- Comparing two clubs on attack and defence
- Strength of schedule context before a preview
## When NOT to Use
- One match in detail: `match-lookup`
- Shot locations and finishing: `xg-analysis`
- A named player: `player-scouting`
- Producing win probabilities from ratings: `elo-ratings`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `list_teams` | Club ids and abbreviations for a season | 1 |
| `get_standings` | Rank, played, W/D/L, goals for and against, points, deductions, qualification note, home and away records, form | 2 |
| `get_team_stats` | Per-match averages for and against: goals, `xg_for`, `xg_against`, shots, shots on target, possession, pass accuracy, corners, fouls, cards, tackles, clean sheets | 5 |
| `get_head_to_head` | Meetings in this competition: wins, draws, goals, first meeting, results newest first | 2 |
| `get_ratings` | Elo ratings, strongest first | 2 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_table`, `get_league_table` | `get_standings` |
| `get_team` | `get_team_stats` with `team` set |
| `get_form` | The `form` field in `get_standings` (last results as letters), or `list_games` with `team` |
| `get_xg_table` | Build it from `get_team_stats`, see `xg-analysis` |
| `get_injuries` | Not available |
## How It Works
**Step 1: Resolve the competition and season.** Default is the Premier League, latest season. `get_standings` accepts every league except `ligamx` and `argentina`. In the Champions League it returns one table per group or the league phase.
**Step 2: Pull the table and the averages.**
```
get_standings {"season": 2025}
get_team_stats {"season": 2025}
```
Omit `team` in `get_team_stats` to get all clubs for 5 credits. One call per club would cost 5 each.
**Step 3: Compute the gaps.** From `get_team_stats`:
```
xGD per match = xg_for - xg_against
goal diff/match = goals_for - goals_against
luck gap = goal diff/match - xGD per match (positive = outperforming)
```
From `get_standings`: points per game = `points / played`, and home and away records parse from strings like `"3-0-0"` (wins-draws-losses).
**Step 4: Judge sustainability.** Over a full 38-match season, goal difference tracks xG difference closely and, as a rule of thumb, a gap above about 0.3 goals per match is unusual. Over 5 or 6 matches, a gap of 0.5 is noise. Do not call a club lucky or unlucky on fewer than about 10 matches.
**Step 5: Add context.** Home and away splits (a club with 5 wins from 5 at home has played a different schedule than one with 3 and 2). `get_head_to_head` for the specific pairing, but it counts every meeting in this competition since the first, so recent meetings matter more than the lifetime record.
## WorkedPreview of the first 4,000 characters. Read full instructions →
walk-forward-validation9.06 KB
---
name: walk-forward-validation
description: "Evaluates soccer prediction models without leaking the future: walk-forward and expanding-window splits by matchweek or season, point-in-time features, leakage checks specific to standings, season stats and ratings, and significance testing of a model against the closing line. Use when the user asks whether cross-validation is okay, how to split match data, whether their backtest leaked, or how to compare two models. Do not use for probability scaling, see probability-calibration."
metadata:
version: 1.0.0
author: StrikerAPI
---
# Walk-Forward Validation
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> Results history comes cheap from `list_games` (2 credits for up to 200 matches). `get_ratings` with `date` gives point-in-time Elo (2). Most StrikerAPI calls return the state as of today, so rebuilding features as of an earlier date from match logs is usually the safe path.
Soccer data is a time series with a regime change every August. A random k-fold split uses next year's results to predict last year's matches, which makes any model look better than it will be. Walk-forward validation trains on the past, predicts the next block, then steps forward.
## When to Use
- "Can I use 5-fold cross-validation on matches?" (No)
- "Is my model any good?"
- "Did my backtest leak?"
- Choosing between two models, two feature sets or two hyperparameters
- Tuning an Elo or a decay rate
## When NOT to Use
- Turning scores into calibrated probabilities: `probability-calibration`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `list_games` | Results by `season`, `from`/`to`, `status` for the training stream | 2 per call |
| `get_ratings` | Elo as of a `date` | 2 |
| `get_game` | Per-match xG and box score (5 each, use sparingly) | 5 |
| `get_shot_map` | A club-season of shots with `game_id` and `date`, so you can rebuild xG per match | 10 |
| `get_odds` | Closing prices for the benchmark, `season` mode | 2 per match |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_standings_as_of` | Not available. `get_standings` returns the table as it stands now (or at season end for a past season); rebuild an as-of table from `list_games` |
| `get_team_stats_as_of` | Not available. `get_team_stats` averages the whole season; rebuild as-of averages from per-match data |
| `get_form_history` | Rebuild from `list_games` |
## The Split
**Expanding window (default).** Train on everything before block `t`, predict block `t`, add block `t` to the training set, step.
**Rolling window.** Same, but drop blocks older than N seasons. Use if the league's style or your model's parameters drift.
Block choice:
| Block | When |
|-------|------|
| Matchweek (roughly 10 matches) | Models that update weekly: Elo, time-decayed Poisson |
| Month | Cheaper retrain |
| Season | Models with hard-to-refit parameters, and for the final report |
```python
def walk_forward(matches, first_test_date, step_days=7, fit=None, predict=None):
matches = sorted(matches, key=lambda m: m["starts_at"])
out, t = [], first_test_date
while t <= matches[-1]["starts_at"][:10]:
train = [m for m in matches if m["starts_at"][:10] < t]
test = [m for m in matches if t <= m["starts_at"][:10] < add_days(t, step_days)]
if train and test:
model = fit(train)
out += [(m, predict(model, m)) for m in test]
t = add_days(t, step_days)
return out
```
(`add_days` is a one-line date helper.) Keep the loop identical for every model you compare.
## Leakage Checklist for Soccer
| Leak | How it happens | Fix |
|------|---------------|-----|
| Table position | `get_standings` returns the table as of now, not as of the match date. Using it as a feature for a match in November uses May's table | Rebuild the as-of table from results |
| Season xG and team averages | `get_team_stPreview of the first 4,000 characters. Read full instructions →
xg-analysis10.7 KB
---
name: xg-analysis
description: "Soccer expected goals analysis: shot maps for a match, club, defence or player, zone breakdowns, xG tables with xG difference and expected points, finishing over- and under-performance, and what a shot's location and body part say about its quality. Use when the user asks about xG, shot maps, shot quality, who is lucky or unlucky, an xG table, or expected points. Do not use for building your own xG model from scratch, that needs a separate dataset pipeline. Do not use for outcome prices, see odds-explorer. Do not use for goalscorer pricing, see goalscorer-prop-modeling."
metadata:
version: 1.0.0
author: StrikerAPI
---
# xG Analysis
> **Default data tool:** StrikerAPI (`strikerapi-tool`).
> `get_shot_map` (10 credits) for located shots with xG. `get_team_stats` (5) for season xG for and against, all clubs in one call. `get_leaders` with `stat` set to `xg` (5) for player rankings. `get_events` with `kind: "shots"` (10) for one match in event order.
Expected goals (xG) gives each shot a probability of being a goal from where it was taken, with what body part, and in what situation. Summed over a match or a season it describes the chances a team created and allowed, which is a steadier signal than the scoreline. The xG in StrikerAPI is our own, computed from ESPN-charted located shots from 2012-13 where located shots exist, and it is `null` where they do not.
## When to Use
- "Show me Arsenal's shot map"
- "Which clubs allowed the most xG?"
- "Build an xG table" / "Who is overperforming?"
- "Is this striker finishing or just lucky?"
- "Expected points for the season"
## When NOT to Use
- Training a new xG model: you need shot features plus freeze-frame or event context that this API does not expose; use the located shots as a baseline only
- Match prices: `odds-explorer`
- Player rates and minutes: `player-scouting`
## Commands Available
| Command | What It Does | Credits |
|---------|-------------|---------|
| `get_shot_map` | Shots for a `team`, a `player`, or one `game_id`, for a `season`. `against: true` with `team` returns shots conceded. `include_shots: false` returns totals and zones only | 10 |
| `get_team_stats` | Per-match `xg_for`, `xg_against`, shots, shots on target for every club (omit `team`) | 5 |
| `get_leaders` | Season leaders by `stat: "xg"`, with `per90` and `min_games` | 5 |
| `get_events` | Match events; `kind: "shots"` gives each shot with `xg`, `zone`, `body_part`, `x`, `y` | 10 |
| `get_game` | Box score with `xg` per team (5) | 5 |
## Commands That Do NOT Exist
| Not Available | Use Instead |
|--------------|-------------|
| `get_xg`, `get_expected_goals` | `get_shot_map`, `get_team_stats` |
| `get_xg_table` | Build it from `get_team_stats` (below) |
| `get_xa`, `get_xgot` | Not available. No expected assists and no post-shot xG |
| `get_pass_map`, `get_heatmap`, `get_pressing` | Not available. Only shots carry coordinates |
## Shot Map Fields
```
get_shot_map {"team": "ARS", "season": 2025}
```
The response has `totals` (shots, located, goals, on_target, xg, xg_per_shot), `zones`, `unlocated_shots`, and a `shots` array, newest first, up to 2,000. Each shot:
| Field | Meaning |
|-------|---------|
| `game_id`, `date`, `minute`, `team`, `player_id`, `player` | Context |
| `outcome` | goal, saved, missed, blocked, woodwork |
| `body_part` | right_foot, left_foot, header |
| `penalty` | True for penalties |
| `zone` | six_yard_box, penalty_area, outside_box, penalty |
| `xg` | The shot's probability of scoring |
| `x`, `y` | Location. `x` is the distance from the goal line as a share of half the pitch (the penalty spot is 0.23). `y` runs across the pitch, 0.5 is the centre |
| `end_x`, `end_y` | Where the shot ended |
| `distance_m` | Distance to goal in metres |
Events from `get_events` also carry `metres.from_goal_line` and `metres.from_centre`, which are easier to plot on a real pitch.
Unlocated shots are counted in `shots_total` but have no xG. InPreview of the first 4,000 characters. Read full instructions →
Release notes
Initial release. Read-only soccer data tools with OAuth sign-in and 14 workflow skills.
Declared in the saved package. Remote tools may change independently.
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package license
- MIT
- Package author
- StrikerAPI
- Keywords
- See keywords
- Commerce declaration
- Does not support commerceThis does not establish whether access is free or paid.
- Review scenarios
- 5 positive · 3 negativeScenario counts, not test results.
Declared capabilities
- Look up clubs, players and matches across many leagues
- Read league tables, schedules and results
- Read lineups, match events and shot maps
- Read expected goals and player leaders
- Read sportsbook odds and prop lines (information only)
Package observed Nov 6, 2026.
Technical details
- First seen
- Oct 30, 2026 · 00:00 UTC
- Last seen
- Nov 7, 2026 · 06:00 UTC
- Collection status
- Collected
plugin_asdk_app_6ad146628be48191826f84406ff2c4c1
Download plugin data (JSON)Plugin details: freshly prepared. Prepared . Refreshed when plugin data changes or after 6 hours. Your account and Follow status are live.