Anonymous Users

Anonymous users allow you to treat visitors as first-class identities before they provide a verified email, phone number, or username.

You can reduce registration friction while still using Descope as your customer identity layer: issue session tokens, attach custom data, and later convert the same anonymous user to a standard user while retaining information you collected during the anonymous phase.

How Anonymous Users Work

Descope represents an anonymous user by issuing a dedicated anonymous session JWT (not a standard user record with login IDs). That token:

  • Is signed by Descope and behaves like other session tokens for your app (e.g. API authorization).
  • Has a lifetime tied to the JWT (and refresh behavior you configure)—when the session expires, that anonymous identity ends unless you refresh or convert the user.
  • Carries a danu claim (true) in the payload so your backend can tell this is an anonymous session.
  • Can include custom claims (for example user preferences, unverified email addresses, or app-specific flags) for use in your product.

When you are ready, you can convert the anonymous user to a regular user, without losing any data you've already gathered on the user.

Creating Anonymous Users

With Flows

The Create Anonymous user - Add Information To JWT flow template provides a starting point. Upon completion, Descope issues an anonymous identity token.

Create Anonymous User Flow

The following example illustrates a typical JWT payload and header after the flow runs. The danu claim marks the session as anonymous; displayName (or any claims you configure) represents optional custom data for your application:

// Payload:
{
  "danu": true,
  "displayName": "xxxxx",
  "drn": "DS",
  "exp": 1731843388,
  "iat": 1731842788,
  "iss": "xxxxxxxxx",
  "rexp": "2024-12-15T11:26:28Z",
  "sub": "xxxxxxxxx"
}
 
// Header:
{
  "alg": "RS256",
  "kid": "xxxxxxxxxxxxxxxx",
  "typ": "JWT"
}

With SDKs

You can use the Descope Management SDK to mint an anonymous session JWT programmatically. A management key is required. For broader SDK setup, see User management SDKs.

Install the SDK

Terminal
npm i --save @descope/node-sdk

Import and initialize Management SDK

import DescopeClient from '@descope/node-sdk';
 
const managementKey = "xxxx"
 
try{
    //  baseUrl="<URL>" // When initializing the Descope clientyou can also configure the baseUrl ex: https://auth.company.com  - this is useful when you utilize a custom domain within your Descope project.
    const descopeClient = DescopeClient({ projectId: '__ProjectID__', managementKey: managementKey });
} catch (error) {
    // handle the error
    console.log("failed to initialize: " + error)
}

Create an anonymous user

This operation creates an anonymous user within the project with the details provided.

 // Args:
//  customClaims (Record<string, any>, optional): A dictionary of custom claims to include in the JWT.
//     These claims can be used to store additional user information.
//  selectedTenant (string, optional): The ID of the tenant to associate with the JWT.
//     This is useful for multi-tenant applications.
 
const customClaims = {
    role: "guest",
    permissions: ["read"]
};
 
const selectedTenant = "tenant_123";
 
const resp = await descopeClient.management.jwt.anonymous(customClaims, selectedTenant);
if (!resp.ok) {
    console.log("Failed to generate JWT for anonymous user.");
    console.log("Status Code: " + resp.code);
    console.log("Error Code: " + resp.error.errorCode);
    console.log("Error Description: " + resp.error.errorDescription);
    console.log("Error Message: " + resp.error.errorMessage);
} else {
    console.log("Successfully generated JWT for anonymous user.");
    console.log(resp.data);
}

Converting Anonymous Users to Regular Users

With Flows

To move from an anonymous session to a regular user, use a flow such as Anonymous User Conversion. This flow authenticates the user and links a verified login ID while preserving context from the anonymous phase.

Update anonymous users magic link flow

  • The template demonstrates one authentication pattern; you can adapt the same approach to other factors your product supports.
  • Verify ownership of the login ID (for example via magic link or OTP) before completing conversion. Doing so prevents users from attaching an email or phone number that already belongs to another account.

With SDKs

If you handle conversion in your backend (instead of using a flow), follow the same rules as above: verify a real login ID, then create a full user and copy over data you stored in the anonymous JWT.

Typical Steps:

  1. Validate the anonymous session JWT.
  2. Extract the claims you intend to keep for the user.
  3. Create the new user using any of the authentication methods in our Client SDKs. Populate custom attributes and other fields from the anonymous user claims.
Was this helpful?

On this page