SDK

Python SDK

Sync and asyncio clients for Python 3.10+, with every object of the API typed. Every endpoint is a method.

Not published yet: the install lines go live with the first release.

Install

One package, no setup beyond your API key.

Python
$ pip install "git+https://github.com/sportsapiapp/sportsapi-python"   # until it is on PyPI
$ pip install sportsapi                                                # once it is

Authenticate

Use the API key from your dashboard. Pass it to the client, or set SPORTSAPI_API_KEY and the client reads it.

Python
from sportsapi import SportsAPI

client = SportsAPI()  # reads SPORTSAPI_API_KEY (or SportsAPI(api_key="sk_live_…"))

First calls

Every method returns the API's { data, meta } envelope, typed. Path parameters come first, in path order, then the query parameters with the API's own names.

Python
live = client.livescores.list(sport="football")
for fixture in live["data"]:
    print(fixture["home"]["name"], fixture["homeScore"]["current"], "–",
          fixture["awayScore"]["current"], fixture["away"]["name"])

table = client.leagues.standings(17, season=61627)["data"]

Errors

One error type per HTTP status, each carrying the API's code, message and Retry-After. Branch on the code, never on the message.

Python
from sportsapi import NotFoundError, PermissionDeniedError, SportsAPIError

try:
    client.fixtures.win_probability(211521)
except PermissionDeniedError as e:  # 403: e.code == "endpoint_not_in_plan", …
    ...
except NotFoundError as e:  # 404: not_found, no_data, not_supported
    ...
except SportsAPIError as e:  # every error: e.status, e.code, e.message, e.retry_after
    ...

Paging

Every endpoint with a page parameter has a pages iterator that walks the pages until there are no more.

Python
for page in client.teams.fixtures_pages(42, type="recent", max_pages=3):
    for fixture in page["data"]:
        ...

asyncio

AsyncSportsAPI has the same methods, awaited.

Python
import asyncio
from sportsapi import AsyncSportsAPI


async def main() -> None:
    async with AsyncSportsAPI() as client:
        fixture = await client.fixtures.get(211521)
        print(fixture["data"]["status"]["description"])


asyncio.run(main())

WebSocket stream (Business)

The stream mints its own single-use ticket, subscribes, reconnects and replays what it missed, and merges every delta into the fixtures it holds.

Python
with client.stream(["livescores", "fixture:211521"]) as stream:
    for frame in stream:
        if frame["type"] == "delta":
            print(frame["id"], frame["changes"])
        in_play = stream.fixtures("livescores")  # the merged state, any time

Options

A 429 rate_limited or a 503 is retried after Retry-After (twice by default); a quota error never is.

Python
SportsAPI(
    api_key=...,      # or SPORTSAPI_API_KEY
    base_url=...,     # or SPORTSAPI_BASE_URL
    timeout=30.0,     # seconds per attempt
    max_retries=2,
)
Every endpoint, with this SDK's call on each page→