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

656 lines
10 KiB
Markdown

# API Reference
Complete reference for the Tyto REST API.
## Base URL
```
http://localhost:8080/api/v1
```
## Authentication
Most endpoints require authentication via Bearer token:
```bash
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/v1/...
```
### Obtain Token
```bash
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "password"}'
```
Response:
```json
{
"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**:
```json
{
"status": "ok",
"version": "1.0.0",
"uptime": 3600
}
```
---
## Authentication
### POST /api/v1/auth/login
Authenticate and obtain session token.
**Request**:
```json
{
"username": "admin",
"password": "password"
}
```
**Response**:
```json
{
"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**:
```json
{
"username": "newuser",
"password": "password123",
"email": "user@example.com"
}
```
### GET /api/v1/auth/me
Get current user info.
**Response**:
```json
{
"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**:
```json
{
"email": "newemail@example.com"
}
```
### PUT /api/v1/auth/me/password
Change password.
**Request**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"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**:
```json
{
"new_password": "temporary-password"
}
```
---
## Roles
### GET /api/v1/roles
List all roles.
**Response**:
```json
{
"roles": [
{
"id": "admin",
"name": "Administrator",
"description": "Full system access",
"permissions": ["*"],
"is_system": true
}
]
}
```
### POST /api/v1/roles
Create custom role.
**Request**:
```json
{
"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**:
```json
{
"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**:
```json
{
"interval": 5
}
```
---
## Error Responses
All errors follow this format:
```json
{
"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 |