Revoke Token
OAuth
Revoke Token
Invalidate an access token (and its paired refresh token)
POST
Revoke Token
Revoke Token
Revokes an OAuth access token. The endpoint follows RFC 7009 semantics: revocation is idempotent and silent — unknown or already-revoked tokens still return200 success. On a successful revoke the server:
- Locates the app installation that owns this
accessToken. - Blacklists both the access token and its paired refresh token for 31 days (only a hash of each token is stored, never the raw value).
- Clears the stored access token, refresh token, and their expiry timestamps on the installation.
status remains
active. The merchant must call POST /apps/store/uninstall/:appId for
a full uninstall.
This endpoint is rate-limited to 5 requests per minute per IP.
Request
Body Parameters
The access token to revoke. Refresh tokens cannot be revoked
directly — passing one returns
200 (silent no-op) because no
installation row matches a refresh token in the accessToken lookup.
To kill a refresh token, revoke its paired access token (which
blacklists both) or wait 30 days for natural expiry.Response
Always 200.
Always
success.Token revoked successfully. Returned for both genuine revocations and
unknown tokens (RFC 7009 §2.2 idempotency).Example Response
What gets revoked
When the server finds an installation matching the supplied access token, both tokens on that row are blacklisted and cleared in a single update:| State | Before | After |
|---|---|---|
| Access token | lms_token_... | cleared |
| Refresh token | lms_refresh_... | cleared |
| Access-token expiry | <24h from now> | cleared |
| Refresh-token expiry | <30d from now> | cleared |
| Blacklist entry (access token) | – | set, 31 days |
| Blacklist entry (refresh token) | – | set, 31 days |
When to revoke
- User-initiated sign-out of your app’s embedded UI.
- Compromised token suspicion — pair with rotating
client_secretviaPOST /apps/developer/:appId/regenerate-secret. - Switching environments between dev/staging/prod for the same app installation.
POST /apps/store/uninstall/:appId.
Ending a session (alternatives)
| Operation | Endpoint | Effect |
|---|---|---|
| Revoke current token only | POST /apps/oauth/revoke | Both tokens blacklisted; installation kept. |
| Rotate refresh token | POST /apps/oauth/token with grant_type=refresh_token | Old refresh token auto-blacklisted; new pair issued. |
| Uninstall app | POST /apps/store/uninstall/:appId | Installation removed (or status → pending-uninstall); deployed extension files removed; uninstall webhooks dispatched. |
| Re-authenticate | GET /apps/oauth/authorize → POST /apps/oauth/token | Reuses the same installation; new tokens overwrite old ones. |
Error Codes
| HTTP | Error message | When |
|---|---|---|
200 | Token revoked successfully | Always returned — including for unknown tokens (RFC 7009 idempotency). |
429 | (throttler) | More than 5 requests/minute from this IP. |
500 | (generic) | Server-side write failed. The token may or may not be revoked — retry. |
Security Notes
- Token blacklist entries live for 31 days — one day longer than the longest possible refresh-token lifetime — so a revoked token can never come back via a stale cache.
- Only a SHA-256 hash of the token is stored in the blacklist; the raw token is never persisted.
- This endpoint has no auth requirement beyond rate limiting — anyone
holding a valid access token can revoke it. This is intentional: a
leaked token should be invalidatable from any environment without
needing the original
client_secret.