Maksim Totmin f20d5aa0e2 docs: restructure documentation into docs/ directory
- Create docs/ with 7 focused files: architecture, api, scoring, agent,
  deployment, freeswitch, development
- Rewrite README.md as concise overview with links to docs/
- Remove AGENTS.md (content merged into docs/ and README)
2026-06-25 22:35:19 +07:00

4.1 KiB
Raw Blame History

API Reference

Authentication

Method Path Auth Description
POST /api/auth/login Login: {"username":"admin","password":"admin"}access_token + refresh_token
POST /api/auth/refresh Refresh access token using refresh_token

All endpoints except /api/route, /api/health/*, /api/monitoring/* require Authorization: Bearer <jwt>.

Roles: admin (full access), viewer (read-only nodes/metrics).

Core

Method Path Auth Description
GET /api/route Route a call. Query: caller_id, dest, ingress_trunk
GET /api/health Stats: total nodes, healthy, requests, uptime
GET /api/health/live Liveness probe (always 200)
GET /api/health/ready Readiness probe (NATS + metrics)

Route Response (success)

{ "node_id": "pbx-03", "score": 88, "sip_gateway": "sip:pbx03.lan:5060" }

Route Response (fallback — all nodes unhealthy)

{
  "fallback": true,
  "sip_gateway": "sip:operator.lan:5060",
  "reason": "all_nodes_unhealthy",
  "nodes": [...]
}

Route Response (no nodes registered)

{ "error": "no_nodes_registered" }

Nodes

Method Path Role Description
GET /api/nodes admin/viewer List all nodes with scores and state
GET /api/nodes/{id}/metrics admin/viewer Metrics history (ring buffer, ~30 min)
PUT /api/nodes/{id}/toggle admin {"disabled":true, "reason":"..."}

Trunks

Method Path Role Description
GET /api/trunks admin All trunks. Query: type=ingress|balance|fallback
POST /api/trunks admin Create trunk
PUT /api/trunks/{id} admin Update trunk
DELETE /api/trunks/{id} admin Delete trunk

Trunk model:

{
  "id": "trk-001",
  "name": "pbx-03 balance",
  "type": "ingress|balance|fallback",
  "node_id": "pbx-03",
  "gateway": "sip:pbx03.lan:5060",
  "codecs": ["PCMU", "PCMA"],
  "context": "default",
  "enabled": true,
  "description": "",
  "created_at": "...",
  "updated_at": "..."
}

Trunk types:

Type Purpose Quantity
ingress Incoming trunk (where calls come from) 1..N
balance Destination trunk (bound to a Node) 1..N
fallback Operator fallback (when all balance score < 0) exactly 1

Users (admin only)

Method Path Description
GET /api/users List users
POST /api/users Create user
PUT /api/users/{id} Update user
DELETE /api/users/{id} Delete user

Note: user-01 (primary admin) cannot be deleted or demoted to viewer.

Monitoring (API-key auth)

Use X-API-Key header (not JWT).

Method Path Description
GET /api/monitoring/zabbix JSON for Zabbix LLD + items
GET /api/monitoring/prometheus text/plain metrics for Prometheus

WebSocket

Method Path Description
WS /ws/metrics Real-time metrics stream for frontend (JWT in query ?token=)

Examples

# Route (no auth)
curl 'http://localhost:8080/api/route?caller_id=74951234567&dest=123&ingress_trunk=trk-001'
# → {"node_id":"pbx-03","score":88,"sip_gateway":"sip:pbx03.lan:5060"}

# Login
TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}' | jq -r '.access_token')

# Nodes with JWT
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/nodes

# Toggle node (admin only)
curl -X PUT http://localhost:8080/api/nodes/pbx-01/toggle \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"disabled":true,"reason":"maintenance"}'

# Prometheus metrics (API-key)
curl -H "X-API-Key: $(jq -r '.monitoring_api_key' data/config.json)" \
  http://localhost:8080/api/monitoring/prometheus