diff --git a/main/config/navigation/manage-users.json b/main/config/navigation/manage-users.json
index eea890a3df..5715972262 100644
--- a/main/config/navigation/manage-users.json
+++ b/main/config/navigation/manage-users.json
@@ -227,6 +227,14 @@
"docs/manage-users/sessions/session-metadata/configure-session-metadata",
"docs/manage-users/sessions/session-metadata/add-organization-information"
]
+ },
+ {
+ "group": "Anonymous Sessions",
+ "pages": [
+ "docs/manage-users/sessions/anonymous-sessions",
+ "docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions",
+ "docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases"
+ ]
}
]
},
diff --git a/main/config/navigation/secure.json b/main/config/navigation/secure.json
index d22b06643f..876c305924 100644
--- a/main/config/navigation/secure.json
+++ b/main/config/navigation/secure.json
@@ -271,6 +271,7 @@
"docs/secure/tokens/access-tokens/json-web-encryption"
]
},
+ "docs/secure/tokens/session-tokens",
"docs/secure/tokens/delegation-tokens",
{
"group": "Refresh Tokens",
diff --git a/main/docs/manage-users/sessions/anonymous-sessions.mdx b/main/docs/manage-users/sessions/anonymous-sessions.mdx
new file mode 100644
index 0000000000..931155e790
--- /dev/null
+++ b/main/docs/manage-users/sessions/anonymous-sessions.mdx
@@ -0,0 +1,178 @@
+---
+title: Anonymous Sessions
+description: Learn how to create and manage user sessions without requiring authentication.
+---
+
+import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"
+
+
+
+Anonymous sessions allow you to create and manage [user sessions](/docs/manage-users/sessions) without requiring authentication.
+
+Users can browse, add items to carts or wishlists, complete purchases, and set preferences before creating an account. Users then bring their activity into their authenticated profile when they sign up or log in.
+
+Use anonymous sessions for the following use cases:
+
+- **Track guest users** across page loads and sessions
+- **Store metadata** such as shopping cart references, preferences, consents, and profiling information
+- **Issue access tokens** for API calls without requiring authentication
+- **Transfer anonymous activity** to authenticated accounts when users sign up or log in
+
+
+Auth0 anonymous session Metadata is not a secure data store and should not be used to store sensitive information.
+This includes secrets and high-risk PII like social security numbers or credit card numbers, etc.
+
+Additionally, the data stored in an anonymous session is not verified for truthness or accuracy and should never be taken at face value.
+
+Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for session tagging and access management purposes.
+To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr)."
+
+
+## How it works
+
+### Gather anonymous sessions data
+
+When you decide to start gathering information about a user, even one who has not authenticated yet, your application sends a `POST` request to the `/anonymous/token` endpoint.
+
+Auth0 responds with two tokens:
+
+- A [**session token**](/docs/secure/tokens/session-tokens) that identifies and persists the anonymous session.
+- An [**access token**](/docs/secure/tokens/access-tokens) that the user can present to your [resource servers (APIs)](/docs/get-started/apis).
+
+Subsequent calls that include the session token continue the same session for the same `user_id`, so all activity is traceable to a single origin.
+Using the access token, anonymous users can call any of your existing APIs.
+
+```mermaid actions={false}
+sequenceDiagram
+ participant app as SPA/APP
+ participant idp as Auth0
+ participant rs as Resource Server
+ note over app: User Browses the site and
we decide to start
storing information about them.
+ app ->> idp: POST /anonymous/token
{language: EN, country: US, order_id: PO123}
+ idp ->> app: Session Token, Access Token
sub: anon@1234-5678-90
+ note over app: User buys something anonymously.
+ app ->>+ rs: POST /purchase
Authorization: Bearer
+ rs ->> rs: Purchase order PO123 created
user_id: anon@1234-5678-90
+ rs ->>- app: HTTP 200 OK
+ note over app: User retrieves their anonymous purchases
+ app ->> rs: GET /purchase
Authorization: Bearer
+ rs ->> app: HTTP 200 OK {purchases: ["PO123"]}
+```
+
+```json Anonymous session data of user anon@1234-5678-90
+{
+ "user_id": "anon@1234-5678-90",
+ "session_id": "sess_456",
+ "metadata": {
+ "language": "EN",
+ "country": "US",
+ "purchase": "P0123"
+ }
+}
+```
+### Transfer anonymous sessions data to user's metadata
+
+When a user who has an anonymous session decides to log in or sign up, your application passes the `anonymous_session_token` to the `/authorize` endpoint using a cookie or an HTTP header.
+
+```javascript cookie example
+// No extra code needed — cookie is sent automatically
+await auth0.loginWithRedirect();
+```
+
+```javascript authorize endpoint example
+GET /authorize?
+ client_id: YOUR_CLIENT_ID&
+ redirect_uri: https://YOUR_ClIENT_URL/callback&
+ response_type: code&
+ scope: openid&
+ Auth0-Anonymous-Session: eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0...
+```
+
+```mermaid actions={false}
+sequenceDiagram
+ participant app as SPA/APP
+ participant idp as Auth0
+ participant rs as Resource Server
+ note over app: User has been browsing the site
+ anonymously and now logs in.
+ app ->>+ idp: POST /authorize?client_id=xxx...
+ Cookie: auth0_anon=eJY...
+ idp ->> idp: Run post-login actions, includes anonymous_session data
+ (language, country, order_id)
+ idp ->> idp: api.idToken.addCustomClaim('original_uid', event.anonymous_session.user_id)
+ idp ->>- app: Access Token, ID Token (with original_uid claim), auth0 cookie
+ app ->>+ rs: Get /purchase?user:anon@1234-5678-90
+ rs ->> rs: Purchase order PO123 created by
+ user_id: anon@1234-5678-90
+ rs ->>- app: HTTP 200 OK {purchase_orders: ["PO123"]}
+```
+
+Auth0 makes the anonymous session data available in your [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) and [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Actions triggers using the `event.anonymous_session` object.
+
+```json anonymous session object
+{
+ "anonymous_session": {
+ "user_id": "anon@1234-5678-90",
+ "session_id": "sess_123",
+ "created_at": "2026-05-14T10:30:00Z",
+ "metadata": {
+ "language": "en",
+ "country": "US",
+ "order_id": "PO123"
+}
+}
+}
+```
+
+To learn more about anonymous sessions with Actions, read [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases).
+
+### End the anonymous session after transfer
+
+Anonymous sessions are not automatically invalidated when a user authenticates. To end the session use the `/anonymous/logout` endpoint:
+
+```javascript wrap lines
+// In your application, after successful login
+if (wasAnonymousSession) {
+ await fetch('https://YOUR_DOMAIN/anonymous/logout', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ credentials: 'include', // Send cookies
+ body: JSON.stringify({ client_id: 'YOUR_CLIENT_ID' }),
+ });
+}
+```
+
+## Best practices
+
+Here are some best practices for anonymous sessions:
+
+- Configure appropriate [anonymous session lifetimes](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#configure-anonymous-sessions-in-your-auth0-tenant) to avoid losing a user's anonymous session data; Auth0 recommends a lifetime of 30 days or longer.
+
+- Select anonymous session's [JSON Web Encryption (JWE)](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#configure-anonymous-sessions-in-your-auth0-tenant) encryption to ensure that potential attackers cannot see the contents of the session.
+
+- Restrict what anonymous `anon@` users can do in your API.
+
+- Validate tokens and sanitize metadata, never trust metadata or tokens from clients without server-side validation.
+
+- Cache [access tokens](/docs/secure/tokens/access-tokens) since they can be reused until they expire.
+
+- Batch and minimize [metadata updates](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#update-the-session-with-metadata). Avoid frequent metadata updates.
+
+
+## Limitations
+
+- [Password reset](/docs/customize/actions/explore-triggers/password-reset-triggers#password-reset-triggers) flows are not supported by anonymous sessions.
+- [Device Code](/docs/get-started/authentication-and-authorization-flow/device-authorization-flow) is not supported because the authentication request and the actual login happen on different devices.
+- [Client-Initiated Backchannel Authentication (CIBA)](/docs/get-started/applications/configure-client-initiated-backchannel-authentication) is not supported because the authentication request and confirmation happen on different devices.
+- [Custom token exchange](/docs/authenticate/custom-token-exchange/cte-example-use-cases) is not supported due to the nature of the transactions (for example, impersonation), which creates a likelihood of attributing anonymous data to the wrong user.
+- [Refresh token exchange](/docs/secure/call-apis-on-users-behalf/token-vault/configure-token-vault#configure-token-exchange) is not supported by anonymous sessions because the user is already logged in if they had a refresh token.
+
+## Learn more
+
+- [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions) Learn how to configure anonymous sessions.
+- [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases) Learn about anonymous sessions use cases.
\ No newline at end of file
diff --git a/main/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases.mdx b/main/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases.mdx
new file mode 100644
index 0000000000..d5b338c8c5
--- /dev/null
+++ b/main/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases.mdx
@@ -0,0 +1,161 @@
+---
+title: Anonymous Sessions Use Cases
+description: Learn about anonymous sessions use cases with Actions.
+sidebarTitle: Use Cases
+---
+
+import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"
+
+
+
+When a user authenticates in your application, anonymous sessions and [Actions](/docs/customize/actions/actions-overview) allow you to transfer anonymous session data, such as shopping cart contents, preferences, and browsing history, to their authenticated user profile.
+
+You can reference the `event.anonymous_session` object in Actions:
+
+```typescript theme={null}
+{
+ user_id: string; // anonymous user id
+ session_id: string; // anonymous session token id
+ created_at: number; // anonymous session creation timestamp
+ expires_at: number; // anonymous session expiration timestamp
+ metadata: { // anonymous session metadata object
+ [key: string]: string
+ };
+}
+```
+
+## Anonymous sessions and Actions use cases
+
+### Save anonymous session metadata to a new user
+
+You can use a [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) Action trigger to copy anonymous metadata into the new user profile when they sign up:
+
+```javascript wrap lines
+exports.onExecutePreUserRegistration = async (event, api) => {
+ if (event.anonymous_session) {
+ // Store reference to the anonymous session
+ api.user.setAppMetadata(
+ 'linked_anonymous_id',
+ event.anonymous_session.user_id
+ );
+
+ // Migrate cart data
+ if (event.anonymous_session.metadata.cart) {
+ api.user.setAppMetadata(
+ 'migrated_cart',
+ event.anonymous_session.metadata.cart
+ );
+ }
+
+ // Copy preferences to user metadata
+ if (event.anonymous_session.metadata.preferences) {
+ api.user.setUserMetadata(
+ 'preferences',
+ event.anonymous_session.metadata.preferences
+ );
+ }
+ }
+};
+```
+
+### Save anonymous session metadata to an existing user
+
+You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to save anonymous metadata to existing users when they log in:
+
+```javascript wrap lines
+exports.onExecutePostLogin = async (event, api) => {
+ if (event.anonymous_session) {
+ // Store last anonymous session reference
+ api.user.setAppMetadata(
+ 'last_anonymous_session',
+ event.anonymous_session.user_id
+ );
+
+ // Add anonymous cart to access token for your API to process
+ api.accessToken.setCustomClaim(
+ 'anonymous_cart',
+ event.anonymous_session.metadata.cart
+ );
+
+ // Track all linked sessions (optional)
+ const linkedSessions =
+ event.user.app_metadata?.linked_sessions || [];
+ if (!linkedSessions.includes(event.anonymous_session.user_id)) {
+ api.user.setAppMetadata('linked_sessions', [
+ ...linkedSessions,
+ event.anonymous_session.user_id,
+ ]);
+ }
+ }
+};
+```
+
+### Merge user metadata with anonymous metadata
+
+You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to merge anonymous metadata to an existing user metadata, such as a cart information, when they log in:
+
+```javascript wrap lines
+exports.onExecutePostLogin = async (event, api) => {
+ if (!event.anonymous_session?.metadata?.cart) {
+ return; // No anonymous cart to merge
+ }
+
+ const anonymousCart = event.anonymous_session.metadata.cart;
+ const existingCart = event.user.app_metadata?.cart || { items: [] };
+
+ // Merge cart items, combining quantities for matching SKUs
+ const mergedItems = [...existingCart.items];
+ for (const anonItem of anonymousCart.items) {
+ const existingIndex = mergedItems.findIndex(
+ (item) => item.sku === anonItem.sku
+ );
+ if (existingIndex >= 0) {
+ mergedItems[existingIndex].qty += anonItem.qty;
+ } else {
+ mergedItems.push(anonItem);
+ }
+ }
+
+ api.user.setAppMetadata('cart', { items: mergedItems });
+ api.accessToken.setCustomClaim('cart', { items: mergedItems });
+};
+```
+
+### Handle multiple anonymous sessions
+
+You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to manage anonymous session metadata from different devices, when the user logs in:
+
+```javascript wrap lines
+exports.onExecutePostLogin = async (event, api) => {
+ if (!event.anonymous_session) return;
+
+ const linkedSessions =
+ event.user.app_metadata?.linked_sessions || [];
+
+ // Option 1: Keep all linked sessions
+ api.user.setAppMetadata('linked_sessions', [
+ ...linkedSessions,
+ {
+ user_id: event.anonymous_session.user_id,
+ linked_at: new Date().toISOString(),
+ device: event.request.user_agent,
+ },
+ ]);
+
+ // Option 2: Keep only the most recent
+ api.user.setAppMetadata('last_anonymous_session', {
+ user_id: event.anonymous_session.user_id,
+ metadata: event.anonymous_session.metadata,
+ });
+};
+```
+
+## Learn more
+
+- [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions) Learn how to configure anonymous sessions.
+- [Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions) Learn about anonymous sessions.
\ No newline at end of file
diff --git a/main/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions.mdx b/main/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions.mdx
new file mode 100644
index 0000000000..32b0067cf8
--- /dev/null
+++ b/main/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions.mdx
@@ -0,0 +1,91 @@
+---
+title: Configure Anonymous Sessions
+description: Learn how to configure anonymous sessions using the Auth0 Management API.
+sidebarTitle: Configure Anonymous Sessions
+---
+
+import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"
+
+
+
+To configure anonymous sessions, you can use the Auth0 [Management API](/docs/api/management/v2).
+
+## Prerequisites
+
+To use anonymous sessions:
+
+- You must [have an Auth0 account](https://auth0.com/).
+- [Register your Auth0 application](/docs/get-started/auth0-overview/create-applications). If you do not have an Auth0 application, you can get started with the Auth0 React or Next.js [Quickstarts](https://auth0.com/docs/quickstart/spa/react).
+- [Register an API (resource server)](/docs/get-started/auth0-overview/set-up-apis).
+
+## Auth0 Management API
+
+### Configure anonymous sessions in your Auth0 tenant
+
+To set the anonymous sessions lifetime and token format, make a `PATCH` request to the [`/api/v2/tenants/settings`](/docs/api/management/v2/tenants/patch-settings) endpoint:
+
+```json
+{
+ "sessions": {
+ "anonymous": {
+ "lifetime_in_minutes": 1440,
+ "token_format": "jwe"
+ }
+ }
+}
+```
+
+### Enable anonymous sessions in your application
+
+To enable anonymous sessions in your Auth0 application, make a `PATCH` request to the [`/api/v2/clients/{id}`](/docs/api/management/v2/clients/patch-clients-by-id) endpoint:
+
+```json
+{
+ "anonymous_sessions": {
+ "active": true
+ }
+}
+```
+
+### Enable anonymous access in your API
+
+To enable anonymous sessions in your API, make a `PATCH` request to the [`/api/v2/resource-servers/{id}`](/docs/api/management/v2/resource-servers/patch-resource-servers-by-id) endpoint:
+
+```json
+{
+"allow_anonymous_access": true,
+"token_lifetime_for_anonymous_access_tokens": 7200
+}
+```
+
+## Create an anonymous session
+
+Once anonymous sessions are configured in your tenant, application, and API, you can create an anonymous session by making a `POST` request to the `/anonymous/token` endpoint:
+
+```json
+{
+ "client_id": "YOUR_CLIENT_ID",
+ "audience": "YOUR_AUDIENCE",
+ "scope": "anon"
+}
+```
+
+The response includes a `session_token` and an `access_token`:
+
+```json
+{
+ "session_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0...",
+ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "token_type": "Bearer",
+ "expires_in": 86400
+}
+```
+
+## Next steps
+
+- [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases) Learn about anonymous sessions use cases.
\ No newline at end of file
diff --git a/main/docs/secure/tokens/session-tokens.mdx b/main/docs/secure/tokens/session-tokens.mdx
new file mode 100644
index 0000000000..4d799dc183
--- /dev/null
+++ b/main/docs/secure/tokens/session-tokens.mdx
@@ -0,0 +1,36 @@
+---
+title: "Session Tokens"
+description: Learn how session tokens enable anonymous sessions in Auth0, allowing applications to maintain session state without an authenticated user.
+---
+
+import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"
+
+
+
+In [anonymous user](/docs/manage-users/sessions/anonymous-sessions) flows, in which there is no authenticated user, Auth0 provides a mechanism to establish a session anonymously.
+
+Auth0 issues a session token and an [access token](/docs/secure/tokens/access-tokens) in response to an [`/anonymous/token`](/docs/manage-users/sessions/anonymous-sessions#gather-anonymous-sessions-data) request. To learn more, read [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions).
+
+
+- The session token contains the anonymous user identity and session information attributes.
+- The access token is usually a [JSON Web Token (JWT)](/docs/secure/tokens/json-web-tokens) whose claims can be read and processed by a resource server (API), whereas the session token is opaque and only meant to be read by Auth0.
+
+
+Typically, a user needs a new access token when gaining access to a resource for the first time, or after the previous access token granted to them expires.
+
+A session token is a credential artifact that your application can use to get a new access token when necessary. You can continue to request new access tokens until the [`anonymous_session_lifetime`](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#configure-anonymous-sessions-in-your-auth0-tenant) expires.
+
+## Session token benefits
+
+- A session token is not bound to the device that created the session. It can be ported and used on a different device.
+
+- A session token can be included in authorization requests, and the information inside the session token is available in [Actions](/docs/customize/actions/actions-overview), to complement the login transaction.
+
+## Learn more
+
+- [Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions) Learn about anonymous sessions.