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

# OAuth Scopes

> What each scope grants and how to request the right ones.

Scopes are intentionally **broad** — three values, each covering a coherent capability area. Request only what you need.

## Defined scopes

| Scope    | Enum                | Grants                                                                                    |
| -------- | ------------------- | ----------------------------------------------------------------------------------------- |
| `read`   | `AUTH_SCOPE_READ`   | Catalog, search, browse, library, playlists, profile reads.                               |
| `stream` | `AUTH_SCOPE_STREAM` | Stream acquisition (`AcquireMusicStream`, `AcquireVideoStream`) — the **billable** event. |

Defined in [`sdk/auth/v1/scope.proto`](https://github.com/anghami/sdk/blob/main/sdk/auth/v1/scope.proto).

A `write` scope (value `2`) is reserved in the enum range but not yet exposed — library and playlist mutations are not in the public SDK today. When mutations land, `write` will be the scope to request.

## Requesting scopes

Pass a space-separated list in the OAuth authorization URL:

```
&scope=read+stream
```

The user sees the scopes during consent and can refuse. The granted scopes are echoed back in the token response — always **check the actual `scope` field** on the response, not the requested scopes, since the user may have granted a subset.

## Per-RPC scope requirements

| Service / RPC                                    | Required                                                 |
| ------------------------------------------------ | -------------------------------------------------------- |
| `MusicCatalogService.*`, `VideoCatalogService.*` | `read` (or API key)                                      |
| `DiscoveryService.*`                             | `read` (or API key)                                      |
| `SoundtrackService.*`                            | `read` (or API key)                                      |
| `PlaylistService.GetPlaylist`                    | `read` (or API key — public playlists only with API key) |
| `PlaylistService.GetUserPlaylists`               | `read`                                                   |
| `LibraryService.*`                               | `read`                                                   |
| `UserService.GetCurrentUser`                     | `read`                                                   |
| `StreamingService.AcquireMusicStream`            | `stream`                                                 |
| `StreamingService.AcquireVideoStream`            | `stream`                                                 |
| `DeveloperService.*`                             | OAuth (any scope) — gated by developer identity          |
| `AuthService.*`                                  | None (these are the auth endpoints)                      |

## Scope vs API key

| Capability         | API key | OAuth `read` | OAuth `stream` |
| ------------------ | ------- | ------------ | -------------- |
| Catalog reads      | ✅       | ✅            | (irrelevant)   |
| Library reads      | ❌       | ✅            | (irrelevant)   |
| Stream acquisition | ❌       | ❌            | ✅              |

In short: API keys are for non-user catalog access. OAuth is for everything user-scoped, with `stream` separated out so users can grant catalog access without granting playback (and so you can audit billable acquires against tokens that were specifically authorized for it).

## Best practices

* **Request narrow.** If your app only browses the catalog, request `read`. Don't ask for `stream` you won't use.
* **Drop scopes on degraded flows.** A read-only "preview mode" should drop `stream` from its scope request.
* **Re-authorize for new scopes.** You cannot upgrade an existing token's scopes — the user must re-authorize through `/v1/auth/authorize` with the new scope set.
* **Inspect what you got.** Always check the response `scope` field; users can deselect scopes during consent.
