Authentication API
This documentation is verified against the actual API test suite (test/auth.test.js).
Overview
Baasix provides three core authentication endpoints:
- User registration
- User login
- Get current user information
For social login (35 OAuth providers), passkeys, and two-factor authentication, see their dedicated guides linked in Related Documentation below.
Discovering Enabled Auth Methods
Rather than hardcoding which login methods your UI should show, fetch them at runtime from the public project-info endpoint.
Endpoint: GET /
Authentication: Not required (public endpoint)
The response includes an auth block alongside the other project info fields:
{
"data": {
"project_name": "My Application",
"...": "...",
"auth": {
"registration": true,
"emailPassword": true,
"magicLink": false,
"passkey": true,
"twoFactor": true,
"socialProviders": ["google", "github", "discord"]
}
}
}| Field | Description |
|---|---|
registration | Whether POST /auth/register currently accepts new signups (see Registration Behavior below) |
emailPassword | Whether LOCAL is in AUTH_SERVICES_ENABLED |
magicLink | true only when LOCAL is enabled and SMTP is configured |
passkey | Whether Passkeys are enabled and fully configured |
twoFactor | Whether Two-Factor Authentication is enabled |
socialProviders | The ids of OAuth providers actually constructed at startup — see SSO & Social Authentication |
Only providers that are both enabled in AUTH_SERVICES_ENABLED and fully credentialed appear in socialProviders. No
secrets or client IDs are ever exposed by this endpoint — it's safe to call from an unauthenticated login page.
Authentication Modes (authMode)
Baasix supports two authentication modes for token delivery. Pass the authMode parameter in login, register, or social sign-in requests:
| Mode | Value | Description |
|---|---|---|
| JWT | jwt (default) | Token returned in response body |
| Cookie | cookie | Token set as HTTP-only cookie |
JWT Mode (Default)
Token is returned in the response body. Store and include it in the Authorization header:
curl http://localhost:3000/items/posts \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Cookie Mode
Token is set as an HTTP-only cookie. Include credentials in requests:
fetch('http://localhost:3000/items/posts', {
credentials: 'include',
});For detailed authMode configuration and usage, see SSO & Social Authentication - Authentication Modes.
Register a New User
Create a new user account.
Endpoint: POST /auth/register
Authentication: Not required
Request Body
{
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"password": "password123",
"authMode": "jwt"
}| Field | Type | Required | Description |
|---|---|---|---|
| firstName | string | Yes | User's first name |
| lastName | string | Yes | User's last name |
| string | Yes | User's email address | |
| password | string | Yes | User's password |
| authMode | string | No | jwt (default) or cookie |
Response
Success (200 OK):
{
"message": "User registered successfully",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"authMode": "jwt",
"user": {
"id": "user-uuid",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
},
"role": {
"id": "role-id-here",
"name": "user"
},
"permissions": [...],
"tenant": null
}Error (400 Bad Request):
When email already exists:
{
"message": "User already exists"
}Public Registration Behavior
Registration is controlled by the PUBLIC_REGISTRATION environment variable (default true).
Error (403 Forbidden) when PUBLIC_REGISTRATION=false:
{
"message": "Public registration is disabled",
"code": "REGISTRATION_DISABLED"
}Setting PUBLIC_REGISTRATION=false only blocks self-serve signups — invitations still work. A request that
carries a valid inviteToken (see Multi-tenant Guide) is accepted even
with public registration disabled.
Example
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"password": "securepass123",
"authMode": "jwt"
}'User Login
Authenticate with email and password.
Endpoint: POST /auth/login
Authentication: Not required
Request Body
{
"email": "user@example.com",
"password": "password123",
"authMode": "jwt"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email address | |
| password | string | Yes | User's password |
| authMode | string | No | jwt (default) or cookie |
| tenant_Id | string | No | Tenant ID (for multi-tenant mode) |
Response
Success (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"authMode": "jwt",
"user": {
"id": "user-uuid",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
},
"role": {
"id": "role-uuid",
"name": "user"
},
"permissions": [...],
"tenant": null
}Error (400 Bad Request):
When password is incorrect:
{
"message": "Incorrect password."
}Two-Factor Challenge
If the user has two-factor authentication enabled, this endpoint does not return a session directly. Instead it returns a challenge:
{
"twoFactorRequired": true,
"twoFactorToken": "short-lived-challenge-token",
"code": "TWO_FACTOR_REQUIRED"
}Complete the login by submitting the code to POST /auth/2fa/verify — see the Two-Factor Authentication guide for the full flow. The challenge is single-use and expires after 5 minutes.
Example
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "securepass123"
}'Using the Token
Include the token in the Authorization header for subsequent requests:
curl http://localhost:3000/auth/me \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Get Current User
Retrieve information about the authenticated user.
Endpoint: GET /auth/me
Authentication: Required (Bearer token)
Request Headers
Authorization: Bearer YOUR_TOKEN_HEREResponse
Success (200 OK):
{
"user": {
"id": "user-id",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
}
}Error (401 Unauthorized):
When no authentication provided:
{
"message": "Unauthorized"
}Example
curl http://localhost:3000/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Refresh Token
Refresh the current access token to extend the session. This creates a new session and invalidates the old one.
Endpoint: POST /auth/refresh
Authentication: Required (Bearer token)
Request Headers
Authorization: Bearer YOUR_CURRENT_TOKEN
Content-Type: application/jsonRequest Body (Optional)
{
"authMode": "jwt"
}| Field | Type | Description |
|---|---|---|
authMode | string | Optional. "jwt" (default) or "cookie" |
Response
Success (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"authMode": "jwt",
"expiresIn": 604800
}Error (401 Unauthorized):
{
"message": "Invalid or expired token"
}Example
curl -X POST http://localhost:3000/auth/refresh \
-H "Authorization: Bearer YOUR_CURRENT_TOKEN" \
-H "Content-Type: application/json"User Logout
Log out the current user and invalidate their session.
Endpoint: GET /auth/logout
Authentication: Required (Bearer token)
Response
Success (200 OK):
{
"message": "Logged out successfully"
}Example
curl http://localhost:3000/auth/logout \
-H "Authorization: Bearer YOUR_TOKEN"Check Token
Verify if the current JWT token is valid.
Endpoint: GET /auth/check
Authentication: Required (Bearer token)
Response
Success (200 OK):
{
"valid": true,
"user": {
"id": "user-uuid"
}
}Error (401 Unauthorized):
{
"valid": false,
"message": "Invalid or expired token"
}Example
curl http://localhost:3000/auth/check \
-H "Authorization: Bearer YOUR_TOKEN"Request Magic Link
Request a magic link for passwordless authentication. An email with a login link or code will be sent to the user.
Endpoint: POST /auth/magiclink
Authentication: Not required
Request Body
{
"email": "user@example.com",
"link": "https://myapp.com",
"mode": "link"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email address | |
| link | string | Yes* | Base URL for the magic link (*required when mode is "link") |
| mode | string | No | "link" (default) sends a clickable link, "code" sends a code |
Note: When
modeis"link", the email will contain a link like{link}/auth/magiclink/{token}. Whenmodeis"code", the email will contain a short verification code.
Response
Success (200 OK):
{
"message": "Instruction sent to your email"
}Error (404 Not Found):
{
"message": "User not found"
}Error (400 Bad Request):
{
"message": "Invalid link"
}Example
curl -X POST http://localhost:3000/auth/magiclink \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"link": "https://myapp.com",
"mode": "link"
}'Validate Magic Link
Validate a magic link token and authenticate the user.
Endpoint: GET /auth/magiclink/:token
Authentication: Not required
URL Parameters
| Parameter | Type | Description |
|---|---|---|
| token | string | Magic link token from the email |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| authMode | string | Optional. "jwt" or "cookie" |
Response
Success (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"authMode": "jwt",
"user": {
"id": "user-uuid",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
},
"role": {
"id": "role-uuid",
"name": "user"
}
}Error (400 Bad Request):
{
"message": "Invalid or expired magic link"
}Example
curl "http://localhost:3000/auth/magiclink/abc123token?authMode=jwt"Request Password Reset
Request a password reset email. A link with a reset token will be sent to the user's email.
Endpoint: POST /auth/password/reset
Authentication: Not required
Request Body
{
"email": "user@example.com",
"link": "https://myapp.com"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email address | |
| link | string | Yes | Base URL for the reset link (email will contain {link}/auth/reset-password/{token}) |
Response
Success (200 OK):
{
"message": "If an account exists, a reset link will be sent"
}Note: For security reasons, this endpoint always returns the same success message whether the email exists or not.
Example
curl -X POST http://localhost:3000/auth/password/reset \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"link": "https://myapp.com"
}'Reset Password with Token
Reset the user's password using a token received via email.
Endpoint: POST /auth/password/reset/:token
Authentication: Not required
URL Parameters
| Parameter | Type | Description |
|---|---|---|
| token | string | Password reset token from email |
Request Body
{
"password": "newSecurePassword123"
}| Field | Type | Required | Description |
|---|---|---|---|
| password | string | Yes | The new password |
Response
Success (200 OK):
{
"message": "Password reset successfully"
}Error (400 Bad Request):
{
"message": "Invalid or expired reset token"
}Example
curl -X POST http://localhost:3000/auth/password/reset/abc123token \
-H "Content-Type: application/json" \
-d '{
"password": "newSecurePassword123"
}'Change Password
Change the current user's password. Requires the current password for verification.
Endpoint: POST /auth/password/change
Authentication: Required (Bearer token)
Request Body
{
"currentPassword": "oldPassword123",
"newPassword": "newSecurePassword456"
}| Field | Type | Required | Description |
|---|---|---|---|
| currentPassword | string | Yes | Current password |
| newPassword | string | Yes | New password to set |
Response
Success (200 OK):
{
"message": "Password changed successfully"
}Error (400 Bad Request):
{
"message": "Current password is incorrect"
}Example
curl -X POST http://localhost:3000/auth/password/change \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "oldPassword123",
"newPassword": "newSecurePassword456"
}'Request Email Verification
Request an email verification link to be sent to the user's email address.
Endpoint: POST /auth/email/verify
Authentication: Required (Bearer token)
Request Body
{
"link": "https://myapp.com"
}| Field | Type | Required | Description |
|---|---|---|---|
| link | string | Yes | Base URL for the verification link (email will contain {link}/auth/verify-email/{token}) |
Response
Success (200 OK):
{
"message": "Verification email sent"
}Already Verified (200 OK):
{
"message": "Email already verified"
}Example
curl -X POST http://localhost:3000/auth/email/verify \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"link": "https://myapp.com"
}'Verify Email with Token
Verify the user's email address using the token from the verification email.
Endpoint: GET /auth/email/verify/:token
Authentication: Not required
URL Parameters
| Parameter | Type | Description |
|---|---|---|
| token | string | Email verification token |
Response
Success (200 OK):
{
"message": "Email verified successfully"
}Error (400 Bad Request):
{
"message": "Invalid or expired verification token"
}Example
curl "http://localhost:3000/auth/email/verify/abc123token"Authentication Flow
Typical authentication flow:
-
Register - Create a new user account
POST /auth/register → Returns token -
Login - Authenticate existing user
POST /auth/login → Returns token -
Access Protected Resources - Use token in requests
GET /auth/me GET /items/:collection ... (with Authorization header)
Permissions
The /auth/me endpoint requires the user to have read permissions for the baasix_User collection. Administrators can grant this permission using the permissions API:
curl -X POST http://localhost:3000/permissions \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"role_Id": "user-role-id",
"collection": "baasix_User",
"action": "read",
"fields": "*"
}'Default Admin Account
The system creates a default admin account during initialization:
- Email:
admin@baasix.com - Password:
admin@123
Security Warning: Change the default admin password immediately in production environments.
Related Documentation
Social Authentication
- SSO & Social Authentication - 35 OAuth providers, including Google, GitHub, Facebook, and Apple Sign In
Passwordless & Multi-Factor
- Passkeys - WebAuthn usernameless sign-in
- Two-Factor Authentication - TOTP with backup codes
Core API Routes
- Item Routes - CRUD operations for collections
- Schema Routes - Dynamic schema management
- API Routes Reference - Complete endpoint listing
Access Control
- Permission Routes - Role-based access control
- Session Limits Feature - Control concurrent sessions per user
Multi-tenant
- Multi-tenant Guide - Tenant-based authentication and isolation
Real-time
- Socket.IO Integration - Authenticate WebSocket connections
Guides
- Integration Guide - Client-side authentication implementation
- Error Handling Guide - Handle authentication errors
- Deployment Guide - JWT and CORS configuration