# Magisterial SDKs

Official Python and TypeScript client libraries for the Magisterial API,
both at v0.2.0. Fully typed — every model is generated from the published
OpenAPI spec (https://api.magisterial.ai/v1/openapi.json), so the SDKs cannot
drift from the live API — with cursor pagination, retries, and long-running
jobs handled for you.

## Install

- Python 3.10+ (sync and async clients): `pip install magisterial`
  — https://pypi.org/project/magisterial/ · https://github.com/bluemens/magisterial-python
- TypeScript/JavaScript, Node 18+, zero dependencies: `npm install magisterial`
  — https://www.npmjs.com/package/magisterial · https://github.com/bluemens/magisterial-node

## Authentication

Both clients read `MAGISTERIAL_API_KEY` from the environment, or accept the
key in the constructor. Keys are self-serve at https://magisterial.ai/console.
Test keys (mag_test_) call the free read endpoints for real and are blocked
from usage-billed endpoints. Never embed a live key client-side.

## Quickstart (Python)

    from magisterial import Magisterial

    client = Magisterial()  # reads MAGISTERIAL_API_KEY

    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"))

    run = client.query.create_and_poll(
        prompt="Who led the NESCAC in assists this season?",
        sport="soccer", division="D3", gender="men",
    )
    print(run.answer)

## Quickstart (TypeScript)

    import Magisterial from "magisterial";

    const client = new Magisterial(); // reads MAGISTERIAL_API_KEY

    const page = await client.players.search({
      sport: "soccer", division: "D1", gender: "women",
      position: "Forward", sort_by: "goals",
    });
    for await (const player of page) {
      console.log(player.name, player.team, player.stats?.goals);
    }

## Behavior

- Pagination: list endpoints are cursor-paginated (`data`, `next_cursor`,
  `has_more`); both SDKs iterate across page boundaries transparently
  (`auto_paging_iter()` / `for await`).
- Errors: typed exceptions/error classes carrying the API's `type`, `code`,
  and `message` — branch on codes like `tier_required` or
  `rate_limit_exceeded` without parsing.
- Retries: automatic on read requests only, honoring Retry-After.
  Usage-billed requests are never retried automatically.
- Long-running jobs: `query.create_and_poll(...)` and
  `exports.create_and_poll(...)` submit and poll in one call.

## Method surface (v0.2.0)

Method names mirror the spec's operationIds (`search_players` becomes
`players.search(...)`).

| Area | Endpoints |
|---|---|
| Reference | GET /v1/sports, /v1/divisions, /v1/conferences, /v1/filters/catalog, /v1/coverage |
| Players | POST /v1/players/search; GET /v1/players/{id}, /v1/players/{id}/seasons |
| Teams | GET /v1/teams, /v1/teams/{id}, /v1/teams/{id}/roster, /v1/teams/{id}/coaches |
| Persons & careers | GET /v1/persons/{id}, /v1/persons/{id}/transfers |
| Games | GET /v1/games, /v1/games/{id} |
| Transfer portal | GET /v1/portal |
| Query | POST /v1/query; GET /v1/query/{run_id} |
| Alerts | POST /v1/alerts; GET /v1/alerts, /v1/alerts/{id}/matches; DELETE /v1/alerts/{id} |
| Exports | POST /v1/exports; GET /v1/exports, /v1/exports/{id} |

Full contracts: https://api.magisterial.ai/v1/llms.txt · release notes:
https://magisterial.ai/changelog.md
