---
title: Verify tokens
description: Verify OAuth2 access tokens locally or with database-backed validation.
sidebar:
  order: 5
---

## Overview

You can verify an **OAuth2 Access Token** locally or enable database-backed validation to detect revocation.

One thing to note is that, besides the standard **OAuth2** token claims, the **Unified Login** implementation includes an additional one called `stt`.
This stands for `SuperTokens Token Type`.
It ensures that the validation occurs for the correct token type:
- `0` represents a **SuperTokens Session Access Token**
- `1` represents an **OAuth2 Access Token**
- `2` represents an **OAuth2 ID Token**.

:::warning

The following guide covers only **OAuth2 Tokens** verification.
For information on how to verify **SuperTokens Session Tokens** please refer to the [following section](/additional-verification/session-verification/protect-api-routes).

:::

---

## Local access token verification

Use the released SuperTokens backend SDK validator for most protected operations. It validates the JWT signature,
expiration, and `stt=1` token type. Configure the intended audience and required scopes. Restricting the client ID is an
optional additional check; it does not replace audience validation. Also compare the token issuer with your Authorization
Server's issuer.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import OAuth2Provider from "supertokens-node/recipe/oauth2provider";

async function validateToken(token: string): Promise<boolean> {
  try {
    const result = await OAuth2Provider.validateOAuth2AccessToken(token, {
      audience: "<AUDIENCE>",
      clientId: "<CLIENT_ID>",
      scopes: ["<YOUR_REQUIRED_SCOPE>"],
    });

    return result.payload.iss === "<YOUR_API_DOMAIN>/auth";
  } catch {
    return false;
  }
}
```
</Tab>
<Tab title="Python" value="python">
```python
from supertokens_python.recipe.oauth2provider.interfaces import OAuth2TokenValidationRequirements
from supertokens_python.recipe.oauth2provider.syncio import validate_oauth2_access_token


def validate_token(token: str) -> bool:
    try:
        result = validate_oauth2_access_token(
            token=token,
            requirements=OAuth2TokenValidationRequirements(
                audience="<AUDIENCE>",
                client_id="<CLIENT_ID>",
                scopes=["<YOUR_REQUIRED_SCOPE>"],
            ),
        )
        return result.payload.get("iss") == "<YOUR_API_DOMAIN>/auth"
    except Exception:
        return False
```
</Tab>
</CodeGroup>

### Email verification

If you are using email and password based authentication, and you want to validate if the user has verified their email, you must check if the `email_verified` claim is true.

---

## Using the token introspection API

Revocation is not visible to local JWT verification, so a revoked token otherwise remains valid until it expires.
For high-security operations, use the backend SDK validator with database checking enabled. This calls Core introspection in
addition to performing local cryptographic and claim validation.

Here is an example of how you can use this validation method:


<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import OAuth2Provider from "supertokens-node/recipe/oauth2provider";

async function validateToken(token: string): Promise<boolean> {
  try {
    const result = await OAuth2Provider.validateOAuth2AccessToken(
      token,
      {
        audience: "<AUDIENCE>",
        clientId: "<CLIENT_ID>",
        scopes: ["<REQUIRED_SCOPE>"],
      },
      true,
    );

    return result.payload.iss === "<YOUR_API_DOMAIN>/auth";
  } catch {
    return false;
  }
}
```
</Tab>
<Tab title="Python" value="python">
```python
from supertokens_python.recipe.oauth2provider.interfaces import OAuth2TokenValidationRequirements
from supertokens_python.recipe.oauth2provider.syncio import validate_oauth2_access_token


def validate_token(token: str) -> bool:
    try:
        result = validate_oauth2_access_token(
            token=token,
            requirements=OAuth2TokenValidationRequirements(
                audience="<AUDIENCE>",
                client_id="<CLIENT_ID>",
                scopes=["<REQUIRED_SCOPE>"],
            ),
            check_database=True,
        )
        return result.payload.get("iss") == "<YOUR_API_DOMAIN>/auth"
    except Exception:
        return False
```
</Tab>
</CodeGroup>
