Files
tyto/docs/api.md
vikingowl 52c10b3d55 docs: add comprehensive documentation
Documentation structure:
- docs/README.md - Documentation index
- docs/getting-started.md - Installation and first run
- docs/usage.md - Dashboard features and usage
- docs/configuration.md - Full configuration reference
- docs/multi-device.md - Agent setup and PKI management
- docs/security.md - Authentication, RBAC, mTLS
- docs/api.md - Complete REST API reference
- docs/deployment.md - Production deployment guide
- docs/troubleshooting.md - Common issues and solutions
- docs/development.md - Contributing and building

Total: ~80KB of documentation covering all features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:23:02 +01:00

10 KiB

API Reference

Complete reference for the Tyto REST API.

Base URL

http://localhost:8080/api/v1

Authentication

Most endpoints require authentication via Bearer token:

curl -H "Authorization: Bearer <token>" http://localhost:8080/api/v1/...

Obtain Token

curl -X POST http://localhost:8080/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "password"}'

Response:

{
  "token": "abc123...",
  "user": {
    "id": "user-id",
    "username": "admin",
    "email": "admin@example.com",
    "roles": ["admin"]
  },
  "expires_at": "2024-01-16T10:30:00Z"
}

Health Check

GET /health

Check server health.

Authentication: Not required

Response:

{
  "status": "ok",
  "version": "1.0.0",
  "uptime": 3600
}

Authentication

POST /api/v1/auth/login

Authenticate and obtain session token.

Request:

{
  "username": "admin",
  "password": "password"
}

Response:

{
  "token": "abc123...",
  "user": {
    "id": "uuid",
    "username": "admin",
    "email": "admin@example.com",
    "roles": ["admin"],
    "permissions": ["*"]
  },
  "expires_at": "2024-01-16T10:30:00Z"
}

POST /api/v1/auth/logout

Invalidate current session.

Response: 204 No Content

POST /api/v1/auth/register

Register new user (if enabled).

Request:

{
  "username": "newuser",
  "password": "password123",
  "email": "user@example.com"
}

GET /api/v1/auth/me

Get current user info.

Response:

{
  "id": "uuid",
  "username": "admin",
  "email": "admin@example.com",
  "roles": ["admin"],
  "permissions": ["*"],
  "auth_provider": "local",
  "last_login": "2024-01-15T10:30:00Z"
}

PUT /api/v1/auth/me

Update current user profile.

Request:

{
  "email": "newemail@example.com"
}

PUT /api/v1/auth/me/password

Change password.

Request:

{
  "current_password": "old-password",
  "new_password": "new-password"
}

Metrics

GET /api/v1/stream

Server-Sent Events stream of real-time metrics.

Query Parameters:

Parameter Type Description
agent_id string Filter by agent (multi-device mode)

Response: SSE stream

event: metrics
data: {"timestamp":"2024-01-15T10:30:00Z","cpu":{...},"memory":{...}}

event: metrics
data: {"timestamp":"2024-01-15T10:30:05Z","cpu":{...},"memory":{...}}

Metrics Structure:

{
  "timestamp": "2024-01-15T10:30:00Z",
  "system": {
    "hostname": "server-01",
    "kernel": "6.1.0-generic",
    "uptime": 86400,
    "architecture": "x86_64"
  },
  "cpu": {
    "cores": [
      {"id": 0, "usage": 15.5, "frequency": 3600}
    ],
    "totalUsage": 15.5,
    "loadAverage": {"one": 0.5, "five": 0.4, "fifteen": 0.3}
  },
  "memory": {
    "total": 16000000000,
    "used": 8000000000,
    "free": 4000000000,
    "available": 10000000000,
    "buffers": 1000000000,
    "cached": 3000000000,
    "swapTotal": 4000000000,
    "swapUsed": 0
  },
  "disk": {
    "mounts": [
      {
        "device": "/dev/sda1",
        "mountpoint": "/",
        "fstype": "ext4",
        "total": 500000000000,
        "used": 100000000000,
        "free": 400000000000
      }
    ],
    "io": [
      {"device": "sda", "readBytes": 1000000, "writeBytes": 500000}
    ]
  },
  "network": {
    "interfaces": [
      {
        "name": "eth0",
        "ipv4": "192.168.1.100",
        "ipv6": "fe80::1",
        "rxBytes": 1000000000,
        "txBytes": 500000000,
        "rxRate": 10000,
        "txRate": 5000
      }
    ],
    "connectionCount": 42
  },
  "processes": {
    "topByCpu": [...],
    "topByMemory": [...],
    "total": 200
  },
  "temperature": {
    "sensors": [
      {"name": "Core 0", "value": 45.0, "high": 80.0, "critical": 100.0}
    ]
  },
  "gpu": {
    "available": true,
    "gpus": [
      {
        "index": 0,
        "name": "NVIDIA GeForce RTX 3080",
        "vendor": "nvidia",
        "utilization": 45,
        "memoryUsed": 4000000000,
        "memoryTotal": 10000000000,
        "temperature": 65.0,
        "powerWatts": 220.0
      }
    ]
  },
  "docker": {
    "available": true,
    "containers": [
      {"id": "abc123", "name": "nginx", "status": "running", "cpu": 0.5, "memory": 50000000}
    ]
  },
  "systemd": {
    "available": true,
    "services": [
      {"name": "nginx.service", "state": "active", "subState": "running"}
    ]
  }
}

GET /api/v1/history

Get historical metrics.

Query Parameters:

Parameter Type Description
from string Start time (ISO 8601)
to string End time (ISO 8601)
resolution string raw, 1m, 5m, 1h
agent_id string Filter by agent

Response:

