Skip to main content
Scopes are sent space-separated in the authorize URL and echoed back in the token response. We recommend requesting only the scopes your integration needs, since each one is shown to the user on the consent screen and high-risk scopes are flagged.

The Registry

Three further scopes exist in the authorization server, positions:read, social:read, and social:write, but they are hidden and cannot be selected when you register an app. Nothing in the API gates on them yet, so offering them would promise access that does not exist. Grants that already carry one continue to work.

Endpoint to Scope Map

Two of these groupings are not obvious from the scope names. Settling a proposal is gated by governance:vote rather than governance:propose, because settling closes a finished vote. Withdrawing a bond and finalizing expired metadata are both gated by governance:propose, even though neither creates a proposal.

Reads Require No Scope

The following endpoints mirror public on-chain state, so any valid access token may call them.
  • GET /partner/v1/governance/{mint}
  • GET /partner/v1/governance/proposals/{proposal}/votes
GET /partner/v1/governance/{mint} includes a viewerVotes array containing the connected user’s own votes, derived from the access token. You get these without a scope and without making a second request.

Requesting Scopes

Scopes are passed space-separated in the authorize URL.
The server splits on whitespace or +. A single unknown scope will fail the entire string. A 403 insufficient_scope response names the scope you need in its message field.

Widening a Grant

An existing token cannot be widened. To request additional scopes, send the user back through the authorize flow with the wider set and exchange the new code.
Re-consenting merges scopes on the underlying grant, but each access token only carries the scopes from the code that produced it. Make sure you use the newly issued token, since the previous one keeps its narrower set until it expires.