Service accounts
Service accounts are named identities that authenticate with API keys. They share the same role-based access control as human users and live under /api/bot-accounts.
All endpoints require builder access (superadmin or the engineer role). Role assignments follow the scoped role assignment rules. Only a superadmin may change, delete, assign or remove roles on, or create or revoke keys for an account that holds a superadmin grant.
List service accounts
Section titled “List service accounts”GET /api/bot-accountsReturns service accounts with their roles.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit |
integer |
Max results (default: 50) |
offset |
integer |
Pagination offset (default: 0) |
Example request
curl https://lt.acme.dev/api/bot-accounts \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "bots": [ { "id": "a1b2c3d4-...", "external_id": "ci-bot", "display_name": "CI Bot", "account_type": "bot", "description": "Runs scheduled workflows", "status": "active", "roles": [ { "role": "scheduler", "type": "member", "created_at": "2025-03-01T00:00:00.000Z" } ], "created_at": "2025-03-01T00:00:00.000Z", "updated_at": "2025-03-01T00:00:00.000Z" } ], "total": 1}Get service account details
Section titled “Get service account details”GET /api/bot-accounts/:idReturns one service account.
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
Example request
curl https://lt.acme.dev/api/bot-accounts/a1b2c3d4-... \ -H "Authorization: Bearer $LT_TOKEN"Response 200
A single service account object.
Response 404
{ "error": "Bot not found" }Create service account
Section titled “Create service account”POST /api/bot-accountsCreates a service account, optionally with initial roles.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
yes | Unique identifier (used as external_id) |
display_name |
string |
no | Human-readable name |
description |
string |
no | Purpose of this service account |
roles |
array |
no | Initial role assignments: [{ role, type }] |
Example request
curl -X POST https://lt.acme.dev/api/bot-accounts \ -H "Authorization: Bearer $LT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "ci-bot", "display_name": "CI Bot", "description": "Runs scheduled workflows", "roles": [{ "role": "scheduler", "type": "member" }] }'Response 201
The created service account object.
Response 409
{ "error": "Bot with this name already exists" }Update service account
Section titled “Update service account”PUT /api/bot-accounts/:idUpdates a service account’s display fields or status.
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
Request body
| Field | Type | Description |
|---|---|---|
display_name |
string |
New display name |
description |
string |
New description |
status |
string |
active, inactive, or suspended |
Example request
curl -X PUT https://lt.acme.dev/api/bot-accounts/a1b2c3d4-... \ -H "Authorization: Bearer $LT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status": "suspended" }'Response 200
The updated service account object.
Delete service account
Section titled “Delete service account”DELETE /api/bot-accounts/:idDeletes the service account and all its API keys (cascade).
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
Example request
curl -X DELETE https://lt.acme.dev/api/bot-accounts/a1b2c3d4-... \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "deleted": true }Service account roles
Section titled “Service account roles”Roles on a service account work the same way as user roles, including the scoped role assignment rules. The three endpoints below mirror /api/users/:id/roles.
List service account roles
Section titled “List service account roles”GET /api/bot-accounts/:id/rolesReturns the roles the service account holds.
Example request
curl https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../roles \ -H "Authorization: Bearer $LT_TOKEN"Add role to service account
Section titled “Add role to service account”POST /api/bot-accounts/:id/rolesGrants a role to the service account.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
role |
string |
yes | Role name |
type |
string |
yes | superadmin, admin, or member |
Example request
curl -X POST https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../roles \ -H "Authorization: Bearer $LT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "role": "scheduler", "type": "member" }'Remove role from service account
Section titled “Remove role from service account”DELETE /api/bot-accounts/:id/roles/:roleRemoves one role from the service account.
Example request
curl -X DELETE https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../roles/scheduler \ -H "Authorization: Bearer $LT_TOKEN"API keys
Section titled “API keys”Each service account can hold several named API keys. The raw key is returned once, at creation.
Generate key
Section titled “Generate key”POST /api/bot-accounts/:id/api-keysCreates an API key for the service account.
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
yes | Key name (unique per service account) |
scopes |
string[] |
no | Allowed scopes (default: []) |
expires_at |
string |
no | ISO 8601 expiry date |
Example request
curl -X POST https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../api-keys \ -H "Authorization: Bearer $LT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "production", "scopes": ["mcp:read"], "expires_at": "2027-01-01T00:00:00.000Z" }'Response 201
{ "id": "key-uuid", "rawKey": "lt_bot_a1b2c3d4e5f6..."}The rawKey is shown once. Store it when you receive it.
API key scopes
Section titled “API key scopes”Scopes control which tools a key can reach on the /mcp endpoint:
| Scope | Description |
|---|---|
mcp:read |
Read-safe tools only: discovery, monitoring, queries |
mcp:full |
All tools: modify state, invoke workflows, manage resources |
A key with mcp:read only sees tools marked read_safe: true. A key with both mcp:read and mcp:full sees all tools. Keys without MCP scopes have no MCP tool filtering applied.
Recommended keys per service account:
- Read key: scopes
["mcp:read"], for monitoring systems. - Full key: scopes
["mcp:read", "mcp:full"], for automation and orchestration.
List keys
Section titled “List keys”GET /api/bot-accounts/:id/api-keysReturns key metadata. Secret values are never returned.
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
Example request
curl https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../api-keys \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "keys": [ { "id": "key-uuid", "name": "production", "scopes": ["mcp:tool:call"], "last_used_at": "2025-03-15T12:00:00.000Z", "created_at": "2025-03-01T00:00:00.000Z" } ]}Revoke key
Section titled “Revoke key”DELETE /api/bot-accounts/:id/api-keys/:keyIdRevokes one API key.
Path parameters
| Parameter | Description |
|---|---|
id |
Service account UUID |
keyId |
API key id |
Example request
curl -X DELETE https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../api-keys/key-uuid \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "revoked": true }Response 404
The key does not exist or belongs to a different service account than :id.
{ "error": "API key not found" }Using a service account API key
Section titled “Using a service account API key”Send the raw key as a Bearer token on any API request:
curl https://lt.acme.dev/api/tasks \ -H "Authorization: Bearer lt_bot_a1b2c3d4e5f6..."The service account authenticates through the same middleware as human users. RBAC checks use the account’s assigned roles.
