Skip to main content
Scopes control what an access token can do. Request the smallest set your app needs. In the authorization code flow the user sees these scopes on the consent screen and approves them. Pass scopes as a space separated string in the scope parameter, or build them with the SDK.
A scope is always resource:action, and the action is always read or write.

Reference

The names that trip people up: it is mapping: and not mappings:, members: and not workspace_members:, and profile:read and not user:read. There is no metrics: scope, usage:read covers metrics. profile and usage are read-only, so profile:write and usage:write do not exist.

Build scopes with the SDK

Typing scope strings by hand is where the mistakes happen, and a wrong one fails as a 403 long after the request that caused it. build_scopes validates as it builds, so a bad resource or action throws immediately.
All four forms return the same kind of value: a deduplicated Scope[] in canonical order.
Scope[]
One resource. enabled: false returns an empty array, which makes a conditional scope a one liner rather than a branch.
Scope[]
A map of resources. A value of true means every action the resource supports. You can also pass "read", ["read", "write"], or { read: true, write: false }.
Scope[]
Validate scope strings you already have, or bare resource names, which expand to every action the resource supports.
authorize_url accepts every one of these directly, so calling build_scopes first is optional.
The returned scopes is the resolved list that was actually sent.

Aliases

The SDK accepts a few aliases for the names that differ from the resource they guard. They resolve to the canonical scope, so build_scopes("user", "read") returns ["profile:read"].

Helpers

Read the profile

profile:read is the scope that answers “who approved access”. With it, a token can call GET /api/v1/user and read the account.
The response never includes secrets such as passwords, tokens, or two factor material.

Scopes that cover more than their name

A few scopes grant access to a resource you would not guess from the name. Two more gaps worth knowing before you design around them. workspaces:write covers create and update but not delete, so DELETE /api/v1/workspaces/{id} cannot be reached by an OAuth token alone. keys:write covers create and update, but not delete.

Sensitive scopes

keys:write lets an app mint gateway API keys, and members:write lets an app manage who belongs to a workspace. Request them only when the app truly needs them, and expect users to scrutinize them on the consent screen.

How scopes are enforced

A request must satisfy two checks. The token must carry the scope, and the account must have permission for the action. If either fails the API returns 403. If the token is missing or expired the API returns 401. The token is limited to the intersection of the scopes the user approved and the scopes the application currently holds. Narrowing an application’s scopes narrows every token it issued.