# Use the OAuth2 Introspection Endpoint

When you use **opaque access tokens** in OAuth2, your API can’t validate them locally. Unlike JWTs, opaque tokens don’t carry their own claims or signature—they’re just random strings.

That means your API needs to **call the introspection endpoint** of the authorization server to verify the token and get information about the user or scopes.

The introspection endpoint returns a JSON object with metadata about the token:

- `active`: whether the token is valid and active
- `scope`: a space-separated list of scopes
- `username`: the user ID or login name
- `exp`: the expiration time (Unix timestamp)
- `client_id`: the client that requested the token

Here’s how to call the introspection endpoint and handle the response:

```ts
let res = await fetch(new URL("/introspect", issuer), {
  method: "POST",
  headers: {
    Authorization: `Basic ${btoa(clientId + ":" + clientSecret)}`,
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({ token }),
});

let data = await res.json();
if (!data.active) throw new Error("Invalid token");

let scopes = data.scope?.split(" ");
let userId = data.username;
```

If the token is active, you can use its metadata to authorize the request—check the scopes, identify the user, etc.

If not, reject the request right away.

---

Want to master secure OAuth2 flows in React Router apps?

📘 My book *React Router OAuth2 Handbook* is now available!

It covers everything from the basics to advanced topics like PKCE, refresh tokens, and E2E auth testing.

→ [books.sergiodxa.com/release](https://go.sergiodxa.com/x6EE88z)
