Management API

March 13, 2026 · View on GitHub

The Management API is an independent HTTPS server that enables remote configuration, lifecycle management, and monitoring of Teleton agents via typed HTTP endpoints — replacing SSH-based management.

It runs on port 7778 by default, uses self-signed TLS, and authenticates requests with tltn_-prefixed API keys.


Table of Contents


Quick Start

1. Enable in config.yaml

api:
  enabled: true
  port: 7778          # default
  # allowed_ips: []   # empty = allow all authenticated requests

2. Start the agent

teleton start

On first start, a tltn_-prefixed API key is generated and printed to the log. Copy it — it won't be shown again.

To get the key as JSON (useful for automation):

teleton start --json-credentials
# Output: {"apiKey":"tltn_...","fingerprint":"a1b2c3...","port":7778}

3. Make your first call

curl -k https://localhost:7778/v1/agent/status \
  -H "Authorization: Bearer tltn_your_key_here"

Note: -k skips TLS verification for self-signed certs. For production, pin the certificate fingerprint instead (see TLS Certificates).


Bootstrap Mode

Start the API without an existing config.yaml — useful for provisioning a fresh VPS entirely over HTTP.

teleton start --api

This starts only the Management API with null dependencies. All /v1/setup/* endpoints are available for remote configuration. Once setup is complete:

# Complete setup via /v1/setup endpoints, then start the agent:
curl -k https://localhost:7778/v1/agent/start \
  -X POST \
  -H "Authorization: Bearer tltn_..."

The agent boots, and all other endpoints become available. Routes that require the agent return 503 Service Unavailable until it starts.

Bootstrap flow

teleton start --api


  API server starts (null deps)


  POST /v1/setup/* ── configure provider, Telegram, wallet...


  POST /v1/agent/start ── creates TeletonApp, hot-swaps deps


  All /v1/* endpoints operational

Authentication

All /v1/* routes require a Bearer token in the Authorization header:

Authorization: Bearer tltn_<base64url-encoded key>

Key format

  • Prefix: tltn_
  • Payload: 32 random bytes, base64url-encoded
  • Example: tltn_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678901234

How it works

  1. The raw API key is shown once at first start (or via --json-credentials)
  2. Only the SHA-256 hash is persisted in config.yaml (api.key_hash)
  3. On each request, the provided key is hashed and compared using timingSafeEqual (constant-time, timing-attack resistant)

Key rotation

teleton api-rotate-key

Generates a new key, prints it, and persists the new hash to config.yaml. The old key is immediately invalidated.


TLS Certificates

The API generates a self-signed certificate on first start, stored at:

  • ~/.teleton/api-cert.pem (certificate)
  • ~/.teleton/api-key.pem (private key)

Both files have 0o600 permissions (owner read/write only).

Certificate details

PropertyValue
AlgorithmRSA 2048-bit, SHA-256
Validity2 years
SANslocalhost (DNS), 127.0.0.1 (IPv4), ::1 (IPv6)
Auto-renewalRegenerated automatically if expired

Fingerprint

Get the TLS fingerprint for certificate pinning:

teleton api-fingerprint
# Output: a1b2c3d4e5f6...  (SHA-256, 64 hex chars)

Or via --json-credentials at startup.

Using the fingerprint with curl

# Instead of -k, pin the certificate:
curl --cacert ~/.teleton/api-cert.pem \
  https://localhost:7778/healthz

Endpoints

Health Probes

No authentication required.

MethodPathDescription
GET/healthzLiveness probe — always returns { "status": "ok" }
GET/readyzReadiness probe — 200 if agent running, 503 with setup status otherwise

/readyz response when agent is not running:

{
  "status": "not_ready",
  "state": "stopped",
  "setup": {
    "workspace": true,
    "config": true,
    "wallet": true,
    "telegram_session": true,
    "embeddings_cached": false
  }
}

Agent Lifecycle

MethodPathDescription
POST/v1/agent/startStart the agent (fire-and-forget). Returns 409 if already running or stopping.
POST/v1/agent/stopStop the agent. Returns 409 if already stopped or starting.
POST/v1/agent/restartStop then start (fire-and-forget). Returns 409 during transitions.
GET/v1/agent/statusReturns { state, uptime, error }
GET/v1/agent/eventsSSE stream of lifecycle state changes

Agent states: stoppedstartingrunningstoppingstopped

SSE event format (/v1/agent/events):

event: status
id: 1710312345678
data: {"state":"running","error":null,"timestamp":1710312345678}

A ping event is sent every 30 seconds to keep the connection alive.

System

MethodPathDescription
GET/v1/system/versionTeleton version, Node.js version, OS, arch, API version
GET/v1/system/infoCPU model/cores/load, memory usage, process/system uptime

Example response (/v1/system/version):

{
  "teleton": "0.8.3",
  "node": "v22.0.0",
  "os": "linux",
  "arch": "x64",
  "apiVersion": "1.0.0"
}

Auth

MethodPathDescription
POST/v1/auth/validateValidates the API key. Returns { "valid": true, "keyPrefix": "tltn_aBcD..." }

Useful for testing connectivity and key validity without side effects.

Logs

MethodPathDescription
GET/v1/api-logs/recent?lines=100Returns recent log lines (max 1000)
GET/v1/api-logs/streamSSE stream of live log entries

Sessions

MethodPathDescription
DELETE/v1/api-memory/sessions/:chatIdDelete a specific chat session. Returns 404 if not found.
POST/v1/api-memory/sessions/prunePrune sessions older than N days. Body: { "maxAgeDays": 30 } (default: 30).

OpenAPI Spec

MethodPathDescription
GET/v1/openapi.jsonOpenAPI 3.1 specification

Reused WebUI Routes

The API mounts all existing WebUI route factories under /v1/, giving you full access to every dashboard feature via HTTP:

PrefixDescription
/v1/statusAgent status and metrics
/v1/toolsTool inventory and configuration
/v1/logsConversation logs
/v1/memoryMemory search and management
/v1/soulSystem prompt (read-only)
/v1/pluginsPlugin management
/v1/mcpMCP server configuration
/v1/workspaceWorkspace file management
/v1/tasksScheduled tasks
/v1/configConfiguration read/write
/v1/marketplacePlugin marketplace
/v1/hooksHook management
/v1/ton-proxyTON Proxy control
/v1/setupSetup wizard (works without agent)

Routes that require agent subsystems (memory, bridge, etc.) return 503 with an RFC 9457 error if the agent is not running.


Rate Limiting

Three tiers of rate limiting apply to all /v1/* routes:

TierLimitApplies to
Global60 requests/minAll methods
Mutations10 requests/minPOST, PUT, DELETE
Reads300 requests/minGET

Rate limits are keyed per API key prefix. When exceeded, the server returns 429 Too Many Requests with a Retry-After header.


Security

IP Whitelist

Restrict access to specific IPs via api.allowed_ips in config. When the list is empty (default), any authenticated request is accepted.

api:
  allowed_ips:
    - "203.0.113.10"
    - "198.51.100.0/24"

Non-whitelisted IPs receive 403 Forbidden. IPv4-mapped IPv6 addresses (::ffff:X.X.X.X) are normalized automatically.

Brute-Force Protection

  • 10 failed attempts per IP within a 5-minute window triggers a 15-minute block
  • Blocked IPs receive 429 Too Many Requests with Retry-After: 900
  • Failed attempt counters are cleaned up every 5 minutes

Audit Logging

All mutating operations (POST, PUT, DELETE) are logged at warn level with:

{
  "audit": true,
  "event": "api_mutation",
  "method": "POST",
  "path": "/v1/agent/restart",
  "statusCode": 200,
  "durationMs": 12,
  "sourceIp": "203.0.113.10",
  "keyPrefix": "tltn_aBcD",
  "requestId": "550e8400-e29b-41d4-a716-446655440000"
}

Request bodies, headers, and secrets are never logged.

Security Headers

Every response includes:

HeaderValue
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Strict-Transport-Securitymax-age=31536000; includeSubDomains
X-Request-IdUUID (auto-generated or forwarded from client)

Configuration

config.yaml

api:
  enabled: true         # Enable the Management API (default: false)
  port: 7778            # HTTPS port (default: 7778)
  key_hash: ""          # SHA-256 hash of the API key (auto-generated on first start)
  allowed_ips: []       # IP whitelist (empty = allow all)

Environment Variables

VariablePurposeDefault
TELETON_API_ENABLEDEnable Management APIfalse
TELETON_API_PORTHTTPS port7778
TELETON_JSON_CREDENTIALSOutput credentials as JSON on startupfalse

Environment variables take precedence over config.yaml.


CLI Commands

CommandDescription
teleton startStart agent (API starts if api.enabled: true)
teleton start --apiBootstrap mode — API only, no config needed
teleton start --json-credentialsPrint {"apiKey","fingerprint","port"} to stdout
teleton api-rotate-keyGenerate new API key and persist hash
teleton api-fingerprintPrint TLS certificate SHA-256 fingerprint

Error Format

All errors follow RFC 9457 Problem Detail with Content-Type: application/problem+json:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid API key"
}
StatusWhen
401Missing, malformed, or invalid API key
403IP not in whitelist
409Agent state conflict (e.g., start when already running)
413Request body exceeds 2MB
429Rate limit or brute-force block exceeded
503Agent subsystem not available (not started yet)

Examples

Check agent status

curl -k https://localhost:7778/v1/agent/status \
  -H "Authorization: Bearer $TELETON_API_KEY"

Restart the agent

curl -k https://localhost:7778/v1/agent/restart \
  -X POST \
  -H "Authorization: Bearer $TELETON_API_KEY"

Stream lifecycle events

curl -k -N https://localhost:7778/v1/agent/events \
  -H "Authorization: Bearer $TELETON_API_KEY"

Get system info

curl -k https://localhost:7778/v1/system/info \
  -H "Authorization: Bearer $TELETON_API_KEY"

Prune old sessions

curl -k https://localhost:7778/v1/api-memory/sessions/prune \
  -X POST \
  -H "Authorization: Bearer $TELETON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"maxAgeDays": 7}'

Validate your API key

curl -k https://localhost:7778/v1/auth/validate \
  -X POST \
  -H "Authorization: Bearer $TELETON_API_KEY"

Bootstrap a fresh VPS

# 1. Start API-only mode
teleton start --api --json-credentials > /tmp/creds.json

# 2. Extract key
KEY=$(jq -r .apiKey /tmp/creds.json)

# 3. Check readiness (see what's missing)
curl -k https://localhost:7778/readyz

# 4. Configure via setup endpoints
curl -k https://localhost:7778/v1/setup/provider \
  -X POST \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"provider":"anthropic","api_key":"sk-ant-..."}'

# 5. Start the agent
curl -k https://localhost:7778/v1/agent/start \
  -X POST \
  -H "Authorization: Bearer $KEY"

Docker with API enabled

docker run -d \
  --name teleton \
  --restart unless-stopped \
  -e TELETON_API_ENABLED=true \
  -e TELETON_JSON_CREDENTIALS=true \
  -v teleton-data:/data \
  -p 7777:7777 \
  -p 7778:7778 \
  ghcr.io/tonresistor/teleton-agent

Docker Compose

services:
  teleton:
    image: ghcr.io/tonresistor/teleton-agent:latest
    restart: unless-stopped
    ports:
      - "7777:7777"   # WebUI
      - "7778:7778"   # Management API
    volumes:
      - teleton-data:/data
    environment:
      - TELETON_API_ENABLED=true
    healthcheck:
      test: ["CMD", "curl", "-kf", "https://localhost:7778/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3