Skip to main content

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

ParameterTypeRequiredDescription
usernamestringYesYour username
passwordstringYesYour password
tenantIdstringYesYour 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

FieldTypeDescription
access_tokenstringJWT token for authenticated requests
token_typestringAlways "Bearer"
expires_innumberToken expiration time in seconds (typically 3600)
userobjectUser information
user.idstringUnique user identifier
user.usernamestringUsername
user.tenant_idstringTenant identifier
user.rolesstring[]User roles
user.permissionsstring[]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:

  1. You'll receive a 401 Unauthorized response
  2. Call the login endpoint again to obtain a new token
  3. 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.

EndpointMethodDescription
/api/v1/admin/api-keysGETList all API keys (key values are never returned)
/api/v1/admin/api-keysPOSTCreate a new API key (key shown only once)
/api/v1/admin/api-keys/:idGETGet API key details
/api/v1/admin/api-keys/:idDELETERevoke an API key
/api/v1/admin/api-keys/:id/usageGETGet usage logs
/api/v1/admin/api-keys/permissionsGETList available permissions

Available Permissions

PermissionDescription
bookings:readView booking details
bookings:writeCreate and modify bookings
bookings:cancelCancel existing bookings
availability:readCheck slot availability
products:readView product catalog
products:writeCreate and update products
customers:readView customer information
customers:writeCreate and update customers
reports:readAccess 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

  1. Never expose tokens: Never commit tokens to version control or expose them in client-side code
  2. Use HTTPS: Always use HTTPS in production to encrypt token transmission
  3. Store securely: Store tokens securely (e.g., in memory, secure storage, or environment variables)
  4. Rotate regularly: Implement token refresh logic to rotate tokens before expiration
  5. 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.