Skip to content

Create authentication token

Request

Universal token creation with consistent token-in-body pattern.

Authentication Flows

USER AUTHENTICATION

  • Header: x-project-key (tenant identification)
  • Body: { authToken: "jwt_from_provider", authType: "user" }
  • Returns: User session with PERS JWT tokens

BUSINESS AUTHENTICATION

  • Header: x-project-key (tenant identification)
  • Body: { authToken: "jwt_from_provider", authType: "business", context: { businessId: "uuid" } }
  • Returns: Business session with PERS JWT tokens (includes role in JWT)
  • If user has single business membership, context.businessId is auto-selected
  • If user has multiple memberships without context.businessId, returns MULTIPLE_CONTEXT_SELECTION_REQUIRED error with available options

ADMIN AUTHENTICATION

  • Header: x-project-key (tenant identification)
  • Body: { authToken: "firebase_jwt", authType: "tenant" }
  • Returns: Admin session with PERS JWT tokens

Third-Party JWT Requirements

When providing authToken from an external identity provider, the JWT must meet these requirements:

JWT Header

FieldRequiredDescription
kidYesKey ID matching a key in your JWKS
algYesSigning algorithm (RS256, ES256, EdDSA)

JWT Payload Claims

ClaimRequiredDescription
issYesIssuer URL (used for JWKS discovery)
subYesSubject identifier (user ID)
audYesAudience (your registered client ID)
expYesExpiration timestamp (Unix epoch)
iatYesIssued at timestamp (Unix epoch)

Provider Requirements

Your identity provider must expose public keys via one of:

  1. {issuer}/.well-known/jwks.json (JWKS endpoint)
  2. {issuer}/.well-known/openid-configuration (OIDC discovery with jwks_uri)

Verification Flow

  1. PERS extracts iss claim from JWT
  2. Fetches JWKS from {issuer}/.well-known/jwks.json
  3. Matches kid header to find signing public key
  4. Verifies signature using matched key
  5. Validates exp, iat, aud claims
  6. Issues PERS access/refresh tokens on success

PERS JWKS (For verifying our tokens)

  • JWKS: https://api.pers.ninja/.well-known/jwks.json
  • Discovery: https://api.pers.ninja/.well-known/openid-configuration
Security
projectKey
Bodyapplication/jsonrequired

Authentication request with token and type. authType defaults to "user" if not specified.

authTokenstring

Authentication token from identity provider (WebAuthn, DFNS, Firebase, Auth0, etc.).

Third-Party JWT Requirements:

  • Header: kid (Key ID matching JWKS), alg (RS256/ES256/EdDSA)
  • Payload Claims: iss (issuer URL), sub (user ID), aud (audience), exp, iat
  • Provider Requirement: Must expose JWKS at {issuer}/.well-known/jwks.json

PERS will automatically discover and fetch the issuer's public keys for verification.

Example:"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtleS0xIn0.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLmNvbSIsInN1YiI6InVzZXItMTIzIiwiYXVkIjoieW91ci1jbGllbnQta
authTypestring

Authentication context type - explicitly declares intent for admin vs user auth

Enum:"user""business""tenant""system""external"
contextobject(AuthContextDTO)

Optional context for explicit business/tenant selection. Required when user has multiple memberships of that type.

rawLoginDataobject

if Tenant settings allowJWTForUnauthenticatedUsers is true, this field contains data to create user and setup unauthenticated user session instead of token verification. Useful for sandbox or trial modes. For now it is only used to create unauthenticated users.

Example:
{ "externalId": "", "email": "user@example.com", "firstName": "", "lastName": "", "customData": {} }
curl -i -X POST \
  https://docs.pers.ninja/_mock/swagger/auth/token \
  -H 'Content-Type: application/json' \
  -H 'x-project-key: YOUR_API_KEY_HERE' \
  -d '{
    "authToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtleS0xIn0.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLmNvbSIsInN1YiI6InVzZXItMTIzIiwiYXVkIjoieW91ci1jbGllbnQtaWQiLCJleHAiOjE3MzM0MDAwMDAsImlhdCI6MTczMzM5NjQwMH0.signature",
    "authType": "user",
    "context": {
      "businessId": "550e8400-e29b-41d4-a716-446655440000",
      "tenantId": "550e8400-e29b-41d4-a716-446655440001"
    },
    "rawLoginData": {
      "externalId": "",
      "email": "user@example.com",
      "firstName": "",
      "lastName": "",
      "customData": {}
    }
  }'

Responses

Token created successfully

Bodyapplication/json
refreshTokenstringrequired

refresh token

Example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRJZCI6IjEiLCJpYXQiOjE2MjYxNzUwNzksImV4cCI6MTYyNjE3NTI3OX0.5w8A6t7b5lBx8D3FmLwJQgJ9z1D9c9Vz7A3f7BvzH2A"
accessTokenstringrequired

JWT access token this token is used to authenticate the user, by default it expires in 15 minutes, and it should be sent in the Authorization header as Bearer token.

Response
{ "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRJZCI6IjEiLCJpYXQiOjE2MjYxNzUwNzksImV4cCI6MTYyNjE3NTI3OX0.5w8A6t7b5lBx8D3FmLwJQgJ9z1D9c9Vz7A3f7BvzH2A", "accessToken": "string" }