# Diagnose: API 401 on a fresh token

## Symptom

`Authorization: Bearer` token rejected by your API with 401, immediately after login.

## Likely causes

1. `aud` is not your API identifier (opaque token, or minted for another API).
2. `iss` mismatch: custom domain vs canonical domain.
3. Expired token (clock skew) or wrong signing key (JWKS cached stale).

## Confirm

Decode the token (jwt.io or a debugger; never paste production tokens into random sites, use a local decoder):

- `aud`: must equal your API identifier exactly.
- `iss`: must equal `https://YOUR-TENANT-DOMAIN/` (or your custom-domain issuer if configured).
- `exp`: must be in the future on the API server's clock.
- `azp`: the client id that requested it.

Then call `GET https://YOUR-TENANT-DOMAIN/userinfo` with the token. If /userinfo 401s too, the token itself is bad (expired, revoked, malformed). If /userinfo 200s but your API 401s, your API's validation config is wrong, not the token.

Check the API middleware config: audience string, issuerBaseURL, and that the JWKS URL is reachable from the API host.

## Fix

- Wrong/missing aud: set the audience at login to the API identifier.
- iss mismatch: align the middleware issuer with the domain the tokens are actually minted from.
- Stale JWKS cache: clear it; key rotation happens.

## Verify

Replay the request with a fresh token and get 200. Automate the claim checks in a smoke test so regressions surface immediately.