# Scopes

> The permissions a token carries. User-consent scopes (openid, profile, email, offline_access, passes:*, invites:read) for OAuth apps, and org:* scopes for organization API keys.

A **scope** is a permission a credential carries. Two disjoint sets exist, one per authentication model: **user-consent scopes** that a signed-in user grants to an OAuth app, and **organization scopes** that an admin assigns to an [API key](/docs/api-keys/overview/). Always request the **least privilege** the integration needs.

## User-delegated scopes (OAuth consent)

Request these in the `scope` parameter of the [authorize request](/docs/oauth/authorize/), space-delimited. They must be a subset of the client's allowed scopes, and the user approves them on the consent screen. If you omit `scope`, the default is `openid profile email`.

| Scope | Grants |
|---|---|
| `openid` | Identity: the `sub` claim, an [`id_token`](/docs/oauth/id-token-userinfo/), and access to [UserInfo](/docs/oauth/id-token-userinfo/). Required for OIDC. |
| `profile` | The `name` and `picture` claims. |
| `email` | The `email` and `email_verified` claims. |
| `offline_access` | A rotating [refresh token](/docs/oauth/token/), so you can obtain fresh access tokens without re-prompting. |
| `passes:read` | View the user's guest passes ([`GET /api/v1/passes`](/docs/api-reference/passes/)). |
| `passes:write` | Create and revoke the user's guest passes ([`POST` / `DELETE /api/v1/passes`](/docs/api-reference/passes/)). |
| `invites:read` | View organization invitations addressed to the user ([`GET /api/v1/invites`](/docs/api-reference/invitations/)). |

A typical resident-app request:

```
openid profile email offline_access passes:read passes:write invites:read
```

Consent is remembered per user, client, and scope: requesting the same or a narrower set stays silent, while requesting a **superset** re-prompts. Send `prompt=consent` to force the consent screen every time.

## Organization API-key scopes

These are assigned when an admin mints an [API key](/docs/api-keys/create-and-manage/) in **Settings → API keys**. They act across the **whole organization**, not on behalf of a single user, and gate the [`/api/v1/org/*`](/docs/api-reference/organization/) endpoints.

| Scope | Grants |
|---|---|
| `org:passes:read` | Read every pass in the organization ([`GET /api/v1/org/passes`](/docs/api-reference/organization/)). |
| `org:passes:write` | Create and revoke any pass in the organization ([`POST` / `DELETE /api/v1/org/passes`](/docs/api-reference/organization/)). |
| `org:facilities:read` | List the organization's facilities ([`GET /api/v1/org/facilities`](/docs/api-reference/organization/)). |

## Enforcement

Scopes are checked on every request. A token that lacks a required scope is rejected with **`403 insufficient_scope`**, and the `WWW-Authenticate: Bearer` response header names the scope that was missing:

```http
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope", scope="passes:write"
```

For user-delegated calls, the acting user must **also** still hold the underlying organization role — a revoked resident cannot keep acting through an old grant, even if the token's scope is intact. See [Errors](/docs/api-reference/errors/) for how to react.