{"service": "meshcore-api", "database": "postgresql://meshcore_ro@postgres:5432/meshcore", "routes": [{"path": "/api/health", "description": "liveness and archive freshness"}, {"path": "/api/stats", "description": "archive-wide counters and coverage"}, {"path": "/api/types", "description": "payload types with packet counts"}, {"path": "/api/packets", "query": "type, since, until, channel, observer, decrypted, min_observations, limit, offset, order", "description": "filter and paginate packets"}, {"path": "/api/packets/{hash}", "description": "one packet with its observations"}, {"path": "/api/observations", "query": "packet, observer, since, until, limit, offset", "description": "filter and paginate observations"}, {"path": "/api/nodes", "query": "role, name, active_since, relaying, has_position, limit, offset, order", "description": "mesh nodes snapshotted from upstream"}, {"path": "/api/nodes/{public_key}", "description": "one node with its change history"}, {"path": "/api/repeaters", "query": "same as /api/nodes, role forced to 'repeater'", "description": "relaying nodes"}, {"path": "/api/observers", "query": "iata, name, limit, offset, order", "description": "receiving stations"}, {"path": "/api/observers/{id}", "description": "one observer with its change history"}, {"path": "/api/channels", "query": "name, limit, offset, order", "description": "channels seen upstream"}, {"path": "/api/channels/{hash}", "description": "one channel with recent traffic"}, {"path": "/api/coverage", "query": "type, gap", "description": "per-type coverage and archive gaps"}, {"path": "/docs", "description": "Swagger UI over the description below"}, {"path": "/openapi.json", "description": "OpenAPI 3.0 description of this API"}], "notes": {"type": "accepts a number (6) or a name (GRP_DATA); an unknown name is a 400, never a silent fallback to type 0", "times": "ISO8601 or a relative age (15m, 24h, 7d); `since` inclusive, `until` exclusive", "paging": "limit defaults to 100, caps at 1000"}, "took_ms": 0.1}