> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nexrex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Scopes

> The seven API permissions and how legacy keys map to them.

Each API key carries one or more **scopes**. Every endpoint requires a specific
scope, named in its reference entry. A request whose key lacks the required scope
receives `403` with code `missing_scope` — and the error message names the scope
that was missing.

Grant the narrowest set of scopes your integration needs.

## The scopes

| Scope             | Grants                                                    |
| ----------------- | --------------------------------------------------------- |
| `org:read`        | Read organization metadata (name, athlete count)          |
| `athletes:read`   | List athletes and read athlete profiles                   |
| `activities:read` | Read athlete activity data (privacy-filtered — see below) |
| `plans:read`      | Read athletes' active training plans                      |
| `groups:read`     | Read organization group metadata                          |
| `exports:create`  | Create asynchronous data-export jobs                      |
| `exports:read`    | List, inspect, and download export jobs                   |

## Legacy aliases

Keys created before scoped permissions existed carry a coarse `read`, `write`, or
`admin` scope. These still work and are expanded automatically:

| Legacy scope | Expands to                             |
| ------------ | -------------------------------------- |
| `read`       | all five `*:read` scopes               |
| `admin`      | all seven scopes                       |
| `write`      | *(no developer-API access — reserved)* |

You don't need to migrate old keys. When you create a new key, pick the precise
scopes instead.

## The privacy ceiling on activity data

`activities:read` never exposes more than a **coach in the same organization**
would see for that athlete. Every activity is filtered through the athlete's own
privacy settings before it leaves the API: fields an athlete has chosen to keep
private (pace, map, heart rate, and so on) are removed, and activities they have
hidden are omitted entirely.

Athletes can also mark **individual activities** as private from the mobile app,
independent of their global privacy settings. A per-activity opt-out is treated
like any other privacy filter: the activity is omitted from `GET /activities`
list results, and `GET /activities/{activity_id}` returns `404` for it.

<Note>
  This means two keys with the same scope can receive different data for the same
  athlete over time, as that athlete adjusts their privacy settings. Build for a
  field being absent rather than assuming a fixed shape.
</Note>