{
  "from": "2024-01-15T09:30:00Z",
  "to": "2024-01-15T10:30:00Z",
  "resolution": "1m",
  "data": [
    {
      "timestamp": "2024-01-15T09:30:00Z",
      "cpu": {"avg": 15.0, "min": 10.0, "max": 25.0},
      "memory": {"avg": 50.0, "min": 48.0, "max": 52.0}
    }
  ]
}

GET /api/v1/export/metrics

Export current metrics.

Query Parameters:

Parameter Type Description
format string json or csv

Processes

GET /api/v1/processes/:pid

Get process details.

Response:

{
  "pid": 1234,
  "name": "nginx",
  "cmdline": "/usr/sbin/nginx -g daemon off;",
  "user": "www-data",
  "state": "S",
  "cpu": 0.5,
  "memory": 50000000,
  "threads": 4,
  "startTime": "2024-01-15T08:00:00Z"
}

POST /api/v1/processes/:pid/signal

Send signal to process.

Request:

{
  "signal": 15
}

Common Signals:

Signal Number Description
SIGTERM 15 Graceful termination
SIGKILL 9 Force kill
SIGSTOP 19 Pause process
SIGCONT 18 Resume process

Alerts

GET /api/v1/alerts

Get current alerts.

Response:

{
  "alerts": [
    {
      "id": "alert-1",
      "type": "cpu",
      "level": "warning",
      "value": 85.0,
      "threshold": 80.0,
      "agent_id": "server-01",
      "created_at": "2024-01-15T10:30:00Z",
      "acknowledged": false
    }
  ],
  "config": {
    "cpu": {"warning": 80, "critical": 95},
    "memory": {"warning": 85, "critical": 95},
    "disk": {"warning": 80, "critical": 90}
  }
}

POST /api/v1/alerts/config

Update alert thresholds.

Request:

{
  "cpu": {"warning": 80, "critical": 95},
  "memory": {"warning": 85, "critical": 95},
  "disk": {"warning": 80, "critical": 90}
}

POST /api/v1/alerts/:id/acknowledge

Acknowledge an alert.


Agents

GET /api/v1/agents

List all agents.

Response:

{
  "agents": [
    {
      "id": "web-server-01",
      "name": "Web Server",
      "hostname": "web-server",
      "status": "online",
      "architecture": "amd64",
      "os": "linux",
      "last_seen": "2024-01-15T10:30:00Z",
      "registered_at": "2024-01-01T00:00:00Z"
    }
  ]
}

GET /api/v1/agents/:id

Get agent details.

POST /api/v1/agents

Add agent manually.

Request:

{
  "id": "new-agent",
  "name": "New Agent"
}

DELETE /api/v1/agents/:id

Remove agent.

POST /api/v1/agents/:id/revoke

Revoke agent certificate.

GET /api/v1/agents/pending

List pending agent registrations.

POST /api/v1/agents/pending/:id/approve

Approve pending agent.

POST /api/v1/agents/pending/:id/reject

Reject pending agent.


Users

GET /api/v1/users

List all users.

Response:

{
  "users": [
    {
      "id": "uuid",
      "username": "admin",
      "email": "admin@example.com",
      "roles": ["admin"],
      "auth_provider": "local",
      "disabled": false,
      "created_at": "2024-01-01T00:00:00Z",
      "last_login": "2024-01-15T10:30:00Z"
    }
  ]
}

POST /api/v1/users

Create user.

Request:

{
  "username": "newuser",
  "password": "password123",
  "email": "user@example.com",
  "roles": ["operator"]
}

GET /api/v1/users/:id

Get user details.

PUT /api/v1/users/:id

Update user.

Request:

{
  "email": "newemail@example.com",
  "roles": ["operator", "viewer"]
}

DELETE /api/v1/users/:id

Disable user (soft delete).

PUT /api/v1/users/:id/password

Reset user password.

Request:

{
  "new_password": "temporary-password"
}

Roles

GET /api/v1/roles

List all roles.

Response:

{
  "roles": [
    {
      "id": "admin",
      "name": "Administrator",
      "description": "Full system access",
      "permissions": ["*"],
      "is_system": true
    }
  ]
}

POST /api/v1/roles

Create custom role.

Request:

{
  "name": "Alert Manager",
  "description": "Can manage alerts only",
  "permissions": ["dashboard:view", "alerts:*"]
}

PUT /api/v1/roles/:id

Update role.

DELETE /api/v1/roles/:id

Delete custom role (system roles cannot be deleted).


Logs

GET /api/v1/logs

Query logs.

Query Parameters:

Parameter Type Description
agent_id string Filter by agent
source string Filter by source (journal, file, docker)
source_name string Filter by source name
level string Comma-separated levels
q string Full-text search
from string Start time (ISO 8601)
to string End time (ISO 8601)
limit int Max results (default 100)
offset int Pagination offset

Response:

{
  "entries": [
    {
      "id": "log-1",
      "timestamp": "2024-01-15T10:30:00Z",
      "agent_id": "web-server-01",
      "source": "journal",
      "source_name": "nginx.service",
      "level": "error",
      "message": "Connection refused",
      "fields": {"pid": "1234"}
    }
  ],
  "total": 150
}

GET /api/v1/logs/stream

SSE stream of live logs.

Query Parameters: Same as /api/v1/logs


Settings

POST /api/v1/settings/refresh

Update refresh interval.

Request:

{
  "interval": 5
}

Error Responses

All errors follow this format:

{
  "error": "Error message",
  "code": "ERROR_CODE",
  "details": {}
}

HTTP Status Codes:

Code Description
400 Bad Request - Invalid input
401 Unauthorized - Missing/invalid token
403 Forbidden - Insufficient permissions
404 Not Found - Resource doesn't exist
500 Internal Server Error