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. |
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 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 | ❌ | ❌ | ✅ |
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 forstreamyou won’t use. - Drop scopes on degraded flows. A read-only “preview mode” should drop
streamfrom its scope request. - Re-authorize for new scopes. You cannot upgrade an existing token’s scopes — the user must re-authorize through
/v1/auth/authorizewith the new scope set. - Inspect what you got. Always check the response
scopefield; users can deselect scopes during consent.