{
  "openapi": "3.0.3",
  "info": {
    "title": "Pingvera API",
    "version": "1.0.0",
    "description": "Pingvera monitoring public API (read-only). Authentication — API token (created in the dashboard: Settings → API tokens) in the Authorization: Bearer pv_... header. Each endpoint requires its own token scope. The organization is determined by the token. For LLM assistants there is an MCP server: POST /mcp (JSON-RPC 2.0, same Bearer token, scope read:monitoring)."
  },
  "servers": [{"url": "https://app.pingvera.com"}],
  "components": {
    "securitySchemes": {
      "apiToken": {"type": "http", "scheme": "bearer", "description": "API token pv_*; scopes: read:metrics, read:hosts, read:monitoring"}
    }
  },
  "security": [{"apiToken": []}],
  "paths": {
    "/api/v1/monitors": {
      "get": {
        "summary": "List of checks (monitors)",
        "description": "Scope read:monitoring. All of the organization's checks with type, target and current status.",
        "responses": {"200": {"description": "OK — {monitors: [...]}"}, "401": {"description": "missing/invalid token"}, "403": {"description": "missing read:monitoring scope"}}
      }
    },
    "/api/v1/incidents": {
      "get": {
        "summary": "Monitoring events (incidents)",
        "description": "Scope read:monitoring. Open and closed events: what broke, when, when it recovered.",
        "parameters": [{"name": "status", "in": "query", "schema": {"type": "string", "enum": ["open", "resolved"]}, "description": "status filter; empty = all"}],
        "responses": {"200": {"description": "OK — {incidents: [...]}"}, "401": {"description": "missing/invalid token"}, "403": {"description": "missing scope"}}
      }
    },
    "/api/v1/hosts": {
      "get": {
        "summary": "Servers with an agent",
        "description": "Scope read:hosts. Server fleet: name, OS, online/offline, metadata.",
        "responses": {"200": {"description": "OK — {hosts: [...]}"}, "401": {"description": "missing/invalid token"}, "403": {"description": "missing read:hosts scope"}}
      }
    },
    "/api/v1/metrics/query": {
      "get": {
        "summary": "Server metrics (time series)",
        "description": "Scope read:metrics. Aggregated host metrics series (avg per interval).",
        "parameters": [
          {"name": "host", "in": "query", "required": true, "schema": {"type": "string"}, "description": "host public_id (see /api/v1/hosts)"},
          {"name": "from", "in": "query", "schema": {"type": "integer"}, "description": "unix seconds, default: one hour ago"},
          {"name": "to", "in": "query", "schema": {"type": "integer"}, "description": "unix seconds, default: now"},
          {"name": "step", "in": "query", "schema": {"type": "integer"}, "description": "aggregation step, sec (default 60)"},
          {"name": "metrics", "in": "query", "schema": {"type": "string"}, "description": "comma-separated list: cpu_pct, mem_used_pct, disk_used_pct, net_in_bps, net_out_bps, etc."}
        ],
        "responses": {"200": {"description": "OK — columnar JSON {t: [...], cpu_pct: [...]}"}, "401": {"description": "missing/invalid token"}, "403": {"description": "missing read:metrics scope"}}
      }
    },
    "/mcp": {
      "post": {
        "summary": "MCP server (Model Context Protocol)",
        "description": "Scope read:monitoring. JSON-RPC 2.0 (initialize / tools/list / tools/call). Tools: list_monitors, list_incidents, list_hosts, uptime_summary. Connecting in Claude Code: claude mcp add --transport http pingvera https://app.pingvera.com/mcp --header \"Authorization: Bearer pv_...\"",
        "responses": {"200": {"description": "JSON-RPC response"}, "401": {"description": "missing/invalid token"}, "403": {"description": "missing read:monitoring scope"}}
      }
    }
  }
}