Overview
Hayon uses JWT (JSON Web Tokens) for API authentication. There are two token types:| Token | Delivery | Lifetime | Purpose |
|---|---|---|---|
| Access token | JSON response body | Short-lived | Authenticates individual API requests |
| Refresh token | httpOnly cookie | 7 days | Issues new access tokens without re-login |
Including the access token in requests
Pass the access token in theAuthorization header on every protected request:
Authorization header and validates the Bearer token. Requests without a valid token receive a 401 Unauthorized response.
The refresh token is stored in an
httpOnly cookie named refreshToken scoped to /api/auth. It is never accessible from JavaScript, which protects it from XSS attacks. Your HTTP client must send cookies automatically (e.g., credentials: 'include' in fetch).Refreshing tokens
When the access token expires, call the refresh endpoint. The refresh token cookie is sent automatically by the browser or HTTP client:refreshToken cookie is set on the response and the previous token is invalidated. Store the new access token and continue making requests.
Error response (missing or expired refresh token):
Refresh token rotation
Every successful call toPOST /api/auth/refresh invalidates the previous refresh token and issues a new one. This limits the damage if a refresh token is stolen — a token can only be used once.
If an already-used refresh token is presented, the request fails with 401.
Access token expiry
Access tokens are short-lived JWTs signed with theACCESS_TOKEN_SECRET environment variable. The expiry duration is configured via JWT_EXPIRES_IN (defaults to 7d if not set). When an access token expires, the API returns:
401 responses, call the refresh endpoint, update the stored access token, and retry the original request.
Device session management
Each login or signup creates a new device session backed by the refresh token. You can inspect and revoke sessions:GET /api/auth/devices— list all active sessions for the authenticated userDELETE /api/auth/devices/:tokenId— revoke a specific sessionDELETE /api/auth/logout/all— revoke all sessions across all devices
Rate limiting on auth endpoints
Authentication endpoints are rate-limited per email address to prevent brute-force attacks:| Endpoint | Limit | Window |
|---|---|---|
POST /api/auth/login | 5 attempts | 15 minutes |
POST /api/auth/request-otp | 2 requests | 1 hour |
POST /api/auth/verify-otp | 5 attempts | 15 minutes |
429 Too Many Requests with a Retry-After header indicating when the window resets.
Authentication errors
401 Unauthorized — missing Authorization header
401 Unauthorized — missing Authorization header
401 Unauthorized — invalid or expired token
401 Unauthorized — invalid or expired token
401 Unauthorized — user no longer exists
401 Unauthorized — user no longer exists
