Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
971884b
feat: add Anonymous Sessions documentation
BcnCarlos Jun 25, 2026
b8fd7a0
fix: address P1 style guide findings in Anonymous Sessions docs
BcnCarlos Jun 25, 2026
99f00bd
fix: address P2 style guide findings in Anonymous Sessions docs
BcnCarlos Jun 25, 2026
72cf0a9
Update
BcnCarlos Jun 25, 2026
2791ed3
feat: add anonymous session workflow diagram
BcnCarlos Jun 25, 2026
9d17ea1
update
BcnCarlos Jun 25, 2026
49a4255
Update
BcnCarlos Jun 25, 2026
2650950
update mermaid
BcnCarlos Jun 25, 2026
0092672
update mermaid
BcnCarlos Jun 25, 2026
5cb01dc
update mermaid
BcnCarlos Jun 25, 2026
b566c45
update
BcnCarlos Jun 25, 2026
e3dacd8
update mermaid
BcnCarlos Jun 25, 2026
7fe0fd8
update
BcnCarlos Jun 26, 2026
f190323
Delete main/docs/images/cdy7uua7fh8z/anonymous-sessions/anonymous-ses…
BcnCarlos Jun 26, 2026
12975c3
update mermaid
BcnCarlos Jun 26, 2026
7dd7d8c
Update navigation, remove claims, rename quickstart, added session to…
BcnCarlos Jul 7, 2026
936dabd
Update release, mermaid code,
BcnCarlos Jul 7, 2026
accaa45
Update code samples
BcnCarlos Jul 7, 2026
edef9a6
updated uses cases
BcnCarlos Jul 7, 2026
00bfe6c
update mermaid
BcnCarlos Jul 7, 2026
56877a5
remove old article, edited use cases.
BcnCarlos Jul 8, 2026
3a1a578
Removed dashboard steps from configure anonymous sessions article
BcnCarlos Jul 8, 2026
d1b8703
Update configure anonymous sessions code samples
BcnCarlos Jul 8, 2026
071a56a
removed best practices article , clean navigation, edited configurati…
BcnCarlos Jul 8, 2026
65e2919
Updated user cases and configuration article
BcnCarlos Jul 8, 2026
e83956e
Update session tokens and anonymous sessions article
BcnCarlos Jul 8, 2026
0b30d59
grammar check
BcnCarlos Jul 9, 2026
dd30ff5
update anonymous sessions article
BcnCarlos Jul 9, 2026
9b8172d
Added suggestion from PM
BcnCarlos Jul 9, 2026
885082a
updated warning
BcnCarlos Jul 9, 2026
a1df022
Update learn more links
BcnCarlos Jul 9, 2026
a4b4a2d
Updated sample codes
BcnCarlos Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions main/config/navigation/manage-users.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
]
},
Expand Down
1 change: 1 addition & 0 deletions main/config/navigation/secure.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
178 changes: 178 additions & 0 deletions main/docs/manage-users/sessions/anonymous-sessions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
title: Anonymous Sessions
description: Create and manage user sessions without requiring authentication.
sidebarTitle: Overview
---

import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"

<ReleaseStageNotice
feature="Anonymous Sessions"
stage="beta"
terms="true"
contact="Auth0 Support"
/>

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 and then carry their activity into their authenticated profile when they sign up or log in.

Use cases for Anonymous Sessions include:

- **Track guest users** across page loads and sessions
- **Store metadata** such as shopping cart references, preferences, consents, and profiling information
- **Issue OAuth 2.0 access tokens** for API calls without requiring authentication
- **Transfer anonymous activity** to authenticated accounts when users sign up or log in


