Skip to main content

pitchapi — Python SDK

Typed Python client for the PitchAPI football-data API. Match results, shots, xG, lineups, momentum, events, player stats, head-to-head, and advanced analytics derived from the event feed.

  • Sync and async clients over one shared core (httpx)
  • Plain dataclass response models — a faithful mirror of the API's JSON, built through a small from_dict converter (no Pydantic, one dependency)
  • Typed exceptions mapped from the API's stable error.code
  • Automatic retries on 429/5xx with Retry-After honoured

Install

pip install pitchapi

Requires Python 3.9+.

Quick start

from pitchapi import PitchAPI

with PitchAPI(api_key="pk_live_...") as client:
    day = client.date.get("2026-08-27")
    for m in day.matches:
        print(m.home_team.name, m.score_home, "-", m.score_away, m.away_team.name)

    match = client.matches.get("m_4DP2fy")
    shots = client.matches.shots(match.id)
    adv = client.matches.advanced(match.id)          # team rollups
    net = client.matches.advanced_network(match.id)  # pass networks

The key can also come from the PITCHAPI_API_KEY environment variable, in which case PitchAPI() needs no arguments.

Async

import asyncio
from pitchapi import AsyncPitchAPI

async def main():
    async with AsyncPitchAPI() as client:
        league = await client.leagues.get("l_0bfbkO")
        matches = await client.leagues.matches(league.id, season="2025/2026")
        print(len(matches.matches), "matches")

asyncio.run(main())

Namespaces

Namespace Methods
client.date get(date, status=None)date is a str (YYYY-MM-DD) or a datetime.date
client.matches get, shots, shot, events, lineups, momentum, stats, players, player, player_shots, h2h, advanced, advanced_network, advanced_players, advanced_player
client.leagues list, get, matches(id, season=None, status=None)
client.teams get
client.players get

Every method returns a typed dataclass from pitchapi.models.

Per-player match stats is a list of PlayerStatGrouptop_stats, attack, defense, duels — and which groups appear depends on position and involvement. Each group's stats is keyed by display label, but the label is presentation text: branch on the entry's key.

for group in client.matches.players("m_4DP2fy")[0].stats:
    for label, entry in group.stats.items():
        s = entry.stat
        # integer and double carry a value; fractionWithPercentage adds a total
        print(group.key, entry.key, s.type, s.value, s.total)

Upcoming fixtures

Match listings return played matches by default. Pass status to reach scheduled ones — "upcoming" for fixtures that have not kicked off, "all" for both. An upcoming match carries a kickoff time_utc and a status, but its scores are None until it is played.

for m in client.date.get("2026-09-01", status="upcoming").matches:
    print(m.time_utc, m.home_team.name, "vs", m.away_team.name)

# Within a season. The season is resolved first, so asking for upcoming
# fixtures of a finished campaign is an empty list, not next season's.
client.leagues.matches("l_0bfbkO", season="2025/2026", status="all")

Lineups for a fixture may be a pre-match prediction rather than the real XI. confirmed is the flag to branch on; lineup_type carries the source's own label for a prediction and is None once the lineup is confirmed.

lineups = client.matches.lineups("m_4DP2fy")
if lineups.home.confirmed:
    print(lineups.home.formation, [p.name for p in lineups.home.starters])
else:
    print("predicted only:", lineups.home.lineup_type)

Errors

from pitchapi import NotFoundError, PlanUpgradeRequiredError, RateLimitError

try:
    client.matches.advanced("m_unprocessed")
except NotFoundError as e:
    # code is RESOURCE_NOT_FOUND or ANALYTICS_UNAVAILABLE
    print(e.code, e.request_id)
except PlanUpgradeRequiredError:
    ...  # league is Pro-only
except RateLimitError as e:
    print("retry after", e.retry_after, "s")

All exceptions derive from pitchapi.PitchAPIError and carry code, status_code, and request_id where available.

Configuration

PitchAPI(
    api_key="pk_live_...",
    base_url="https://api.pitchapi.dev",  # override for self-hosting/tests
    timeout=30.0,
    max_retries=2,                        # 429/5xx + network errors; 0 disables
)

Development

pip install -e ".[dev]"
pytest              # tests use httpx.MockTransport — no network
mypy                # scoped to src/ by pyproject
ruff check .
ruff format --check .

OpenAPI

A full OpenAPI 3.1 description of the API lives at openapi/openapi.yaml in the repository root. The dataclass models in this SDK mirror its schemas one-to-one.

License

This client library is released under the MIT License.

The licence covers the SDK source only. Access to the PitchAPI service and the football data it returns is governed separately by the PitchAPI terms of service — an MIT-licensed client does not grant any right to the data.

Release files for pitchapi 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pitchapi 0.1.3
File Size Uploaded
pitchapi-0.1.3.tar.gz 23.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pitchapi 0.1.3
File Interpreter ABI Platform
pitchapi-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 50.8 kB

Release files / pitchapi-0.1.3.tar.gz

Download URL pitchapi-0.1.3.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
89cb01396030caa58defeb95c132cb023ca126470c59b1c08fa7741ee8bec3b5
BLAKE2b-256 checksum
How to use checksums
5678084af20ea8183ce9ab9f56959141d2262c467c031cbceb20bdb937906507
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / pitchapi-0.1.3-py3-none-any.whl

Download URL pitchapi-0.1.3-py3-none-any.whl
Size 27.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
15fef66632a2da84595c57034cf72d063e684a9bc5d02ae3754ad63663b22ae6
BLAKE2b-256 checksum
How to use checksums
7a02b860ff20778d00760db33ee35b291f6db7815f5653d42a7e69358f2ae449
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.1.5

2 release files

0.1.4

2 release files

This release

0.1.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page