Skip to main content
Use this flow when people sign in to your app with their own account. It requires a Web application and PKCE with the S256 method.

How it works

1

Send the user to the authorize endpoint

Your app redirects the browser to /oauth/authorize with your client_id, a redirect_uri, the scope, a state, and a PKCE code_challenge.
2

The user approves

We show the consent screen with the scopes you requested. The user approves or denies.
3

We redirect back with a code

On approval we redirect to your redirect_uri with a one time code and your state. On denial it redirects with error=access_denied.
4

Exchange the code for tokens

Your server calls the token endpoint with the code and the PKCE code_verifier and receives an access token and a refresh token.

Generate PKCE values

PKCE is required. Create a random code_verifier, then derive the code_challenge as the base64url encoded SHA256 of the verifier.
pkce.ts
The SDK does this for you through oauth.authorize_url(). Reach for it unless you need the raw flow.

Step 1: authorize request

Redirect the user to the authorize endpoint.
string
required
Must be code.
string
required
Your application client_id.
string
required
Must exactly match one of the redirect URIs registered on the application.
string
required
A space separated list of scopes. See Scopes.
string
required
The base64url SHA256 of your code_verifier.
string
required
Must be S256.
string
An opaque value your app generates. We return it unchanged so you can defend against cross site request forgery.
A complete URL looks like this.

Step 2: the redirect back

After the user approves, we redirect to your redirect_uri.
If the user denies, or the request is invalid, we redirect with an error.
Always compare the returned state to the value you sent before you trust the code.

Step 3: exchange the code

Your server exchanges the code at the token endpoint. Send your client_secret and the matching code_verifier.
A successful response returns the tokens.

Step 4: call the API

Send the access token as a bearer token. Read the user who approved access from GET /api/v1/user.

Refresh the access token

Access tokens last one hour. Use the refresh token to get a new one. Refresh tokens rotate, so replace the stored refresh token with the one you receive back.

Effective scopes

The access token is limited to the scopes the user approved, intersected with the scopes the application currently holds. If you later remove a scope from the application, existing tokens lose that scope on their next request.

Errors

redirect error
The user declined on the consent screen.
token error
The code was already used, expired, or the code_verifier did not match the code_challenge.
token error
The client_id or client_secret is wrong, or the app is disabled.
api error
The token is valid but does not carry the scope the endpoint requires.