PremAnalytics Web API

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

PlanAPI accessRate limitMonthly requests
Data Fan planNot available––
Data Supporter plan✓120 req/min300/mo (resets on the 1st, UTC)
Data Ultras plan✓240 req/minUnlimited*

* 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 →

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/overall
    Overall table (points, GD, form, top scorer, …)
  • GET /league-table/home-away
    The table split into home and away records

Squad aggregates

Season aggregates per club across four categories: standard, shooting, goalkeeping and miscellaneous.

  • GET /squad/standard-stats
    Goals, assists, minutes and core stats per club
  • GET /squad/shooting
    Shots, on-target %, conversion
  • GET /squad/goalkeeping
    Saves, save %, clean sheets
  • GET /squad/misc-stats
    Cards, fouls, tackles, aerials

Opponent aggregates

What each club *conceded* to its opponents — useful for defensive analysis. Same four categories.

  • GET /opponent/standard-stats
    Conceded goals/assists and core against-stats
  • GET /opponent/shooting
    Shots faced
  • GET /opponent/goalkeeping
    Opposing keepers’ stats
  • GET /opponent/misc-stats
    Opponents’ cards, fouls, …

Player stats

Per-player season aggregates. Filter with club= or player=. Includes per-90 variants.

  • GET /team/standard-stats
    Goals, assists, minutes, per-90s
  • GET /team/shooting
    Shots, SoT, conversion
  • GET /team/playing-time
    Minutes, starts/subs, team +/-
  • GET /team/misc-stats
    Tackles won, interceptions, cards
  • GET /team/goalkeeper-stats
    Keeper aggregates (save %, CS, GA90)

Matches

Per-match data: results and upcoming schedules, plus per-match player stats and minute-by-minute events.

  • GET /matches/fixtures
    Results (score, venue, attendance)
  • GET /matches/fixtures/{match_id}
    A single fixture
  • GET /matches/schedules
    Upcoming (unplayed) matches
  • GET /matches/player-stats
    Per-match player stats
  • GET /matches/keeper-stats
    Per-match keeper stats
  • GET /matches/events
    Goals, cards, subs with minute
  • GET /matches/team-stats
    Per-match team stats (possession, …)

News

Published news articles (JA/EN).

  • GET /news
    Published news list
  • GET /news/{news_id}
    A single article

Common parameters: season (e.g. 25/26; defaults to current), plus club, player, match_id and gameweek filters.

Base URL
https://premie-backend-lvuzwxd3aq-uc.a.run.app/v1
Auth
X-API-Key: pak_…

Issue keys in Settings > Web API

Format
GET / JSON

All 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 Unauthorized
    Missing or invalid X-API-Key header
  • 403 Forbidden
    Valid key but plan not eligible (Fan / cancelled) or key suspended
  • 404 Not Found
    No data for the given id
  • 429 Too Many Requests
    Rate limit or monthly quota exceeded — retry after Retry-After seconds

Quota headers (every response)

  • X-Monthly-Limit
    Your monthly request cap
  • X-Monthly-Used
    Requests used this month
  • X-Monthly-Remaining
    Requests remaining
  • Retry-After
    On 429 only: seconds until retry

Start pulling data

API keys are available on Data Supporter ($6/mo) and above.