What it means
We couldn’t authenticate the request. Either there’s noAuthorization
header, the bearer token we saw doesn’t match anything we issued, it’s
expired, or it’s been revoked.
Common causes & fixes
| Cause | Fix |
|---|---|
Missing Authorization header | Add Authorization: Bearer <access_token>. |
| Header format wrong | Must be exactly Bearer <token>. Not bearer, no extra whitespace, no quoting. |
| Access token expired (1-hour TTL) | Refresh via grant_type=refresh_token. See Authentication / refreshing. |
| Refresh token used after rotation | The previous refresh token is revoked the moment you refresh. Always store the new one immediately. |
| User disconnected | The user clicked Disconnect on their DSS dashboard. Reconsent flow is needed — see user.consent.revoked. |
| Partner suspended | Your client_id has been suspended by DSS support. Contact us. |
Distinguishing “expired” vs “revoked”
We don’t expose this in thedetail for security reasons (you shouldn’t be
able to probe which case you’re in to enumerate users). Treat them the same:
- Try a refresh. If it succeeds, you had a stale access token — store the new pair and retry the original request.
- If the refresh itself returns
invalid_grant, the user has either disconnected or your refresh token has expired (90-day TTL). In either case, you need to send the user through the authorize flow again.

