# Permissions & scopes

> What an API key or MCP OAuth grant is allowed to do, and how to request the least access you need.

## Keys are read-only
The statshawk REST API is a **read-only** data surface. An API key can read stats; it can
never create, modify, or delete data, change your plan, rotate other keys, or touch your
account settings. Account management happens only in the [dashboard](/dashboard/api-keys)
behind a browser login. It is not reachable with an API key at all.

That means the blast radius of a leaked key is bounded to reading data and consuming your
quota. Revoke it in the dashboard and the next request receives `401`.

## Key environments
| Prefix      | Scope                                                           | Intended use                   |
| ----------- | --------------------------------------------------------------- | ------------------------------ |
| `sk_live_…` | Read all data, metered against your plan                        | Production traffic             |
| `sk_test_…` | Read all data, metered against your plan, attributed separately | Staging, CI, agent experiments |

Both environments authenticate identically; the split exists so you can rotate and audit
the two traffic classes independently (see [Authentication](/docs/getting-started/auth)).
Create one key per integration or per agent so you can revoke a single consumer without
disturbing the rest.

## Plan tier as an access scope
Some endpoints require a paid plan. A Free-tier key calling one of them receives
`403 TIER_REQUIRES_PAID` rather than partial data, so an agent can detect the boundary
deterministically. Per-competition feature support is discoverable up front via
`GET /v1/competitions/{comp}/capabilities` and `GET /v1/persons/{person_id}/capabilities`.

## MCP OAuth scopes
The MCP server at `https://mcp.statshawk.ai/mcp` uses OAuth 2.1 with PKCE. The
authorization server metadata is published at
[`/.well-known/oauth-authorization-server`](/.well-known/oauth-authorization-server) and the
resource metadata at `https://mcp.statshawk.ai/.well-known/oauth-protected-resource`.

| Scope           | Grants                                                                                                                                                            |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stats:read`    | `get_standings`, `get_box_score`, `search_games`, `get_team_roster`, `get_play_by_play`, `search_player`, `get_odds_markets`, `get_odds_spot`, `get_odds_history` |
| `analysis:read` | `get_mlb_matchups`, `get_player_props`                                                                                                                            |

Both scopes are read-only; a token never grants account or billing access. Assistants
request both by default. Request only `stats:read` if an agent does not need the analysis
tools. Revoke a connected assistant from the dashboard at any time.

## Requesting least privilege
* **Agents:** use a `sk_test_…` key named after the agent, or the MCP OAuth flow, never a
  shared production key.
* **Products:** one `sk_live_…` key per service; rotate on a schedule via the dashboard.
* **CI:** a `sk_test_…` key stored as a secret; revoke when the pipeline is retired.
