# Scopes


Source: https://docs.stxapp.io/oauth/scopes/

A scope is a named slice of a member's account that they grant your app. You request scopes on the [authorize](/oauth/authorization-flow/) request, the member approves them, and every token your app holds is confined to them. Ask for the least you need: members approve a short list faster than a long one.

There are two disjoint vocabularies. **Member scopes** travel on a member token, through consent. **App scopes** travel on an app token (`client_credentials`), with no member. Neither ever satisfies the other.

## Member scopes

Named `resource.action`, where the action is `read` or `write`. This is the complete list. Paths are under `/api/v1`; `{user_id}` is the member's id from `GET /api/v1/me`.

| Scope | Lets your app | REST | Channels |
| --- | --- | --- | --- |
| `profile.read` | See who the member is: user and account ids, public handle and avatar. No name or other personal details | `GET /me` | |
| `balance.read` | See their cash balance | `GET /account/balance` | `balances:{user_id}` |
| `portfolio.read` | See their open positions, settlement history, and loyalty, fee and adjustment ledgers | `GET /positions`, `GET /account/market_stats`, `GET /portfolio/settlements`, `GET /portfolio/loyalty`, `GET /portfolio/fees`, `GET /portfolio/adjustments` | `positions:{user_id}`, `settlements:{user_id}` |
| `orders.read` | See their orders and fills | `GET /orders`, `GET /orders/{id}`, `GET /fills` | `orders:{user_id}`, `fills:{user_id}` |
| `transfers.read` | See their deposit and withdrawal history | `GET /portfolio/deposits`, `GET /portfolio/withdrawals` | |
| `orders.write` | Place and cancel orders for them | `POST /orders`, `POST /orders/batched`, `DELETE /orders/{id}`, `DELETE /orders/batched`, `DELETE /orders/all` | joining `orders:{user_id}` with `cancel_on_disconnect` |
| `terms.write` | Accept the terms and conditions for them | `POST /tnc/accept` | |

`GET /fills` takes an `order_ids` filter (comma-separated UUIDs of the member's own orders) alongside `market_ids`, both under `orders.read`. An id belonging to another account matches nothing rather than erroring.

A member channel needs the matching scope **and** the member's own `user_id` in the topic. Any other account channel (`account:`, `portfolio:`, `user_info:`, `active_*`, and the rest) is refused to an OAuth token whatever its scopes.

## App scopes

| Scope | REST | Channels |
| --- | --- | --- |
| `market_data` | `GET /markets` | `market:<market_id>`, `orderbook`, `ticker`, `trades`, `market_stats`, `markets`, `market_info`, `market_updates` |
| `events` | `GET /events` | `events` |

An app token is refused by every member endpoint and member channel.

### Member tokens read the catalogue too

`GET /api/v1/markets` and `GET /api/v1/events` are the market and event catalogue. A **member** token reads both whatever its scopes, and joins the public market-data channels above without any scope. An app token is needed only to read the catalogue with no member involved.

## No scope moves money

There is deliberately no scope that initiates, approves or cancels a deposit or a withdrawal. `transfers.read` is read-only history. A member funds their account on STX, never through your app, which keeps your app out of money transmission.

## Effective scope

The scope a request actually has is

```
token scopes ∩ grant scopes ∩ client.allowed_scopes
```

evaluated on every call. A member revoking the grant, or STX narrowing your client's allowed scopes, takes effect on the next request without waiting for the token to expire. For an app token the grant term drops out: `token scopes ∩ client.allowed_scopes`.

## How a request is narrowed

- The authorize request's `scope` is intersected with the scopes your client is allow-listed for. Scopes outside the allow-list are dropped, and the consent screen shows what remains.
- An unknown scope, or nothing left after narrowing, fails with `invalid_scope`. A request with no `scope` fails with `invalid_request`. Both come back to your `redirect_uri`.
- The member allows or denies the list as a whole.

## The grant only widens

A member's grant records every scope they have approved for your app. Approving more later widens it; a later request for fewer does not shrink it. An access token carries the scopes of the request that minted it and is re-checked against the grant on every call, so a wider consent later never widens a token already issued. Consent narrows only when the member revokes it, from [Connected apps](/isv/hosted-pages/#connected-apps).

## `orders.write` and verification

A member can consent before their identity verification is complete. The grant is issued, and the consent screen tells them that placing orders stays unavailable until verification completes.