Comment thread
BcnCarlos marked this conversation as resolved.
## 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.

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.
Because the access token is OAuth 2.0-compliant, 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 <br> we decide to start <br> storing information about them.
app ->> idp: POST /anonymous/token<br>{language: EN, country: US, order_id: PO123}
idp ->> app: Session Token, Access Token<br>sub: anon@1234-5678-90
note over app: User buys something anonymously.
app ->>+ rs: POST /purchase<br> Authorization: Bearer <Access Token>
rs ->> rs: Purchase order PO123 created<br>user_id: anon@1234-5678-90
rs ->>- app: HTTP 200 OK
note over app: User retrieves their anonymous purchases
app ->> rs: GET /purchase<br> Authorization: Bearer <Access Token>
rs ->> app: HTTP 200 OK {purchases: ["PO123"]}
```

```json Anonymous session data of user 57f0fcba-e6f0-4e74-ae65-f4c8953a72fb
{
user_id: "57f0fcba-e6f0-4e74-ae65-f4c8953a72fb",
Comment thread
BcnCarlos marked this conversation as resolved.
Outdated
session_id: "sess_456",
metadata: {
language: 'EN',
country: 'US',
purchase: 'PO123'
Comment thread
BcnCarlos marked this conversation as resolved.
Outdated
}
}
```

### 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 a query parameter.
Comment thread
BcnCarlos marked this conversation as resolved.
Outdated

```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 <br>anonymously and now logs in.
app ->> idp: POST /authorize?client_id=xxx...&anonymous_session_token=eJY...
idp ->> idp: Run post-login actions, includes anonymous_session data <br> (language, country, purchase)
idp ->> idp: api.idToken.addCustomClaim('origin', event.anonymous_session.user_id)
idp ->> app: Access Token, ID Token (with original claim), auth0 cookie
app ->>+ rs: Get /purchase{user:anon|123}
rs ->> rs: Purchase order PO123 created<br>user_id: anon@1234-5678-90
rs ->>- app: PUR_987
Comment thread
BcnCarlos marked this conversation as resolved.
Outdated
```


```javascript cookie example
// No extra code needed — cookie is sent automatically
await auth0.loginWithRedirect();
```

```javascript authorize endpoint example
https://YOUR_DOMAIN/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=https://YOUR_APPLICATION_URL/callback&
response_type=code&
scope=openid profile&
anonymous_session_token=SESSION_TOKEN
```

Auth0 makes the anonymous session data available in your `Pre-Registration` and `Post-Login` Actions using the `event.anonymous_session` object.

```json anonymous session object
{
"anonymous_session": {
"user_id": "anon|abc123",
"session_id": "sess_123",
"created_at": "2026-05-14T10:30:00Z",
"metadata": {
"cart": {
"items": [{ "sku": "ITEM-001", "qty": 2 }]
},
"preferences": {
"theme": "dark"
}
}
}
}
Comment thread
BcnCarlos marked this conversation as resolved.
```

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 explicitly:

```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.

- Validate tokens server-side.

- Restrict what anonymous `anon|` users can do in your API.
Comment thread
BcnCarlos marked this conversation as resolved.
Outdated

- Sanitize metadata, never trust metadata from clients without validation.

- Cache [access tokens](/docs/secure/tokens/access-tokens) since they can be reused until they expire.

- Batch [metadata updates](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#update-the-session-with-metadata). Avoid frequent metadata updates.

- Minimize metadata size for better performance.

- Never store sensitive information in anonymous session metadata.


## Limitations

- Anonymous session metadata transfer is supported with [`post-Login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) and [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) Action triggers.
- [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) — Configure Anonymous Sessions and create your first session in five steps.
- [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases) — Migrate guest activity at login or sign-up.
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
title: Anonymous Sessions Use Cases
description: Use anonymous session data to migrate guest activity at login or sign-up.
sidebarTitle: Use Cases
---

import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx"

<ReleaseStageNotice
feature="Anonymous Sessions"
stage="beta"
terms="true"
contact="Auth0 Support"
/>

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: string; // anonymous session create timestamp
expires_at: string; // anonymous session expire timestamp
metadata: { // anonymous session metadata
[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) — Configure Anonymous Sessions and create your first session in five steps.
Loading
Loading