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>
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 |