Metadata-Version: 2.4
Name: footballdata-io
Version: 0.1.0
Summary: Official Python SDK for the footballdata.io API
Project-URL: Homepage, https://footballdata.io
Project-URL: Documentation, https://footballdata.io/docs
Project-URL: Repository, https://github.com/voroxi/footballdata-python
Project-URL: Issues, https://github.com/voroxi/footballdata-python/issues
Author-email: Voroxi Group LLC <support@footballdata.io>
License: MIT
License-File: LICENSE
Keywords: api,fixtures,football,footballdata,predictions,soccer,sports,standings
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: requests>=2.20
Description-Content-Type: text/markdown

# footballdata.io — Python SDK

Official Python client for the [footballdata.io](https://footballdata.io) API — fixtures, live scores, standings, predictions, odds, stats, and FIFA rankings.

[![PyPI](https://img.shields.io/pypi/v/footballdata-io.svg)](https://pypi.org/project/footballdata-io/)
[![Python](https://img.shields.io/pypi/pyversions/footballdata-io.svg)](https://pypi.org/project/footballdata-io/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)

- **API base URL:** `https://footballdata.io/api/v1`
- **Get a free API key:** <https://footballdata.io/signup>

## Install

```bash
pip install footballdata-io
```

The only dependency is [`requests`](https://pypi.org/project/requests/). Python 3.8+.

## 30-second quickstart

```python
from footballdata_io import Client

client = Client("YOUR_API_KEY")

# Today's fixtures
fixtures = client.fixtures.today()
print(fixtures)

# Predictions for a specific match
predictions = client.matches.predictions(123456)
print(predictions)

# Rate-limit / plan info from the last response
print(client.last_meta)  # { "plan": ..., "requests_remaining": ..., ... }
```

Every method returns the parsed `data` payload from the response envelope. The
client sends `Authorization: Bearer <API_KEY>` on every request automatically.

## Configuration

```python
from footballdata_io import Client

client = Client(
    "YOUR_API_KEY",
    base_url="https://footballdata.io/api/v1",  # override if needed
    timeout=30,                                  # seconds
)

# Use as a context manager to close the HTTP session when done:
with Client("YOUR_API_KEY") as client:
    coverage = client.meta.coverage()
```

## Examples by resource group

### `meta`

```python
client.meta.status()       # GET /meta/status
client.meta.coverage()     # GET /meta/coverage
```

### `account`

```python
client.account.usage()     # GET /account/usage
```

### `fixtures`

```python
client.fixtures.today(league_id=39, status="NS", page=1, limit=20)  # GET /fixtures/today
client.fixtures.today_predictions()                                 # GET /fixtures/today/predictions
client.fixtures.live()                                              # GET /fixtures/live
client.fixtures.upcoming(page=1, limit=20)                          # GET /fixtures/upcoming
client.fixtures.results(page=1, limit=20)                           # GET /fixtures/results
```

### `leagues`

```python
client.leagues.list(country="England", search="premier", page=1, limit=20)  # GET /leagues
client.leagues.standings(39)   # GET /leagues/{id}/standings
client.leagues.matches(39)     # GET /leagues/{id}/matches
client.leagues.teams(39)       # GET /leagues/{id}/teams
client.leagues.seasons(39)     # GET /leagues/{id}/seasons
client.leagues.stats(39)       # GET /leagues/{id}/stats
client.leagues.btts(39)        # GET /leagues/{id}/btts
client.leagues.corners(39)     # GET /leagues/{id}/corners
```

### `matches`

```python
client.matches.list(page=1, limit=20)      # GET /matches
client.matches.get(123456)                 # GET /matches/{id}
client.matches.stats(123456)               # GET /matches/{id}/stats
client.matches.events(123456)              # GET /matches/{id}/events
client.matches.odds(123456)                # GET /matches/{id}/odds
client.matches.predictions(123456)         # GET /matches/{id}/predictions
client.matches.probabilities(123456)       # GET /matches/{id}/probabilities
client.matches.btts(123456)                # GET /matches/{id}/btts
client.matches.corners(123456)             # GET /matches/{id}/corners
client.matches.by_date("2026-05-10")       # GET /matches/date/{date}
```

### `teams`

```python
client.teams.list(search="arsenal", page=1, limit=20)  # GET /teams
client.teams.get(42)              # GET /teams/{id}
client.teams.matches(42)          # GET /teams/{id}/matches
client.teams.players(42)          # GET /teams/{id}/players
client.teams.stats(42)            # GET /teams/{id}/stats
client.teams.h2h(42, 49)          # GET /teams/{id}/h2h/{opponentId}
```

### `players`

```python
client.players.list(search="saka", page=1, limit=20)  # GET /players
client.players.get(1100)          # GET /players/{id}
client.players.stats(1100)        # GET /players/{id}/stats
```

### `seasons`

```python
client.seasons.list()             # GET /seasons
client.seasons.matches(2024)      # GET /seasons/{id}/matches
client.seasons.standings(2024)    # GET /seasons/{id}/standings
client.seasons.teams(2024)        # GET /seasons/{id}/teams
```

### `countries`

```python
client.countries.list()               # GET /countries
client.countries.leagues("England")   # GET /countries/{country}/leagues
```

### `fifa_rankings`

```python
client.fifa_rankings.list()            # GET /fifa-rankings
client.fifa_rankings.current()         # GET /fifa-rankings/current
client.fifa_rankings.periods()         # GET /fifa-rankings/periods
client.fifa_rankings.history("Brazil") # GET /fifa-rankings/{country}/history
```

### `search`

```python
client.search("arsenal")   # GET /search?q=arsenal
```

## Error handling

Non-2xx responses (and API error envelopes) raise a typed `FootballDataError`
exposing `status`, `code`, `message`, and `details`. For plan-gated endpoints
(HTTP 403) the `details` include an `upgrade` hint.

```python
from footballdata_io import Client, FootballDataError

client = Client("YOUR_API_KEY")

try:
    data = client.matches.odds(123456)
except FootballDataError as err:
    print(err.status)   # e.g. 403
    print(err.code)     # e.g. "plan_upgrade_required"
    print(err.message)  # human-readable message

    upgrade = err.details.get("upgrade")
    if upgrade:
        print("Upgrade to {} ({}): {}".format(
            upgrade["plan_name"], upgrade["price"], upgrade["upgrade_url"]
        ))
```

Common statuses: `401` invalid/missing key, `403` plan gate (upgrade hint in
`details`), `404` not found, `429` rate limit exceeded.

## Rate-limit metadata

Each successful response includes a `meta` block with plan and usage info.
Read it from the client after any call:

```python
client.fixtures.live()
meta = client.last_meta
# { "plan": "starter", "requests_used": 12, "requests_limit": 1000,
#   "requests_remaining": 988, ... }
```

## Links

- Website & docs: <https://footballdata.io>
- Get a free API key: <https://footballdata.io/signup>
- Source: <https://github.com/voroxi/footballdata-python>

## License

MIT © 2026 Voroxi Group LLC. See [LICENSE](./LICENSE).
