Skip to main content

Overview

JWT authentication is ideal for first-party web apps and server integrations that can safely store user credentials.
  • POST /api/v1/auth/login exchanges credentials for an access token.
  • HttpOnly cookies (auth_token, refresh_token_id) are also set for browser clients.
  • Use POST /api/v1/auth/refresh-session to rotate short-lived tokens.
Access tokens expire quickly (15 minutes). Always implement refresh logic.

Login Flow

  1. Collect email/password from the integration user.
  2. Send the payload to /api/v1/auth/login.
  3. Cache the returned JWT for Authorization headers.
  4. Store refresh identifiers securely.
POST /api/v1/auth/login
{
  "email": "[email protected]",
  "password": "password"
}
Response:
{
  "success": true,
  "data": {
    "user": {
      "id": "uuid",
      "email": "[email protected]",
      "firstName": "John",
      "lastName": "Doe",
      "role": "member",
      "firmId": "uuid",
      "isActive": true,
      "firm": {
        "id": "uuid",
        "name": "Law Firm Name"
      }
    },
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "refresh_token_string"
  }
}
The accessToken should be used in the Authorization: Bearer <token> header for subsequent API requests. The refreshToken can be used to obtain a new access token when it expires. HttpOnly cookies are also set for browser-based clients.

Using Tokens

Include the JWT in every request:
Authorization: Bearer <jwt>

Refresh Sessions

  • Endpoint: POST /api/v1/auth/refresh-session
  • Requires the refresh_token_id cookie (for browser clients) or refresh token in the request body (for server-to-server).
  • Returns a brand new JWT access token and rotates refresh identifiers.
  • Access tokens expire after 15 minutes (configurable via JWT_EXPIRES_IN).
  • Refresh tokens expire after 7 days (configurable via JWT_REFRESH_EXPIRES_IN).
For browser clients, the refresh endpoint automatically uses the refresh_token_id cookie:
POST /api/v1/auth/refresh-session
Content-Type: application/json
Cookie: refresh_token_id=<refresh_token_id>

{}
Response:
{
  "success": true,
  "message": "Session refreshed successfully"
}
The response sets new HttpOnly cookies:
  • auth_token - New JWT access token
  • refresh_token_id - New refresh token identifier

Server-to-Server Refresh

For server integrations, include the refresh token in the request:
POST /api/v1/auth/refresh-session
Content-Type: application/json

{
  "refreshToken": "<refresh_token_string>"
}
Use server-side storage for refresh tokens. Browser integrations should rely on HttpOnly cookies. Always implement automatic token refresh logic to handle expired tokens gracefully.
If refresh fails (token expired, revoked, or user inactive), the endpoint clears authentication cookies and returns a 401 error. Your application should redirect to login in this case.

Error Codes

All errors follow the standard error response format:
{
  "success": false,
  "error": {
    "code": "token_expired",
    "message": "Access token has expired",
    "details": []
  }
}
Common authentication error codes:
  • no_token – Missing Authorization header
  • token_expired – Access token exceeded its TTL
  • token_invalid – Token signature or claims invalid
  • rate_limited_email / rate_limited_ip – Too many login attempts
  • account_not_fully_activated – User account is inactive
  • account_inactive_login_attempt – Login attempt on inactive account
Standard HTTP status codes:
  • 400 – Bad Request (validation errors, invalid token)
  • 401 – Unauthorized (authentication failed)
  • 403 – Forbidden (account inactive)