Developer
Authentication
Atlas accepts two kinds of credential on every /v1 request and on the hosted MCP endpoint: a Personal Access Token for first-party and CI use, or an OAuth 2.0 access token for third-party apps that act on a user's behalf. This guide covers both end to end (mint, use, scope, refresh, introspect, rotate, and revoke) with copyable examples grounded in the real endpoints.
Two kinds of credential
Every authenticated call carries a bearer token in the Authorization header. The header shape is identical for both credential types; only how you obtain and manage the token differs.
Personal Access Token
A long-lived token that carries your own permissions, narrowed to the scopes you pick. Best for scripts, CI, backend jobs, and first-party integrations. Prefixed atlas_pat_.
OAuth 2.0 access token
A short-lived token a user grants to a third-party app through a consent screen. Best when someone else's app needs to act on a user's behalf without ever seeing a password or a PAT. Expires in one hour; refreshed automatically.
Authorization: Bearer atlas_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThe same /v1 API and the same hosted MCP endpoint accept either credential. Scopes, tenant isolation, and rate limits are enforced identically regardless of which one you send.
PAT vs OAuth: when to use which
Both are first-class. The right choice is about who owns the credential and who the caller is acting as.
| Personal Access Token | OAuth 2.0 | |
|---|---|---|
| Acts as | You (the token owner). | The user who granted consent. |
| Best for | CI, cron, backend jobs, your own scripts, and tools for a single workspace. | Third-party apps, marketplace integrations, anything you ship to other people. |
| Lifetime | Long-lived until you revoke or it hits its optional expiry. | Access token 1 hour; refresh token 30 days, rotated on every use. |
| Obtained via | Settings, then API access. | A registered app and the authorization-code (or device) flow. |
| Secret handling | One token string. Treat it like a password. | A client_id (+ client_secret for confidential apps) plus per-user tokens. |
| Revocation | Revoke the token in Settings. | Revoke a single token, or revoke the whole app to cut off every user at once. |
Rule of thumb
Personal Access Tokens
A PAT is the shortest path from nothing to an authenticated request. It carries your permissions, narrowed to the scopes you grant, and is revocable independently of your login session.
Create a token
Open Settings, then API access, and click New token. Give it a name, pick the narrowest scopes the job needs (start withtasks:read), and optionally set an expiry. The token is shown once and starts withatlas_pat_, so copy it now and store it in a secret manager.Send it as a bearer header
Pass the token verbatim on every request. No exchange, no refresh: a PAT is ready to use the moment it is minted.curl -H "Authorization: Bearer atlas_pat_REPLACE_ME" \ https://api-atlas.wrxstack.com/v1/tasks?limit=50Rotate or revoke any time
The same page lists every token with its last-used time. Rotate issues a fresh secret and invalidates the old one; Revoke kills it immediately. See Rotate and revoke below.
Scopes are enforced per request
403 (insufficient-scope) if the token is missing the scope a route requires. The problem body lists requiredScopes and grantedScopes so you know exactly what to add. See the 403 example in the REST guide.Scopes
Scopes are a coarse resource:action split (read, write, sometimes delete) per resource. The same vocabulary applies to PATs and to OAuth apps, so a token or an app only ever gets what you check. Grant the least you need.
ai
| Scope | Grants |
|---|---|
ai:read | Use Ask Atlas, semantic search, and other read-only AI helpers. |
ai:write | Natural-language capture creating tasks, AI rescheduling, etc. |
announcements
| Scope | Grants |
|---|---|
announcements:read | View workspace announcements. |
announcements:write | Create, schedule, and publish workspace announcements. |
appointments
| Scope | Grants |
|---|---|
appointments:read | List confirmed bookings, view appointment detail, subscribe to the appointments ICS feed. |
appointments:write | Reschedule, cancel, mark no-show, send reminders, and edit private host notes. |
attachments
| Scope | Grants |
|---|---|
attachments:read | List file attachments and download them through short-lived links. |
attachments:write | Upload files and attach them to work items. |
attachments:delete | Remove attachments from work items. |
automations
| Scope | Grants |
|---|---|
automations:read | View automation rules, run history, versions, and the workflow-template catalog. |
automations:write | Create, update, delete, enable/disable, run, and revert automations; install templates. |
billing
| Scope | Grants |
|---|---|
billing:read | View subscription, invoices, and plan/entitlement status. |
billing:write | Start checkout, change plan, add seats, and cancel - for workspace admins. |
booking
| Scope | Grants |
|---|---|
booking:read | View booking pages, meeting types, questions, and availability. |
booking:write | Create and change booking pages, meeting types, questions, and blackout dates. |
calendar
| Scope | Grants |
|---|---|
calendar:read | View calendar events, availability, booking metadata, and conflicts. |
calendar:write | Create, reschedule, cancel, and update calendar-backed bookings. |
chat
| Scope | Grants |
|---|---|
chat:read | View chat channels, members, and message history. |
chat:write | Create channels/DMs, post/edit/delete messages, and manage members and reactions. |
comments
| Scope | Grants |
|---|---|
comments:read | View comments and discussion threads on work items. |
comments:write | Create and update comments on work items. |
connectors
| Scope | Grants |
|---|---|
connectors:read | See which apps are connected and read data through them. Your workspace administrator must allow this first. |
connectors:manage | Run write operations through connected apps and change connector settings. Your workspace administrator must allow this first. |
contracts
| Scope | Grants |
|---|---|
contracts:read | View contracts, their clauses, and renewal dates. |
contracts:write | Draft, edit, approve, and send contracts, and record renewals. |
crm
| Scope | Grants |
|---|---|
crm:read | View accounts, contacts, deals, pipelines, activities, and forecasts. |
crm:write | Add and change accounts, contacts, deals, and activities, and move deals through a pipeline. |
crm:delete | Archive or delete accounts, contacts, and deals. |
dashboards
| Scope | Grants |
|---|---|
dashboards:read | View dashboards and their widgets. |
dashboards:write | Create and change dashboards and their widgets. |
delivery
| Scope | Grants |
|---|---|
delivery:read | View engagements and everything recorded against them. Your workspace administrator must allow this first. |
delivery:write | Create and change engagements and act on deliverables and approvals. Your workspace administrator must allow this first. |
developer
| Scope | Grants |
|---|---|
developer:manage | Register OAuth apps, manage API keys, and view API usage and rate limits. |
diagrams
| Scope | Grants |
|---|---|
diagrams:read | List, view, and export diagrams, templates, and shape libraries. |
diagrams:write | Create/update diagrams, templates, comments, bindings, and share links. |
diagrams:delete | Archive or delete diagrams, comments, bindings, and share links. |
esign
| Scope | Grants |
|---|---|
esign:read | View signature envelopes, their recipients, and their status. |
esign:write | Create, send, remind, and void signature envelopes. Signing itself happens in Atlas. |
forms
| Scope | Grants |
|---|---|
forms:read | List forms and export their submissions. |
forms:write | Create, update, and delete forms and manage task approval requests. |
goals
| Scope | Grants |
|---|---|
goals:read | View Objectives and Key Results, including linked projects. |
goals:write | Create and update Objectives and Key Results. |
goals:delete | Permanently remove Objectives and Key Results. |
growth
| Scope | Grants |
|---|---|
growth:read | View your referral summary and NPS survey eligibility. |
growth:write | Create and change growth suite records, agreements, and approvals. |
habits
| Scope | Grants |
|---|---|
habits:read | View your habits, streak statistics, and at-risk habits. |
habits:write | Create, update, archive, and check in/out of habits. |
hr
| Scope | Grants |
|---|---|
hr:read | View employees, departments, leave, attendance, hiring, reviews, and HR requests. |
hr:write | Change employee records and approve or reject leave, hiring steps, and HR requests. |
huddles
| Scope | Grants |
|---|---|
huddles:read | List and view lightweight audio/video huddles and their rosters. |
huddles:write | Start, join, leave, update state for, and end huddles. |
inbox
| Scope | Grants |
|---|---|
inbox:read | List your notifications and read the unread count. |
inbox:write | Mark notifications read/unread and mark all as read. |
intelligence
| Scope | Grants |
|---|---|
intelligence:read | Semantic search, recommendations, and summaries via the local intelligence layer. |
intelligence:write | Natural-language capture and generation via the local intelligence layer. |
meetings
| Scope | Grants |
|---|---|
meetings:read | View meetings, notes, transcripts, and action items. |
meetings:write | Create meetings, edit notes, and turn action items into tasks. |
onboarding
| Scope | Grants |
|---|---|
onboarding:read | View client onboardings, their templates, and their tasks. |
onboarding:write | Start, update, and complete client onboardings. |
pats
| Scope | Grants |
|---|---|
pats:manage | List, mint, and revoke other access tokens. Sensitive - grant sparingly. |
payroll
| Scope | Grants |
|---|---|
payroll:read | View salary structures, payroll runs, declarations, and loans. Sensitive. |
payroll:write | Change salary structures and calculate, approve, and pay payroll runs. Sensitive. |
| Scope | Grants |
|---|---|
pdf:read | List and download PDF documents and jobs, read annotations, and run read-only analysis such as comparison, signature verification, and text extraction. |
pdf:write | Convert, split, extract pages, stamp, sign, encrypt, optimise, and fill PDF forms, and create or change documents, versions, jobs, and annotations. |
privacy
| Scope | Grants |
|---|---|
privacy:read | View consent records and data export requests. |
privacy:manage | Record consent and start data exports. |
profile
| Scope | Grants |
|---|---|
profile:read | Read your name, email, timezone, locale, and notification config. |
profile:write | Update your profile details, preferences, and public profile fields. |
projects
| Scope | Grants |
|---|---|
projects:read | List and view your projects (no task data on its own). |
projects:write | Add new projects, rename, or reorganise existing ones. |
projects:delete | Archive or permanently delete projects. |
reports
| Scope | Grants |
|---|---|
reports:read | List, run, and export report and dashboard definitions (JSON/CSV). |
reports:write | Create and change report definitions and schedule report deliveries. |
search
| Scope | Grants |
|---|---|
search:read | Run global, unified, and cross-tool searches across content you can access. |
service
| Scope | Grants |
|---|---|
service:read | View incidents, postmortems, on-call schedules, and alert sources. Your workspace administrator must allow this first. |
service:write | Declare and update incidents and publish postmortems. Your workspace administrator must allow this first. |
tasks
| Scope | Grants |
|---|---|
tasks:read | List, view, and search your tasks across all projects. |
tasks:write | Add new tasks, change status, priority, schedule, or assignee. |
tasks:delete | Move tasks to the archive or permanently delete them. |
time
| Scope | Grants |
|---|---|
time:read | List your time entries and view the currently running timer. |
time:write | Create, start, stop, and update your time entries. |
time:delete | Permanently remove your time entries. |
webhooks
| Scope | Grants |
|---|---|
webhooks:manage | Create, update, replay, and delete outbound webhook subscriptions. |
whiteboards
| Scope | Grants |
|---|---|
whiteboards:read | List and view whiteboards and their contents. |
whiteboards:write | Create whiteboards and edit what is on them. |
whiteboards:delete | Permanently remove whiteboards. |
wiki
| Scope | Grants |
|---|---|
wiki:read | View wiki spaces, pages, revisions, and comments. |
wiki:write | Create and edit pages, publish them, restore revisions, and comment. |
wiki:delete | Permanently remove wiki pages. |
workload
| Scope | Grants |
|---|---|
workload:read | View workload allocation, overallocations, leveling proposals, and capacity profiles. |
workload:write | Create or replace per-user capacity profiles used by workload math. |
workspace
| Scope | Grants |
|---|---|
workspace:read | View members, teams, roles, access grants, and the audit log. |
workspace:manage | Invite and remove members and change teams, roles, and access grants. Sensitive. |
What a token can and cannot do
A personal access token or an OAuth access token acts as the person who created it. It is subject to that person's role, module permissions, and plan, exactly as they are when signed in, and scopes only narrow it further. When the person is removed from the workspace or their access is disabled, every token they created stops working on the next request. The workspace IP allowlist applies to tokens as well as to signed-in sessions, in addition to any allowlist set on the token itself.
An operation accepts a token only when it declares the scope it requires. A few operations are never available to a token, whatever scopes it holds:
- Create or rotate an access token. Listing and revoking tokens remain available.
- Sign in, sign out, manage sessions, and two-factor authentication.
- Approve an OAuth application or register one.
- Delete or export an account.
- Configure single sign-on, SCIM, or the workspace IP allowlist.
- Change the plan or pay for it.
- Super administration.
Sensitive areas
Four areas hold a workspace's most sensitive records, so tokens cannot use their scopes until a workspace owner or administrator allows the area in Settings, then API access, under Sensitive areas. The setting is checked on every request, so allowing or withdrawing an area applies to every token at once, and each change is recorded in the audit log.
| Area | Scopes | Covers |
|---|---|---|
| Chat content | chat:* | Channels, direct messages, and message history. |
| Connected apps | connectors:* | Data read and actions taken through the apps connected to this workspace. |
| Client delivery | delivery:* | Client engagements and everything recorded against them. |
| Service operations | service:* | Incidents, postmortems, and on-call schedules. |
When a token is refused, the response is a 403 problem, and its type field says why:
| Problem type | Meaning | What to do |
|---|---|---|
scope-family-disabled | The token holds the scope, but the workspace has not allowed its sensitive area. | Ask a workspace owner or administrator to allow the area under Sensitive areas. |
insufficient-scope | The operation declares a scope the token does not hold. | Create a token with one of the scopes listed in requiredScopes. |
scope-not-declared | The operation is not available to tokens. | Call it from the Atlas app while signed in. |
session-only | The operation manages credentials, identity, or billing. | Sign in to Atlas and do it there. |
pat-ip-blocked | The request came from an address outside the token's allowlist. | Call from an allowed address, or change the allowlist. |
OAuth 2.0
Atlas is a full OAuth 2.1 authorization server. Third-party apps register once, then run the authorization-code flow (with PKCE) so a user can grant scoped access without sharing a password or a PAT. Access tokens are opaque bearer tokens that expire in one hour and refresh silently.
Everything is discoverable
/.well-known/oauth-authorization-server and let your OAuth library configure itself. The endpoints below are shown for clarity; the discovery document is the source of truth.1. Register an app
Open Settings, then Developer and click Register OAuth app. Provide a name, one or more redirect URIs (exact-match HTTPS callbacks), and the scopes the app may request. Choose the client type:
| Client type | Credential | Use when |
|---|---|---|
| Confidential | client_id + client_secret (cs_...) | Your app has a backend that can keep a secret (server-side web app, API). |
| Public (PKCE only) | client_id (cli_...), no secret | The code runs where a secret cannot hide (SPA, mobile, CLI, desktop). PKCE is required. |
The secret is shown once
client_secret is displayed only at registration and after each rotation. Store it in a secret manager. If it leaks, rotate it from the same Developer page. See Rotate and revoke.2. Discover the endpoints
Atlas publishes two RFC discovery documents. The first (RFC 8414) tells a client where the authorization server lives; the second (RFC 9728) tells an MCP client which authorization server protects the hosted /mcp resource.
curl https://api-atlas.wrxstack.com/.well-known/oauth-authorization-server{
"issuer": "https://api-atlas.wrxstack.com",
"authorization_endpoint": "https://atlas.wrxstack.com/oauth/authorize",
"token_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/token",
"userinfo_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/userinfo",
"jwks_uri": "https://api-atlas.wrxstack.com/.well-known/jwks.json",
"registration_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/register",
"revocation_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/revoke",
"introspection_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/introspect",
"device_authorization_endpoint": "https://api-atlas.wrxstack.com/v2/oauth/device_authorization",
"scopes_supported": ["tasks:read", "tasks:write", "projects:read", "..."],
"response_types_supported": ["code"],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code"
],
"token_endpoint_auth_methods_supported": ["none", "client_secret_post"],
"code_challenge_methods_supported": ["S256"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"]
}The protected-resource document points MCP clients at the authorization server that guards the hosted /mcp endpoint:
curl https://api-atlas.wrxstack.com/.well-known/oauth-protected-resource{
"resource": "https://api-atlas.wrxstack.com/mcp",
"authorization_servers": ["https://api-atlas.wrxstack.com"],
"scopes_supported": ["tasks:read", "tasks:write", "..."],
"bearer_methods_supported": ["header"],
"resource_name": "Atlas MCP",
"resource_documentation": "https://atlas.wrxstack.com/docs/mcp"
}Endpoint reference
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /.well-known/oauth-authorization-server | Authorization-server metadata (RFC 8414). |
| GET | /.well-known/oauth-protected-resource | Protected-resource metadata for /mcp (RFC 9728). |
| GET | https://atlas.wrxstack.com/oauth/authorize | Browser consent page (on the web origin). Users log in and approve scopes here. |
| POST | /v2/oauth/token | Exchange a code, refresh, or device_code for tokens. |
| POST | /v2/oauth/introspect | Check whether a token is active (RFC 7662). |
| POST | /v2/oauth/revoke | Revoke an access or refresh token (RFC 7009). |
| POST | /v2/oauth/device_authorization | Start the device-code flow (RFC 8628). |
| GET | /v2/oauth/userinfo | Read the subject and granted scope for a bearer access token. |
| GET | /.well-known/jwks.json | Signing keys for id_token verification (RS256). |
MCP clients discover the same thing
/mcp endpoint without a token, Atlas answers 401 with a WWW-Authenticate header that points at /.well-known/oauth-protected-resource. The client reads it, finds this authorization server, and runs the flow below automatically. See the MCP connection guide.3. Authorization code flow (with PKCE)
This is the flow for apps a user signs in to. PKCE (Proof Key for Code Exchange, S256) is required for public clients and recommended for everyone: it stops a stolen authorization code from being redeemed by anyone but you.
Create a PKCE verifier and challenge (public clients)
Generate a high-entropycode_verifier, hash it with SHA-256, and base64url-encode the result into acode_challenge. Keep the verifier; send only the challenge.# 1. code_verifier: 43-128 URL-safe chars kept secret in your app code_verifier=$(openssl rand -base64 96 | tr -d '\n=+/' | cut -c1-96) # 2. code_challenge: base64url( SHA-256( code_verifier ) ) code_challenge=$(printf '%s' "$code_verifier" \ | openssl dgst -binary -sha256 \ | openssl base64 | tr '+/' '-_' | tr -d '=\n') echo "verifier: $code_verifier" echo "challenge: $code_challenge"Send the user to the authorization page
Redirect the user's browser to the authorization endpoint on the web origin. They sign in to Atlas (if not already), see exactly which scopes you asked for, and approve or deny.stateis an opaque anti-CSRF value you generate and verify on the way back.texthttps://atlas.wrxstack.com/oauth/authorize ?client_id=cli_YOUR_CLIENT_ID &redirect_uri=https://yourapp.example/callback &scope=tasks:read%20tasks:write &state=RANDOM_ANTI_CSRF_VALUE &code_challenge=THE_CODE_CHALLENGE &code_challenge_method=S256Receive the code on your redirect URI
On approval, Atlas redirects the browser back to your registeredredirect_uriwith a single-usecodeand yourstate. Reject the response ifstatedoes not match what you sent. A denial returns?error=access_deniedinstead.texthttps://yourapp.example/callback ?code=ac_1a2b3c4d5e6f... &state=RANDOM_ANTI_CSRF_VALUEExchange the code for tokens
POST the code to the token endpoint. Public clients send thecode_verifier; confidential clients send theclient_secret. The code is single-use and expires in five minutes.curl -X POST https://api-atlas.wrxstack.com/v2/oauth/token \ -H "Content-Type: application/json" \ -d '{ "grant_type": "authorization_code", "code": "ac_1a2b3c4d5e6f...", "redirect_uri": "https://yourapp.example/callback", "client_id": "cli_YOUR_CLIENT_ID", "code_verifier": "THE_ORIGINAL_CODE_VERIFIER" }'The token endpoint returns an access token, its lifetime in seconds, a refresh token, and the granted scope:
httpHTTP/1.1 200 OK Content-Type: application/json { "access_token": "at_9f8e7d6c5b4a...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "rt_0a1b2c3d4e5f...", "scope": "tasks:read tasks:write" }
4. Call the API
The access token is an opaque bearer token. Send it exactly like a PAT: the /v1 API does not care which credential type it is.
curl -H "Authorization: Bearer at_9f8e7d6c5b4a..." \
https://api-atlas.wrxstack.com/v1/tasks?limit=505. Refresh before it expires
Access tokens live one hour. When yours nears expiry (or a call returns 401), exchange the refresh token for a new pair. Refresh tokens rotate: each refresh returns a brand-new refresh token and invalidates the one you sent. Store the new one.
curl -X POST https://api-atlas.wrxstack.com/v2/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "rt_0a1b2c3d4e5f...",
"client_id": "cli_YOUR_CLIENT_ID",
"client_secret": "cs_YOUR_CLIENT_SECRET"
}'Reuse detection
Introspect a token
A resource server can ask Atlas whether a token is still active and what it carries (RFC 7662). An inactive token returns simply { "active": false } and nothing else.
curl -X POST https://api-atlas.wrxstack.com/v2/oauth/introspect \
-H "Content-Type: application/json" \
-d '{
"token": "at_9f8e7d6c5b4a...",
"client_id": "cli_YOUR_CLIENT_ID",
"client_secret": "cs_YOUR_CLIENT_SECRET"
}'{
"active": true,
"scope": "tasks:read tasks:write",
"client_id": "cli_YOUR_CLIENT_ID",
"token_type": "Bearer",
"sub": "usr_01HW3RA2B3C4D5E6F7G8H9J0K1",
"aud": "https://api-atlas.wrxstack.com/mcp",
"exp": 1746123456,
"iat": 1746119856,
"jti": "jti_7c9e2f14..."
}Revoke a token
Revoke an access or refresh token (RFC 7009) at logout or when a user disconnects your app. Revoking a refresh token also revokes the access tokens minted from it.
curl -X POST https://api-atlas.wrxstack.com/v2/oauth/revoke \
-H "Content-Type: application/json" \
-d '{
"token": "rt_0a1b2c3d4e5f...",
"token_type_hint": "refresh_token",
"client_id": "cli_YOUR_CLIENT_ID",
"client_secret": "cs_YOUR_CLIENT_SECRET"
}'Device code flow
For inputs-constrained devices (a CLI, a TV, an IoT box) that cannot host a browser redirect, use the device-code grant (RFC 8628). Start it, show the user the user_code and verification_uri, then poll the token endpoint until they approve.
curl -X POST https://api-atlas.wrxstack.com/v2/oauth/device_authorization \
-H "Content-Type: application/json" \
-d '{ "client_id": "cli_YOUR_CLIENT_ID", "scope": "tasks:read" }'{
"device_code": "dc_1a2b3c...",
"user_code": "WDJB-MJHT",
"verification_uri": "https://atlas.wrxstack.com/device",
"verification_uri_complete": "https://atlas.wrxstack.com/device?user_code=WDJB-MJHT",
"expires_in": 600,
"interval": 5
}Poll every interval seconds. Until the user approves you get authorization_pending; once they do, the same call returns the token pair.
curl -X POST https://api-atlas.wrxstack.com/v2/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": "dc_1a2b3c...",
"client_id": "cli_YOUR_CLIENT_ID"
}'Rotate and revoke credentials
Treat every credential as rotatable. Rotate on a schedule, rotate immediately on any suspected leak, and always prefer the least-privilege scope set. Here is every lifecycle path Atlas gives you.
Rotate or revoke a Personal Access Token
- Open Settings, then API access. Each token shows its name, scopes, and last-used time.
- Click Rotate to create a replacement secret for the same token. The new value is shown once; update your secret store, then the old value stops working.
- Click Revoke (the trash action) to kill a token immediately. Every caller using it (including any MCP agent) loses access at once.
Rotate an OAuth app's client secret
- Open Settings, then Developer and find the app in the OAuth applications table.
- Click Rotate secret. Atlas issues a new
cs_...secret and invalidates the previous one. Theclient_idis unchanged, so already-issued user tokens keep working, and only new token exchanges need the new secret. - Deploy the new secret to your backend, then confirm sign-ins still succeed.
Revoke an entire OAuth app
On the same Developer page, Revoke an app to deactivate its client_id and invalidate every access and refresh token issued to every user for that app in one action. Use this when an app is decommissioned or a client secret is known to be compromised and you want a hard cutoff.
Revoke a single OAuth token
To disconnect one user (a logout, an account unlink) without touching anyone else, call POST /v2/oauth/revoke with that user's refresh token - see Revoke a token. This is the RFC 7009 path and is the correct programmatic revocation for a per-user session.
If a credential leaks
Best practices
The short list that keeps an integration secure and boring.
- Least privilege. Grant only the scopes a token or app actually uses. Start read-only and widen when a call needs it.
- Rotate on a schedule. Rotate PATs and client secrets periodically, not just after an incident. Automate it where you can.
- Never embed a secret in a public client. A SPA, mobile, or CLI app is a public client: use PKCE, no
client_secret. - Prefer OAuth for third parties, PAT for first-party. If someone else installs your app, they should sign in with OAuth, never paste your PAT.
- Store the latest refresh token. Refresh tokens rotate; persisting the newest one avoids a reuse-detection lockout.
- Verify
stateand validate redirect URIs. Always check the returnedstate, and register exact-match HTTPS redirect URIs only.