# verifyToken()

> This is a lower-level method intended for more advanced use-cases. It's recommended to use [`authenticateRequest()`](https://clerk.com/docs/reference/backend/authenticate-request.md), which fully authenticates a token passed from the `request` object.

```ts
function verifyToken(
  token: string,
  options: {
    apiUrl?: string;
    apiVersion?: string;
    audience?: string | string[];
    authorizedParties?: string[];
    clockSkewInMs?: number;
    headerType?: string | string[];
    jwksCacheTtlInMs?: number;
    jwtKey?: string;
    secretKey?: string;
    skipJwksCache?: boolean;
  },
): Promise<JwtReturnType<JwtPayload, TokenVerificationError>>;
```

Verifies a Clerk-generated token signature. Networkless if the `jwtKey` is provided. Otherwise, performs a network call to retrieve the JWKS from the [Backend API](https://clerk.com/docs/reference/backend-api/tag/jwks/GET/jwks){{ target: '_blank' }}.

## Parameters

| Parameter                    | Type                                                                                                                                                                                                                                                                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`                      | `string`                                                                                                                                                                                                                                                            | The token to verify.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `options`                    | `{ apiUrl?: string; apiVersion?: string; audience?: string | string[]; authorizedParties?: string[]; clockSkewInMs?: number; headerType?: string | string[]; jwksCacheTtlInMs?: number; jwtKey?: string; secretKey?: string; skipJwksCache?: boolean; }` | Options for verifying the token. It is recommended to set these options as [environment variables](https://clerk.com/docs/guides/development/clerk-environment-variables.md#api-and-sdk-configuration) where possible, and then pass them to the function. For example, you can set the `secretKey` option using the `CLERK_SECRET_KEY` environment variable, and then pass it to the function like this: `verifyToken(token, { secretKey: process.env.CLERK_SECRET_KEY })`.                                                |
| `options.apiUrl?`            | `string`                                                                                                                                                                                                                                                            | The [Clerk Backend API](https://clerk.com/docs/reference/backend-api){{ target: '_blank' }} endpoint. Defaults to `'https://api.clerk.com'`.                                                                                                                                                                                                                                                                                                                                                                                |
| `options.apiVersion?`        | `string`                                                                                                                                                                                                                                                            | The version passed to the Clerk API. Defaults to `'v1'`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `options.audience?`          | `string | string[]`                                                                                                                                                                                                                                      | A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). If passed, it is checked against the `aud` claim in the token.                                                                                                                                                                                                                                                                                                                                                                |
| `options.authorizedParties?` | `string[]`                                                                                                                                                                                                                                               | An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack. Example: `['http://localhost:3000', 'https://example.com']`.                                                                                                                                                                                                                                                                                                                                               |
| `options.clockSkewInMs?`     | `number`                                                                                                                                                                                                                                                            | Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to `5000`.                                                                                                                                                                                                                                                                                                                    |
| `options.headerType?`        | `string | string[]`                                                                                                                                                                                                                                      | A string or list of allowed [header types](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.9). Defaults to `'JWT'`.                                                                                                                                                                                                                                                                                                                                                                                               |
| `options.jwksCacheTtlInMs?`  | `number`                                                                                                                                                                                                                                                            | **Deprecated.** This cache TTL will be removed in the next major version. Specifying a cache TTL is a no-op.                                                                                                                                                                                                                                                                                                                                                                                                                |
| `options.jwtKey?`            | `string`                                                                                                                                                                                                                                                            | Used to verify the session token in a networkless manner. Supply the PEM public key from the **[**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page -> Show JWT public key -> PEM Public Key** section in the Clerk Dashboard. **It's recommended to use [the environment variable](https://clerk.com/docs/guides/development/clerk-environment-variables.md) instead.** For more information, refer to [Manual JWT verification](https://clerk.com/docs/guides/sessions/manual-jwt-verification.md). |
| `options.secretKey?`         | `string`                                                                                                                                                                                                                                                            | The Clerk Secret Key from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard.                                                                                                                                                                                                                                                                                                                                                                                            |
| `options.skipJwksCache?`     | `boolean`                                                                                                                                                                                                                                                           | A flag to ignore the JWKS cache and always fetch JWKS before each JWT verification.                                                                                                                                                                                                                                                                                                                                                                                                                                         |

## Example

The following example demonstrates how to use the [JavaScript Backend SDK](https://clerk.com/docs/reference/backend/overview.md) to verify the token signature.

In the following example:

1. The **JWKS Public Key** from the Clerk Dashboard is set in the environment variable `CLERK_JWT_KEY`.
2. The session token is retrieved from the `__session` cookie or the Authorization header.
3. The token is verified in a networkless manner by passing the `jwtKey` prop.
4. The `authorizedParties` prop is passed to verify that the session token is generated from the expected frontend application.
5. If the token is valid, the response contains the verified token.

```ts
import { verifyToken } from "@clerk/backend";
import { cookies } from "next/headers";

export async function GET(request: Request) {
  const cookieStore = cookies();
  const sessToken = cookieStore.get("__session")?.value;
  const bearerToken = request.headers
    .get("Authorization")
    ?.replace("Bearer ", "");
  const token = sessToken || bearerToken;

  if (!token) {
    return Response.json(
      { error: "Token not found. User must sign in." },
      { status: 401 },
    );
  }

  try {
    const verifiedToken = await verifyToken(token, {
      jwtKey: process.env.CLERK_JWT_KEY,
      authorizedParties: ["http://localhost:3001", "api.example.com"], // Replace with your authorized parties
    });

    return Response.json({ verifiedToken });
  } catch (error) {
    return Response.json({ error: "Token not verified." }, { status: 401 });
  }
}
```

If the token is valid, the response will contain a JSON object that looks something like this:

```json
{
  "verifiedToken": {
    "azp": "http://localhost:3000",
    "exp": 1687906422,
    "iat": 1687906362,
    "iss": "https://magical-marmoset-51.clerk.accounts.dev",
    "nbf": 1687906352,
    "sid": "sess_2Ro7e2IxrffdqBboq8KfB6eGbIy",
    "sub": "user_2RfWKJREkjKbHZy0Wqa5qrHeAnb"
  }
}
```

---

## Sitemap

[Overview of all docs pages](https://clerk.com/docs/llms.txt)
