Skip to content

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.

GET /api/bot-accounts

Returns service accounts with their roles.

Query parameters

Parameter Type Description
limit integer Max results (default: 50)
offset integer Pagination offset (default: 0)

Example request

Terminal window
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 /api/bot-accounts/:id

Returns one service account.

Path parameters

Parameter Description
id Service account UUID

Example request

Terminal window
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" }
POST /api/bot-accounts

Creates 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

Terminal window
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" }
PUT /api/bot-accounts/:id

Updates 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

Terminal window
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 /api/bot-accounts/:id

Deletes the service account and all its API keys (cascade).

Path parameters

Parameter Description
id Service account UUID

Example request

Terminal window
curl -X DELETE https://lt.acme.dev/api/bot-accounts/a1b2c3d4-... \
-H "Authorization: Bearer $LT_TOKEN"

Response 200

{ "deleted": true }

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.

GET /api/bot-accounts/:id/roles

Returns the roles the service account holds.

Example request

Terminal window
curl https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../roles \
-H "Authorization: Bearer $LT_TOKEN"
POST /api/bot-accounts/:id/roles

Grants 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

Terminal window
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" }'
DELETE /api/bot-accounts/:id/roles/:role

Removes one role from the service account.

Example request

Terminal window
curl -X DELETE https://lt.acme.dev/api/bot-accounts/a1b2c3d4-.../roles/scheduler \
-H "Authorization: Bearer $LT_TOKEN"

Each service account can hold several named API keys. The raw key is returned once, at creation.

POST /api/bot-accounts/:id/api-keys

Creates 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

Terminal window
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.

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.
GET /api/bot-accounts/:id/api-keys

Returns key metadata. Secret values are never returned.

Path parameters

Parameter Description
id Service account UUID

Example request

Terminal window
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"
}
]
}
DELETE /api/bot-accounts/:id/api-keys/:keyId

Revokes one API key.

Path parameters

Parameter Description
id Service account UUID
keyId API key id

Example request

Terminal window
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" }

Send the raw key as a Bearer token on any API request:

Terminal window
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.