Skip to main content

Endpoint

POST /recipe/session
Creates a new session for a user after successful authentication. Returns access and refresh tokens along with session metadata.

Request Body

userId
string
required
The user ID for whom to create the session. This can be either the primary user ID or recipe user ID depending on your authentication setup.
userDataInJWT
object
required
Custom data to be included in the access token JWT payload. This data is accessible without database queries but increases token size.Example:
{
  "role": "admin",
  "permissions": ["read", "write"]
}
userDataInDatabase
object
required
Custom data to be stored in the database and associated with the session. This data is not included in tokens.Example:
{
  "lastLoginIp": "192.168.1.1",
  "deviceInfo": "Chrome on MacOS"
}
enableAntiCsrf
boolean
required
Whether to enable anti-CSRF token protection for this session. Set to true for browser-based applications.
useDynamicSigningKey
boolean
Whether to use dynamic signing keys for the access token. Defaults to true for CDI version >= 2.21.
  • true - Uses rotating keys for enhanced security
  • false - Uses static key for simplified verification

Response

status
string
Always returns "OK" on success.
session
object
Session metadata
accessToken
object
Access token information
refreshToken
object
Refresh token information
idRefreshToken
object
ID refresh token (deprecated in CDI >= 2.21)
antiCsrfToken
string
Anti-CSRF token to be included in subsequent requests (only if enableAntiCsrf is true).

Example Request

curl -X POST https://your-domain.com/recipe/session \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user123",
    "userDataInJWT": {
      "role": "admin",
      "email": "[email protected]"
    },
    "userDataInDatabase": {
      "lastLoginIp": "192.168.1.1",
      "userAgent": "Mozilla/5.0..."
    },
    "enableAntiCsrf": true,
    "useDynamicSigningKey": true
  }'

Example Response

{
  "status": "OK",
  "session": {
    "handle": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "userId": "user123",
    "recipeUserId": "user123",
    "userDataInJWT": {
      "role": "admin",
      "email": "[email protected]"
    },
    "tenantId": "public"
  },
  "accessToken": {
    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiry": 1640000000000,
    "createdTime": 1639996400000
  },
  "refreshToken": {
    "token": "def456...",
    "expiry": 1648000000000,
    "createdTime": 1639996400000
  },
  "antiCsrfToken": "anti-csrf-token-value"
}

Implementation Details

Source Code Reference

Implemented in:

Session Creation Process

  1. Generate Session Handle - Creates a UUID and appends tenant ID if not default
  2. Handle User ID Mapping - Resolves external user ID to SuperTokens user ID if mapping exists
  3. Resolve Primary User - Determines primary user ID for linked accounts
  4. Create Refresh Token - Generates opaque refresh token with optional anti-CSRF
  5. Create Access Token - Generates JWT with user data and token hashes
  6. Store in Database - Persists session data with hashed refresh token
  7. Update Active Users - Records user activity timestamp

Token Expiry

Default token lifetimes (configurable in core config):
  • Access Token: 1 hour (3600000 ms)
  • Refresh Token: 100 days (8640000000 ms)

Security Considerations

Access Token Payload Size: Keep userDataInJWT minimal as it’s included in every request. Large payloads increase bandwidth and may exceed size limits.
User ID Mapping: If using external user ID mapping, provide the external user ID. The core will automatically resolve to the internal SuperTokens user ID.
Enable Anti-CSRF: Always enable anti-CSRF protection for browser-based applications to prevent cross-site request forgery attacks.

Error Responses

status
string
Error status code
message
string
Error description

Common Errors

  • 400 Bad Request: Invalid userDataInJWT payload that exceeds size limits or contains invalid data
  • 500 Internal Server Error: Database connection issues or internal processing errors

CDI Version Compatibility

  • CDI < 2.21: Returns idRefreshToken in response
  • CDI >= 2.21: idRefreshToken removed, useDynamicSigningKey parameter available
  • CDI >= 3.0: tenantId included in session response
  • CDI >= 4.0: recipeUserId included in session response

Build docs developers (and LLMs) love