# OAuth

> How an app acts for other STX members with OAuth 2.0, how that differs from an API key, and where OAuth is enabled.

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

export const demo = (id) => cfg.regions.find((r) => r.id === id).environments.find((e) => e.id === 'integration').url

STX supports two ways to authenticate. An **API key** signs requests for your own account. **OAuth** lets an app act for other STX members: a member signs in on STX, approves the access your app asks for, and your app calls the API for them with a scoped token they can revoke at any time.

STX uses standard OAuth 2.0: the authorization code flow with PKCE (Proof Key for Code Exchange). A standard OAuth client library works against it. If you are building a product for STX members, the [ISV program](/isv/) covers access, the hosted pages and the TypeScript SDK; these pages cover the protocol.

## API key or OAuth

| | API key | OAuth |
| --- | --- | --- |
| Who acts | You, on your own account | Your app, for a member, or as itself |
| Credential | Your Ed25519 key | A member's scoped access token, or an app token |
| The member's secrets | You hold your own key | You never see them |
| Consent | Not applicable | The member grants it once and can revoke it |
| Good for | Your own trading, bots, market making | A product used by STX members; a site showing prices |

Trading your own account needs only an API key; see [Authentication](/api/authentication/).

## The model

- **Client**: your application, registered once with STX as one of four [application types](/isv/#application-types). It has a public `client_id` and, for a Web app or Server-to-server app, a `client_secret`.
- **Member**: an STX account holder using your app. They sign in to STX directly; you never handle their credentials.
- **Grant**: a member's standing consent for your client, the set of scopes they approved. One active grant per member per client. Revoking it cuts your access.
- **Scope**: a named slice of access, such as `balance.read` or `orders.write`. See [Scopes](/oauth/scopes/). Deposits and withdrawals are never delegable.

A **member token** (authorization code with PKCE) proves your app may act for one member within a scope. A **refresh token** gets a new one without the member. An **app token** (`client_credentials`) authenticates the app itself, with no member, for the public market and event catalogue. All are opaque strings. Hold tokens on your server where you have one. A Browser app or Mobile or desktop app keeps them in memory or the platform's secure storage, never in a URL, a log or a shipped bundle.

## The endpoints at a glance

| Endpoint | Method | Auth | Purpose |
| --- | --- | --- | --- |
| `/oauth/authorize` | GET | member's browser session | Send the member to consent ([Authorization code flow](/oauth/authorization-flow/)) |
| `/oauth/token` | POST | `client_secret_basic`, or `client_id` for a Browser app or Mobile or desktop app | Code exchange, refresh, client credentials |
| `/oauth/revoke` | POST | same | Revoke a token pair ([Revoking](/oauth/tokens-and-security/#revoking)) |
| `/oauth/introspect` | POST | `client_secret_basic` | Check one of your own tokens ([Checking a token](/oauth/tokens-and-security/#checking-a-token)) |
| `/oauth/register` | POST | none | Dynamic client registration, off by default ([Dynamic registration](/oauth/tokens-and-security/#dynamic-registration)) |
| `/.well-known/oauth-authorization-server` | GET | none | Server metadata, RFC 8414 ([Discovery](/oauth/discovery-and-errors/#discovery)) |
| `/.well-known/oauth-protected-resource` | GET | none | Resource metadata, RFC 9728 ([Discovery](/oauth/discovery-and-errors/#discovery)) |

## Calling the API with a token

An access token is a bearer on the same [REST API](/api/rest/) a signed request uses, sent as `Authorization: Bearer <token>` on `/api/v1`. On the [WebSocket](/websockets/), send it in the handshake header `x-stx-oauth-token`. Every call is limited to the scopes the member approved; see [effective scope](/oauth/scopes/#effective-scope).

The [rate limit guidance](/concepts/rate-limits/) applies to calls made with an OAuth token as it does to signed requests.

## In this section

  - [Authorization code flow](/oauth/authorization-flow/): The steps from redirect to a call made as the member, silent re-authorization, and app tokens.
  - [Scopes](/oauth/scopes/): Every scope, the routes and channels it reaches, and how a request is narrowed.
  - [Tokens and security](/oauth/tokens-and-security/): Lifetimes, refresh and rotation, revoking, introspection, dynamic registration, and a checklist for production.
  - [Discovery and errors](/oauth/discovery-and-errors/): The metadata documents, and every error the OAuth endpoints and the API return.
