Official Python and TypeScript libraries for the Magisterial API. Fully typed — every model is generated from the published OpenAPI spec, so the SDKs cannot drift from the live API — with cursor pagination, retries, and long-running queries handled for you.
# pip install magisterial
from magisterial import Magisterial
client = Magisterial() # reads MAGISTERIAL_API_KEY
# Search players — auto-pagination follows the cursor for you
page = client.players.search(
sport="soccer", division="D1", gender="women",
position="Forward", sort_by="goals",
)
for player in page.auto_paging_iter():
print(player.name, player.team, player.stats.get("goals"))
# Natural-language query: submit, poll, get the answer
run = client.query.create_and_poll(
prompt="Who led the NESCAC in assists this season?",
sport="soccer", division="D3", gender="men",
)
print(run.answer)Both packages ship under the name magisterial. The Python library offers sync and async clients; the TypeScript library is a zero-dependency fetch client that works in Node 18+ and modern runtimes.
Both clients read the API key from the MAGISTERIAL_API_KEY environment variable by default, or accept it explicitly in the constructor. Test keys (mag_test_) call the free read endpoints for real and are blocked from usage-billed endpoints, so they are safe for development. Never embed a live key in client-side code — the SDKs are built for servers, scripts, and notebooks.
export MAGISTERIAL_API_KEY="mag_live_xxxxxxxxxxxxxxxxxxxx"
from magisterial import Magisterial # Reads MAGISTERIAL_API_KEY from the environment client = Magisterial() # Or pass the key explicitly (multi-key setups, tests) client = Magisterial(api_key="mag_test_...")
List endpoints are cursor-paginated. Each page exposes data, next_cursor, and has_more — but you rarely need them: both SDKs can iterate items across page boundaries and follow the cursor transparently until it is exhausted.
page = client.teams.list(
sport="volleyball", division="D3", gender="women",
)
# One page at a time: page.data, page.next_cursor, page.has_more
for team in page.data:
print(team.name)
# Or let the SDK follow next_cursor across every page
for team in page.auto_paging_iter():
print(team.name)API errors raise typed exceptions (Python) or throw typed error classes (TypeScript) that mirror the API’s error envelope — each carries the type, code, and message from the response body, so you can branch on tier_required vs rate_limit_exceeded without parsing anything.
Retries are automatic and honor the Retry-After header — on read requests only. Usage-billed requests are never retried automatically, so a transient failure can never bill you twice.
Natural-language queries and bulk exports are asynchronous on the API — submit, get an id, poll until the job completes. The SDKs collapse that into one call that submits and polls for you, returning the finished run or export.
# Natural-language query: submit + poll in one call
run = client.query.create_and_poll(
prompt="Which D2 programs lost their starting goalkeeper to the portal?",
sport="soccer", division="D2", gender="men",
)
print(run.answer)
# Same pattern for bulk exports — returns the finished job
export = client.exports.create_and_poll(
dataset="players", sport="soccer", division="D1", gender="women",
)
print(export.download_url)The v0.2.0 surface, grouped by API area. SDK method names mirror the spec’s operationIds — search_players becomes players.search(...) in Python and players.search({...}) in TypeScript. Parameters and response shapes are exactly what the API reference documents.
/v1/sportslist_sports/v1/divisionslist_divisions/v1/conferenceslist_conferences/v1/filters/catalogget_filter_catalog/v1/coverageget_coverage/v1/players/searchsearch_players/v1/players/{player_id}get_player/v1/players/{player_id}/seasonsget_player_seasons/v1/teamslist_teams/v1/teams/{team_id}get_team/v1/teams/{team_id}/rosterget_team_roster/v1/teams/{team_id}/coachesget_team_coaches/v1/persons/{person_id}get_person/v1/persons/{person_id}/transferslist_person_transfers/v1/gameslist_games/v1/games/{game_id}get_game/v1/portallist_portal_entries/v1/querycreate_query/v1/query/{run_id}get_query_run/v1/alertscreate_alert/v1/alertslist_alerts/v1/alerts/{alert_id}delete_alert/v1/alerts/{alert_id}/matcheslist_alert_matches/v1/exportscreate_export/v1/exports/{export_id}get_export/v1/exportslist_exports