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.
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) |
| Data Ultras plan | ✓ | 240 req/min | Unlimited* |
* “Unlimited” pauses at 5,000 requests/month as a safety check (contact us to lift). We may also temporarily suspend access for safety reviews. 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"""PremiAnalytics 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.