Quick start
Get an API key from the developer console, then make your first request. Keys are created and managed from your account — sign in and the console opens straight to key management.
Open the console, create a key, and copy it — the full token is shown only once.
curl https://api.magisterial.ai/v1/sports \ -H "Authorization: Bearer mag_live_xxxxxxxxxxxxxxxxxxxx"
Introduction
The API is organized around predictable, resource-oriented URLs. It accepts JSON request bodies, returns JSON responses, and uses standard HTTP verbs, status codes, and authentication. Every response you receive is scoped to exactly the sports and divisions your plan includes — the same data you see inside the Magisterial app.
Authentication
Authenticate with an API key sent as a bearer token in the Authorization header. Keys are created and rotated from your account settings. Live keys are prefixed mag_live_ and test keys mag_test_. Treat keys like passwords — they carry your plan’s full access. Never embed a live key in client-side code.
curl https://api.magisterial.ai/v1/players/search \
-H "Authorization: Bearer mag_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "sport": "soccer", "gender": "men", "division": "D1" }'Requests without a valid key return 401 Unauthorized.
Scoping & access
Access is governed per sport and per division by your subscription tier. Every request must declare a scope — a sport, gender, and division — and results never span beyond what your plan entitles you to. A request for a division you don’t hold returns 403 Forbidden with the required tier, rather than silently returning nothing.
"D1,D2,D3" to search across all three at once. NAIA and NJCAA are separate associations and cannot be combined with NCAA divisions.Rate limits
Every account may make up to 120 requests per minute across all /v1 endpoints, shared by all of its keys. Each response reports where you stand:
X-RateLimit-Limit: 120 X-RateLimit-Remaining: 119 X-RateLimit-Reset: 1751990460
X-RateLimit-Reset is the Unix time (seconds) when the window resets. Exceeding the limit returns 429 Too Many Requests with a Retry-After header (seconds to wait) and the standard error body:
{
"error": {
"type": "rate_limited",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded (120 per 1 minute). Wait for the window to reset and retry."
}
}Pagination & errors
List endpoints are cursor-paginated. Pass limit (max 100) and follow next_cursor from each response until it is null.
{
"data": [ /* ... */ ],
"next_cursor": "eyJvZmZzZXQiOjEwMH0",
"has_more": true
}Errors use standard status codes and a consistent body:
{
"error": {
"type": "forbidden",
"code": "tier_required",
"message": "This division requires a Pro plan or higher for soccer.",
"required_tier": "pro"
}
}Usage-billed endpoints (portal, query, alerts) add billing errors: 403 api_billing_not_enabled until billing is enabled in the console, 403 api_billing_past_due after a failed invoice, and 402 budget_exceeded once month-to-date spend reaches your budget cap (the response includes budget_usd and spent_usd).
Sports & divisions
Discovery endpoints returning the sports, divisions, and conferences your key can query. Use these to populate pickers and validate scope before issuing a data request.
/v1/sports/v1/divisions/v1/conferencesdivisionstringrequiredD1.Filter catalog
Returns the queryable fields, operators, and allowed values for a given sport — the same catalog that powers search and automations in the app. Build valid /players/search filters from this rather than hard-coding field names.
/v1/filters/catalogsportstringrequiredPlayers
Players and their per-season statistics. Search returns matches within your scope; the detail endpoints return a single player and their season history.
/v1/players/searchBody
sportstringrequireddivisionstringrequiredgenderstringoptionalmen or women (ignored for single-gender sports).filtersarrayoptionallimitintegeroptional/v1/players/{id}/v1/players/{id}/seasonsExample response
{
"data": [
{
"id": "plr_8fk2...",
"person_id": "prs_1a9c...",
"name": "Jordan Reyes",
"position": "GK",
"team": { "id": "tm_44...", "name": "Georgetown" },
"division": "D1",
"class_year": "Junior"
}
],
"next_cursor": null,
"has_more": false
}Persons & careers
A person is a real individual linked across every school, season, and transfer they appear in. Use this to follow a career across programs — the identity that survives a transfer, where a player is one school-season slice.
/v1/persons/{id}/v1/persons/{id}/transfersTeams & coaches
Programs, their rosters, and coaching staffs.
/v1/teamsdivisionstringrequired/v1/teams/{id}/v1/teams/{id}/rosterseasonstringoptional/v1/teams/{id}/coachesTransfer portal
The live NCAA transfer portal. Returns players currently in the portal within your scope, with entry status and timing. Access follows NCAA rules — verified coaches do not see their own school’s players. Usage-billed per request; contact info appears only for Pro/Max accounts, matching the in-app paywall.
/v1/portalsportstringrequireddivisionstringrequiredgenderstringoptionalstatusstringoptionalsincestring (ISO 8601)optionallimitintegeroptionalGames
Fixtures with box scores and, where available, play-by-play. Filter by team, date range, or season.
/v1/gamesteam_idstringoptionalfromstring (ISO 8601)optionaltostring (ISO 8601)optional/v1/games/{id}Natural-language query
Ask a question in plain English and get a structured answer with the data behind it. Queries run as asynchronous jobs — create a run, then poll it to completion. This is the same assistant that powers the app. Usage-billed at model cost with a markup; the final billed amount is returned with the result.
/v1/querypromptstringrequiredsportstringrequireddivisionstringoptionalgenderstringoptional/v1/query/{run_id}POST /v1/query
{ "prompt": "Which D2 goalkeepers had a save percentage above 80% last season?",
"sport": "soccer", "division": "D2" }
// 202 Accepted
{ "run_id": "9b1f...", "status": "queued" }
GET /v1/query/9b1f...
// 200 OK (terminal)
{ "run_id": "9b1f...", "status": "done",
"answer": "Five D2 goalkeepers finished above 80%...",
"usage": { "tokens_in": 41230, "tokens_out": 902,
"model": "claude-sonnet-4-6", "billed_usd": 0.42 } }Alerts & webhooks
Instead of scanning the portal yourself, register a watch alert and poll its matches. Alerts are evaluated automatically as new portal data lands and are billed per active alert per month. Webhook delivery is coming soon — a stored webhook_url will start receiving events when it ships; until then, poll the matches endpoint.
/v1/alertsnamestringrequiredsportstringrequireddivisionstringrequiredfiltersobjectrequiredwebhook_urlstringoptional/v1/alerts/v1/alerts/{id}/matches/v1/alerts/{id}