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
dataclassresponse models — a faithful mirror of the API's JSON, built through a smallfrom_dictconverter (no Pydantic, one dependency) - Typed exceptions mapped from the API's stable
error.code - Automatic retries on
429/5xxwithRetry-Afterhonoured
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, heatmaps(id, frame=None) |
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 PlayerStatGroup — top_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.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pitchapi-0.1.5.tar.gz | 25.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pitchapi-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 54.8 kB
Release files / pitchapi-0.1.5.tar.gz
| Download URL | pitchapi-0.1.5.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3239b52e01c6eb9d98abf837f05160e42c6681392d80253faaaff0ffcba36dab
|
|
BLAKE2b-256 checksum How to use checksums |
a921b55fc682a57bc81a2d2102067ea9f64e25c5ae0e1543d3a6f6b39548885e
|
| 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.5-py3-none-any.whl
| Download URL | pitchapi-0.1.5-py3-none-any.whl |
|---|---|
| Size | 29.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78da865587eba569018955495d2567ea813fdc955a6d3618fd0e95374b7b8ac8
|
|
BLAKE2b-256 checksum How to use checksums |
b3fb454e1939c12357fb29ba7987db58bd1937194d3bbf4e86028910016f4784
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|