Authentication API
The Authentication API provides endpoints for obtaining access tokens and managing authentication.
Login
Authenticate and obtain a JWT access token for API access.
POST /api/auth/login
Content-Type: application/json
Request Body
{
"username": "your-username",
"password": "your-password",
"tenantId": "t_demo"
}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Your username |
password | string | Yes | Your password |
tenantId | string | Yes | Your tenant ID |
Response
Status: 200 OK
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": "user_123",
"username": "your-username",
"tenant_id": "t_demo",
"roles": ["admin"],
"permissions": ["bookings:read", "bookings:write", "admin:access"]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
access_token | string | JWT token for authenticated requests |
token_type | string | Always "Bearer" |
expires_in | number | Token expiration time in seconds (typically 3600) |
user | object | User information |
user.id | string | Unique user identifier |
user.username | string | Username |
user.tenant_id | string | Tenant identifier |
user.roles | string[] | User roles |
user.permissions | string[] | User permissions |
Error Responses
401 Unauthorized - Invalid credentials
{
"error": "INVALID_CREDENTIALS",
"message": "Invalid username or password",
"code": 401
}
400 Bad Request - Missing required fields
{
"error": "VALIDATION_ERROR",
"message": "Missing required field: username",
"code": 400
}
Usage Example
cURL
curl -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "admin123",
"tenantId": "t_demo"
}'
JavaScript/TypeScript
async function login(username: string, password: string, tenantId: string) {
const response = await fetch('http://localhost:3001/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
tenantId,
}),
});
if (!response.ok) {
throw new Error('Login failed');
}
const data = await response.json();
return data.access_token;
}
// Usage
const token = await login('admin', 'admin123', 't_demo');
console.log('Token:', token);
Python
import requests
def login(username: str, password: str, tenant_id: str) -> str:
response = requests.post(
'http://localhost:3001/api/auth/login',
json={
'username': username,
'password': password,
'tenantId': tenant_id,
}
)
response.raise_for_status()
return response.json()['access_token']
# Usage
token = login('admin', 'admin123', 't_demo')
print(f'Token: {token}')
Token Usage
Once you have obtained an access token, include it in all subsequent API requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
x-tenant-id: t_demo
Token Expiration
Tokens expire after the time specified in expires_in (typically 1 hour). When a token expires:
- You'll receive a
401 Unauthorizedresponse - Call the login endpoint again to obtain a new token
- Use the new token for subsequent requests
Handling Token Expiration
async function apiRequest(url: string, token: string, tenantId: string) {
let response = await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
'x-tenant-id': tenantId,
'Content-Type': 'application/json',
},
});
// Handle token expiration
if (response.status === 401) {
// Token expired, re-authenticate
const newToken = await login(username, password, tenantId);
// Retry with new token
response = await fetch(url, {
headers: {
Authorization: `Bearer ${newToken}`,
'x-tenant-id': tenantId,
'Content-Type': 'application/json',
},
});
}
return response.json();
}
API Key Authentication
For machine-to-machine integrations, Sessiq supports API key authentication as an alternative to JWT tokens. API keys are scoped to a tenant and carry granular permissions.
Sending an API Key
API keys can be sent via either header:
x-api-key: bk_abc123...
or as a Bearer token:
Authorization: Bearer bk_abc123...
Keys are identified by the bk_ prefix. The system hashes the key with SHA-256 and looks it up in the database, then validates status, tenant account, optional IP whitelist, and rate limits.
Managing API Keys
API keys are managed through the admin endpoints. A Pro or Enterprise plan is required.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/api-keys | GET | List all API keys (key values are never returned) |
/api/v1/admin/api-keys | POST | Create a new API key (key shown only once) |
/api/v1/admin/api-keys/:id | GET | Get API key details |
/api/v1/admin/api-keys/:id | DELETE | Revoke an API key |
/api/v1/admin/api-keys/:id/usage | GET | Get usage logs |
/api/v1/admin/api-keys/permissions | GET | List available permissions |
Available Permissions
| Permission | Description |
|---|---|
bookings:read | View booking details |
bookings:write | Create and modify bookings |
bookings:cancel | Cancel existing bookings |
availability:read | Check slot availability |
products:read | View product catalog |
products:write | Create and update products |
customers:read | View customer information |
customers:write | Create and update customers |
reports:read | Access analytics and reports |
Wildcard support: bookings:* grants all booking permissions.
Example: Creating an API Key
curl -X POST http://localhost:3001/api/v1/admin/api-keys \
-H "Authorization: Bearer $TOKEN" \
-H "x-tenant-id: t_demo" \
-H "Content-Type: application/json" \
-d '{
"name": "POS Integration",
"permissions": ["bookings:read", "bookings:write", "availability:read"]
}'
Example: Using an API Key
curl http://localhost:3001/api/v1/availability?productId=p_demo&siteId=s_demo \
-H "x-api-key: bk_live_abc123..." \
-H "x-tenant-id: t_demo"
Security Notes
- Key storage: Keys are hashed with SHA-256 and never stored in plain text.
- Single display: The full key is returned only once at creation time.
- IP whitelist: Optional per-key IP filtering is supported.
- Rate limiting: Configurable per-key rate limits (default: 1000 requests per hour).
- Expiration: Optional expiry date on keys.
- Usage tracking: All requests are logged with endpoint, method, status code, response time, IP, and user agent.
Security Best Practices
- Never expose tokens: Never commit tokens to version control or expose them in client-side code
- Use HTTPS: Always use HTTPS in production to encrypt token transmission
- Store securely: Store tokens securely (e.g., in memory, secure storage, or environment variables)
- Rotate regularly: Implement token refresh logic to rotate tokens before expiration
- Scope permissions: Request only the permissions you need
Development Credentials
For development and testing, you can use:
- Username:
admin - Password:
admin123 - Tenant ID:
t_demo
Note: These credentials are for development only. Change them before deploying to production.