Two OAuth endpoints, two specifications, two different jobs.
Introspection (RFC 7662) asks the authorisation server whether a token is currently valid and what it grants. Use it for opaque tokens your API cannot validate locally.
Revocation (RFC 7009) tells the authorisation server to invalidate a token. Use it at sign-out and during incident response.
Revoke the refresh token
The most consequential detail: revoking an access token alone accomplishes very little. If the attacker also holds the refresh token, they mint a new access token immediately and you have achieved nothing except a brief interruption.
Revoke the refresh token. Most authorisation servers cascade this, invalidating every access token derived from it. Set token_type_hint=refresh_token so the server searches the right store first.
Why revocation always returns 200
RFC 7009 requires a 200 whether or not the token existed. This looks like a bug and is a deliberate design: a 404 for an unknown token would let an attacker probe which tokens exist. Do not treat 200 as confirmation the token was found — confirm with an introspection call returning active: false.
Reading an introspection response
active is the only field guaranteed to be present. Everything else — scope, client_id, exp, sub — is optional and varies by server.
Treat a missing active as a failure. Code that does if (response.active !== false) fails open when the server returns an error object with no active field at all.
Introspection costs a round trip
Every introspected request becomes two network calls, with the authorisation server in the critical path of your API. At any volume that is a latency and availability problem: if the authorisation server is down, your API is down.
Two mitigations:
- Cache the result for a few seconds. The exposure is that a revoked token stays usable for the cache duration; a short TTL bounds it.
- Use JWTs and validate locally where the token format is yours to choose. That removes the round trip entirely, at the cost of not being able to revoke before expiry — which is the same trade-off as everywhere else in this space.
Client authentication
Both endpoints require the client to authenticate. HTTP Basic with client_id:client_secret is the default and keeps the secret out of the request body and therefore out of most logs. Body-parameter authentication is permitted where Basic is impractical, but the secret then appears in anything that logs POST bodies.
Frequently asked questions
Do I need introspection if I use JWTs?
Usually not — that is the point of a JWT. You may still want it for a "is this token revoked" check on high-value operations, where the latency is worth the certainty.
What does token_type_hint do?
It tells the server which store to check first. It is a performance optimisation, not a constraint: the server must still find the token if the hint is wrong.
Can I revoke all of a user's tokens at once?
Not through RFC 7009, which operates on a single token. Most providers expose a separate session or grant management API for that. Rotating the signing key is the blunt instrument that invalidates everything.
How do I confirm revocation actually worked?
Introspect the same token afterwards and check for active: false. Never assume — the 200 from the revocation endpoint tells you nothing about whether the token was found.