A scope is a named slice of a member’s account that they grant your app. You request scopes on the authorize 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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “Effective scope”The scope a request actually has is
token scopes ∩ grant scopes ∩ client.allowed_scopesevaluated 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
Section titled “How a request is narrowed”- The authorize request’s
scopeis 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 noscopefails withinvalid_request. Both come back to yourredirect_uri. - The member allows or denies the list as a whole.
The grant only widens
Section titled “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.
orders.write and verification
Section titled “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.

