Skip to main content

Authentication

The API uses JWT bearer tokens for authentication. You'll get two tokens when you log in — each with a different purpose and lifetime.

Token types

TokenLifetimePurpose
Access tokenShort-livedPassed as Authorization: Bearer <token> on every request
Refresh tokenLong-livedUsed to obtain a new access token when the current one expires
┌─────────┐          ┌───────────┐
│ Login │────────→ │ Get both │
│ │ │ tokens │
└─────────┘ └─────┬─────┘

┌─────▼─────┐
┌──────│ Use API │◄────────┐
│ │ normally │ │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ ┌─────┴─────┐
│ │ 401? │──→│ Refresh │
│ └───────────┘ │ token │
│ └───────────┘

┌─────▼──────┐
│ Refresh │
│ also 401? │──→ Re-login
└────────────┘

Step by step

  1. Login — Call POST /v1/auth/login with your email and password. Store both the accessToken and refreshToken.

  2. Use the access token — Include it in every API request:

    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
  3. Handle expiration — When you receive a 401 Unauthorized response, your access token has expired. Call POST /v1/auth/refresh with your refresh token to get a new access token.

  4. Re-login if needed — If the refresh token itself is expired or revoked, you'll get a 401 from the refresh endpoint too. In that case, log in again with POST /v1/auth/login.

Security best practices

  • Store tokens securely — never expose tokens in client-side code, URLs, or logs
  • Refresh proactively — instead of waiting for a 401, you can decode the JWT to check its expiration time and refresh before it expires
  • Revoke on logout — call POST /v1/auth/revoke when a user session ends to invalidate the refresh token
  • Revoke all in emergencies — if you suspect a token has been compromised, call POST /v1/auth/revoke-all to invalidate all sessions