Authentication
Authenticate with the Reten API using API keys or JWT tokens.
All endpoints require authentication unless marked as Public. Reten supports two authentication methods.
API Keys (Recommended for Integrations)
API keys provide stateless authentication ideal for integrations, CI/CD pipelines, and service-to-service communication.
Key Characteristics
- Scoped permissions — each key carries an explicit list of permissions (subset of the creator's)
- Tenant-bound — each key is associated with a specific tenant (no
x-tenant-idheader needed) - Secure storage — only a SHA-256 hash is stored; the plaintext key is shown once at creation
- Optional expiration — keys can have an expiry date after which they are automatically rejected
Creating an API Key
Create an API key via POST /api/api-keys with the desired permissions. The plaintext key is returned once and must be stored securely.
Request
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable name for the key |
permissions | string[] | Yes | Permissions to grant (subset of your own) |
expiresAt | ISO 8601 | No | Expiration date |
curl -X POST https://api.reten.ai/api/api-keys \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Integration Key",
"permissions": ["VIEW_ACTIVITIES", "CREATE_ACTIVITY"]
}'import axios from 'axios';
const response = await axios.post(
'https://api.reten.ai/api/api-keys',
{
name: 'Integration Key',
permissions: ['VIEW_ACTIVITIES', 'CREATE_ACTIVITY'],
},
{
headers: {
Authorization: 'Bearer <token>',
'x-tenant-id': '<tenant-id>',
},
}
);
// Save this key securely — it is only shown once
const apiKey = response.data.key; // rtn_sk_...Using an API Key
Include the key in the x-api-key header for all requests:
x-api-key: rtn_sk_<key>When using an API key, the tenant is resolved automatically — no x-tenant-id header is needed.
Email + Password (JWT)
JWT tokens are used for interactive user sessions. The flow involves a login request that returns an access token and sets a refresh token cookie.
Auth Flow
- Call
POST /api/auth/loginwith email and password - Receive an access token in the response body; a refresh token is set as an HTTP-only cookie
- Include the access token in all subsequent requests via the
Authorizationheader - When the access token expires (15 min), call
POST /api/auth/refresh— the server validates the refresh cookie and issues a new access token - On logout, the refresh cookie is cleared
Token Lifetimes
| Token | Lifetime | Transport |
|---|---|---|
| Access token | 15 minutes | Authorization: Bearer header |
| Refresh token | 7 days | HTTP-only cookie |
Login Request
| Field | Type | Required | Description |
|---|---|---|---|
identifier | string | Yes | Username or email address |
password | string | Yes | User password (min 8 characters) |
curl -X POST https://api.reten.ai/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"identifier": "admin@example.com",
"password": "SecurePass123!"
}'import axios from 'axios';
const response = await axios.post(
'https://api.reten.ai/api/auth/login',
{
identifier: 'admin@example.com',
password: 'SecurePass123!',
}
);
const { accessToken, user } = response.data;Response 200 OK
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "admin@example.com",
"firstName": "Admin",
"lastName": "User"
}
}Using JWT with Tenant Context
When authenticating with JWT, most endpoints require a tenant context via the x-tenant-id header:
Authorization: Bearer <access_token>
x-tenant-id: <tenant_uuid>You can retrieve the list of tenants your user belongs to via GET /api/tenants/my-tenants.