Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usetitan.app/llms.txt

Use this file to discover all available pages before exploring further.

The Admin API is available exclusively on self-hosted Titan instances. It gives you full control over API key lifecycle, instance-wide settings, and license inspection — all authenticated with your master key.
The master key has unrestricted admin access to your Titan instance. Store it in a secrets manager, never hard-code it in application code, and never expose it in client-side or browser environments.

Authentication

Every Admin API request must include the master key as a Bearer token:
Authorization: Bearer {MASTER_KEY}
The master key is the value you set in the MASTER_KEY environment variable when you deployed Titan. All examples below use $MASTER_KEY as a placeholder.

API key management

API keys (titan_ prefix) are what your applications use to authenticate against the Titan REST API. You create and manage them here.

List all keys

curl --request GET \
  --url http://localhost:8080/admin/keys \
  --header "Authorization: Bearer $MASTER_KEY"
{
  "data": [
    {
      "id": "key_01jz4xkq0000000000000000",
      "label": "production-backend",
      "scopes": ["messages:write", "sessions:manage"],
      "isActive": true,
      "createdAt": "2025-05-01T10:00:00Z",
      "expiresAt": "2025-07-30T10:00:00Z"
    }
  ]
}

Create a key

curl --request POST \
  --url http://localhost:8080/admin/keys \
  --header "Authorization: Bearer $MASTER_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "label": "production-backend",
    "lifetimeDays": 90,
    "scopes": ["messages:write", "sessions:manage", "webhooks:manage"]
  }'
{
  "data": {
    "id": "key_01jz4xkq0000000000000000",
    "key": "titan_AAAB...",
    "label": "production-backend",
    "scopes": ["messages:write", "sessions:manage", "webhooks:manage"],
    "isActive": true,
    "createdAt": "2025-05-01T10:00:00Z",
    "expiresAt": "2025-07-29T10:00:00Z"
  }
}
The key field is returned only on creation. Store it immediately — it cannot be retrieved again.
The scopes array controls what the key can do. Available scopes:
ScopeAccess
*All permissions
sessions:readRead session status and info
sessions:manageCreate, start, stop, and delete sessions
messages:writeSend messages
chats:readRead chat history and metadata
chats:manageArchive, delete, and manage chats
contacts:readRead contact list and info
contacts:manageBlock, unblock, and manage contacts
groups:readRead group info
groups:manageCreate, update, and manage groups
webhooks:manageCreate, update, and delete webhooks
media:readDownload media
media:managePersist and manage media

Get a key

curl --request GET \
  --url http://localhost:8080/admin/keys/key_01jz4xkq0000000000000000 \
  --header "Authorization: Bearer $MASTER_KEY"
{
  "data": {
    "id": "key_01jz4xkq0000000000000000",
    "label": "production-backend",
    "scopes": ["messages:write", "sessions:manage"],
    "isActive": true,
    "createdAt": "2025-05-01T10:00:00Z",
    "expiresAt": "2025-07-30T10:00:00Z"
  }
}

Update a key

You can rename a key or enable/disable it without rotating the key material:
curl --request PUT \
  --url http://localhost:8080/admin/keys/key_01jz4xkq0000000000000000 \
  --header "Authorization: Bearer $MASTER_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "label": "production-backend-v2",
    "isActive": true
  }'
{
  "data": {
    "id": "key_01jz4xkq0000000000000000",
    "label": "production-backend-v2",
    "scopes": ["messages:write", "sessions:manage"],
    "isActive": true,
    "createdAt": "2025-05-01T10:00:00Z",
    "expiresAt": "2025-07-30T10:00:00Z"
  }
}

Rotate a key

Rotating a key immediately revokes the old key and issues a new one. The revocation takes effect immediately across all running API instances.
curl --request POST \
  --url http://localhost:8080/admin/keys/key_01jz4xkq0000000000000000/rotate \
  --header "Authorization: Bearer $MASTER_KEY"
{
  "data": {
    "id": "key_01jz9ynr0000000000000000",
    "key": "titan_BBBC...",
    "label": "production-backend-v2",
    "scopes": ["messages:write", "sessions:manage"],
    "isActive": true,
    "createdAt": "2025-05-15T09:00:00Z",
    "expiresAt": "2025-08-13T09:00:00Z"
  }
}
The old key is revoked immediately. Update any application that uses the old key before calling rotate, or update it immediately after and deploy quickly.

Delete a key

curl --request DELETE \
  --url http://localhost:8080/admin/keys/key_01jz4xkq0000000000000000 \
  --header "Authorization: Bearer $MASTER_KEY"
Returns 204 No Content on success. Deletion is immediate and permanent.

Instance settings

Get current settings

curl --request GET \
  --url http://localhost:8080/admin/settings \
  --header "Authorization: Bearer $MASTER_KEY"
{
  "data": {
    "rateLimit": 100,
    "msgRateLimit": 50,
    "debugMode": false,
    "logLevel": "info"
  }
}

Update settings

curl --request PUT \
  --url http://localhost:8080/admin/settings \
  --header "Authorization: Bearer $MASTER_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "rateLimit": 200,
    "msgRateLimit": 100,
    "debugMode": false,
    "logLevel": "warn"
  }'
{
  "data": {
    "rateLimit": 200,
    "msgRateLimit": 100,
    "debugMode": false,
    "logLevel": "warn"
  }
}
Settings fields:
FieldTypeDescription
rateLimitintegerMaximum API requests per minute across all keys
msgRateLimitintegerMaximum message-send requests per minute
debugModebooleanEnable verbose debug logging
logLevelstringLog verbosity: debug, info, warn, error

License info

Inspect the claims embedded in your license file:
curl --request GET \
  --url http://localhost:8080/admin/license \
  --header "Authorization: Bearer $MASTER_KEY"
{
  "data": {
    "sessionLimit": 100,
    "platform": "kubernetes",
    "issuedAt": "2025-01-01T00:00:00Z",
    "expiresAt": "2026-01-01T00:00:00Z",
    "gracePeriodDays": 14,
    "awsAccountId": null,
    "isExpired": false,
    "isInGracePeriod": false
  }
}
FieldDescription
sessionLimitMaximum concurrent WhatsApp sessions allowed by this license
platformPlatform restriction: aws, gcp, azure, docker, kubernetes, or any
issuedAtDate the license was issued
expiresAtLicense expiry date — renew before this date
gracePeriodDaysDays the instance continues to operate after expiry
awsAccountIdAWS account ID the license is bound to, or null if unrestricted
isExpiredtrue if the license has passed its expiry date
isInGracePeriodtrue if the instance is running on the post-expiry grace period

Debug mode

Toggle debug logging without updating instance settings:
curl --request POST \
  --url http://localhost:8080/admin/debug \
  --header "Authorization: Bearer $MASTER_KEY" \
  --header "Content-Type: application/json" \
  --data '{"enabled": true}'
{
  "data": {
    "debugMode": true
  }
}
Enable debug mode temporarily when diagnosing a specific issue, then disable it once you have captured the logs you need. Debug mode produces significantly more log output and can affect performance under load.