Premier League data, in your code.
Standings, club & player season stats, per-match detail and news over a simple JSON REST API — for your notebooks, bots, dashboards and apps.
Prefer to use it from an AI client such as Claude or Cursor, without writing code? See MCP.
Plans & limits
| Plan | API access | Rate limit | Monthly requests |
|---|---|---|---|
| Data Fan plan | Not available | – | – |
| Data Supporter plan | ✓ | 120 req/min | 300/mo (resets on the 1st, UTC) |
| Data Ultras plan | ✓ | 240 req/min | Unlimited* |
* Because “unlimited” is an open-ended resource, we may pause access for a safety check even within the limits — contact us and we will lift it right away. Keys stop working on cancellation or downgrade to Data Fan (they work again if you re-subscribe). Rate limits and monthly quotas are subject to change.
See pricing →Available data
API docs (Swagger) ↗All 24 endpoints. Full parameter and response-schema definitions live in the Swagger docs.
League table
The official league table: results, goal difference, last-5 form, attendance and each club’s top scorer.
GET /league-table/overallOverall table (points, GD, form, top scorer, …)GET /league-table/home-awayThe table split into home and away records
Squad aggregates
Season aggregates per club across four categories: standard, shooting, goalkeeping and miscellaneous.
GET /squad/standard-statsGoals, assists, minutes and core stats per clubGET /squad/shootingShots, on-target %, conversionGET /squad/goalkeepingSaves, save %, clean sheetsGET /squad/misc-statsCards, fouls, tackles, aerials
Opponent aggregates
What each club *conceded* to its opponents — useful for defensive analysis. Same four categories.
GET /opponent/standard-statsConceded goals/assists and core against-statsGET /opponent/shootingShots facedGET /opponent/goalkeepingOpposing keepers’ statsGET /opponent/misc-statsOpponents’ cards, fouls, …
Player stats
Per-player season aggregates. Filter with club= or player=. Includes per-90 variants.
GET /team/standard-statsGoals, assists, minutes, per-90sGET /team/shootingShots, SoT, conversionGET /team/playing-timeMinutes, starts/subs, team +/-GET /team/misc-statsTackles won, interceptions, cardsGET /team/goalkeeper-statsKeeper aggregates (save %, CS, GA90)
Matches
Per-match data: results and upcoming schedules, plus per-match player stats and minute-by-minute events.
GET /matches/fixturesResults (score, venue, attendance)GET /matches/fixtures/{match_id}A single fixtureGET /matches/schedulesUpcoming (unplayed) matchesGET /matches/player-statsPer-match player statsGET /matches/keeper-statsPer-match keeper statsGET /matches/eventsGoals, cards, subs with minuteGET /matches/team-statsPer-match team stats (possession, …)
News
Published news articles (JA/EN).
GET /newsPublished news listGET /news/{news_id}A single article
Common parameters: season (e.g. 25/26; defaults to current), plus club, player, match_id and gameweek filters.
https://premie-backend-lvuzwxd3aq-uc.a.run.app/v1X-API-Key: pak_…Issue keys in Settings > Web API
GET / JSONAll endpoints are read-only
Your first request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://premie-backend-lvuzwxd3aq-uc.a.run.app/v1/league-table/overall"Query past seasons with ?season=25/26 (omit for the current season). Check your remaining monthly quota via the X-Monthly-Remaining response header.
Integrate it into your code
Ready-to-run implementations in five languages. Copy, set your API key as an environment variable, run.
top_scorers.py"""PremAnalytics Web API — 得点ランキング上位5名を表示する例。
事前準備: pip install requests
API キーは環境変数 PREMIA_API_KEY に設定してください。
"""
import os
import time
import requests
BASE_URL = "https://premie-backend-lvuzwxd3aq-uc.a.run.app/v1"
API_KEY = os.environ["PREMIA_API_KEY"]
session = requests.Session()
session.headers["X-API-Key"] = API_KEY
def get(path: str, **params) -> list[dict]:
"""GET リクエスト。429(レート制限)は Retry-After に従い1回だけ再試行する。"""
for attempt in range(2):
resp = session.get(f"{BASE_URL}{path}", params=params, timeout=15)
if resp.status_code == 429 and attempt == 0:
wait = int(resp.headers.get("Retry-After", "60"))
print(f"rate limited — {wait}s 待機して再試行します")
time.sleep(wait)
continue
resp.raise_for_status()
# 月間クォータの残量はレスポンスヘッダーで確認できる
remaining = resp.headers.get("X-Monthly-Remaining")
if remaining is not None:
print(f"(今月の残りリクエスト: {remaining})")
return resp.json()
raise RuntimeError("unreachable")
def main() -> None:
players = get("/team/standard-stats", season="26/27")
top5 = sorted(players, key=lambda p: (p["gls"] or 0), reverse=True)[:5]
for i, p in enumerate(top5, start=1):
print(f"{i}. {p['player']} ({p['club']}) — {p['gls']:g} goals, {p['ast']:g} assists")
if __name__ == "__main__":
main()Every sample implements the same task (top 5 scorers of 26/27) with error handling, rate-limit retry and quota checking. Pass your API key via an environment variable — never hard-code it.
Errors & response headers
Status codes
401 UnauthorizedMissing or invalid X-API-Key header403 ForbiddenValid key but plan not eligible (Fan / cancelled) or key suspended404 Not FoundNo data for the given id429 Too Many RequestsRate limit or monthly quota exceeded — retry after Retry-After seconds
Quota headers (every response)
X-Monthly-LimitYour monthly request capX-Monthly-UsedRequests used this monthX-Monthly-RemainingRequests remainingRetry-AfterOn 429 only: seconds until retry
Start pulling data
API keys are available on Data Supporter ($6/mo) and above.