{
  "openapi": "3.1.0",
  "info": {
    "title": "codeDB API",
    "summary": "Monitoramento de SQL Server e PostgreSQL: instâncias, incidentes e causa raiz.",
    "description": "API pública do **codeDB**, plataforma SaaS de monitoramento de SQL Server e PostgreSQL.\n\n**Quando usar:** listar instâncias monitoradas de um cliente e investigar incidentes (lentidão,\nbloqueios, queda de health score) com causa raiz e evidências. Somente leitura.\n\n**Autenticação:** crie uma API Key em Dashboard → Configurações → API Keys (planos Trial e\nBusiness; trial de 7 dias sem cartão). Envie como `X-API-Key: cdb_v1_…` ou\n`Authorization: Bearer cdb_v1_…`, ou troque por um access token de 60 min em\n`POST /oauth/token` (OAuth 2.0 client_credentials).\n\n**MCP:** `POST /mcp` (Streamable HTTP) expõe as mesmas consultas como ferramentas; `initialize` e\n`tools/list` não exigem credencial.\n\n**Rate limit:** 120 req/min por IP em `/api/v1/*` e `/mcp`. Toda resposta traz `RateLimit-Policy`,\n`RateLimit` (draft IETF httpapi-ratelimit-headers) e `X-RateLimit-*`; o 429 traz `Retry-After` (s).\n\n**Versionamento:** versão na URL (`/api/v1`); mudanças incompatíveis só numa nova versão. Descontinuação\né sinalizada com os headers `Deprecation` (RFC 9745) e `Sunset` (RFC 8594), com no mínimo 6 meses de\naviso: https://app.codedb.com.br/docs/api#versionamento\n\n**Erros:** JSON com `error.code`, `error.message`, `error.hint` e `error.docs`.\n\nDocumentação: https://app.codedb.com.br/docs/api\n",
    "termsOfService": "https://app.codedb.com.br/termos",
    "contact": {
      "name": "codeDB",
      "url": "https://app.codedb.com.br/contato"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.codedb.com.br",
      "description": "Produção"
    }
  ],
  "paths": {
    "/api/v1/incidents": {
      "get": {
        "tags": [
          "public-api"
        ],
        "summary": "Listar incidentes",
        "description": "Lista os incidentes detectados e classificados (início/fim, health score mínimo,\ncausa raiz com evidências), do mais recente para o mais antigo, até 200 por chamada.\nRequer escopo `incidents:read`.",
        "operationId": "listIncidents",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 90,
              "minimum": 1,
              "description": "Janela em dias (1-90).",
              "default": 7,
              "title": "Days"
            },
            "description": "Janela em dias (1-90)."
          },
          {
            "name": "instance_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filtra por instância.",
              "title": "Instance Id"
            },
            "description": "Filtra por instância."
          },
          {
            "name": "environment_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filtra por ambiente (todas as instâncias dele).",
              "title": "Environment Id"
            },
            "description": "Filtra por ambiente (todas as instâncias dele)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IncidentList"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "description": "Credencial ausente, inválida ou expirada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "403": {
            "description": "Escopo, plano ou assinatura sem acesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "422": {
            "description": "Parâmetro inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "429": {
            "description": "Limite de requisições excedido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Segundos a esperar antes de tentar de novo.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          },
          {
            "OAuth2": [
              "incidents:read"
            ]
          }
        ]
      }
    },
    "/api/v1/instances": {
      "get": {
        "tags": [
          "public-api"
        ],
        "summary": "Listar instâncias monitoradas",
        "description": "Lista as instâncias SQL Server/PostgreSQL ativas do tenant, com engine, ambiente\ne último contato do agente. Requer escopo `instances:read`.",
        "operationId": "listInstances",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstanceList"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "description": "Credencial ausente, inválida ou expirada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "403": {
            "description": "Escopo, plano ou assinatura sem acesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "429": {
            "description": "Limite de requisições excedido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Segundos a esperar antes de tentar de novo.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          },
          {
            "OAuth2": [
              "instances:read"
            ]
          }
        ]
      }
    },
    "/oauth/token": {
      "post": {
        "tags": [
          "oauth"
        ],
        "summary": "Emitir access token (client_credentials)",
        "description": "Troca uma API Key do codeDB por um access token Bearer de curta duração (1 h),\nno fluxo OAuth 2.0 client_credentials. Autenticação do cliente por\n`client_secret_post` (campos do formulário) ou `client_secret_basic` (HTTP Basic).\nRevogar a API Key no portal invalida os tokens já emitidos.",
        "operationId": "createAccessToken",
        "parameters": [
          {
            "name": "authorization",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Alternativa: HTTP Basic com client_id:client_secret.",
              "title": "Authorization"
            },
            "description": "Alternativa: HTTP Basic com client_id:client_secret."
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Body_createAccessToken"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Requisição, grant ou escopo inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "401": {
            "description": "Credenciais do cliente inválidas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "429": {
            "description": "Limite de requisições excedido."
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "tags": [
          "mcp"
        ],
        "summary": "Servidor MCP (Streamable HTTP)",
        "description": "Endpoint MCP para agentes (Claude, ChatGPT, Cursor…): JSON-RPC 2.0 com `initialize`,\n`ping`, `tools/list` e `tools/call`. Ferramentas read-only `list_incidents` e\n`list_instances`. `initialize`, `ping` e `tools/list` não exigem credencial; `tools/call` exige\n`Authorization: Bearer <API Key ou access token>`.",
        "operationId": "mcpMessage",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "jsonrpc": {
                    "const": "2.0"
                  },
                  "id": {
                    "type": [
                      "string",
                      "integer"
                    ],
                    "description": "Ausente em notificações."
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "ping",
                      "tools/list",
                      "tools/call",
                      "notifications/initialized"
                    ]
                  },
                  "params": {
                    "type": "object"
                  }
                },
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "example": {
                  "jsonrpc": "2.0",
                  "id": 1,
                  "method": "tools/call",
                  "params": {
                    "name": "list_incidents",
                    "arguments": {
                      "days": 1
                    }
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Resposta JSON-RPC 2.0 (result ou error).",
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "202": {
            "description": "Notificação aceita (sem corpo).",
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido ou versão de protocolo não suportada.",
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "description": "Credencial ausente, inválida ou expirada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "403": {
            "description": "Escopo, plano ou assinatura sem acesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "429": {
            "description": "Limite de requisições excedido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Segundos a esperar antes de tentar de novo.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "description": "Cota e janela: \"default\";q=120;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Saldo e segundos até zerar: \"default\";r=87;t=23.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Segundos até a janela zerar.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          },
          {
            "OAuth2": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Body_createAccessToken": {
        "properties": {
          "grant_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Grant Type",
            "description": "Sempre `client_credentials`."
          },
          "client_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Id",
            "description": "Prefixo da API Key (ex.: cdb_v1_1a2b3c4)."
          },
          "client_secret": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Secret",
            "description": "API Key completa (cdb_v1_…)."
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scope",
            "description": "Subconjunto dos escopos da API Key, separados por espaço. Omitido = todos."
          }
        },
        "type": "object",
        "title": "Body_createAccessToken"
      },
      "ErrorInfo": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Código estável do erro (ex.: unauthorized, forbidden, not_found)."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "Mensagem legível."
          },
          "hint": {
            "type": "string",
            "title": "Hint",
            "description": "Como resolver."
          },
          "docs": {
            "type": "string",
            "title": "Docs",
            "description": "URL da documentação."
          }
        },
        "type": "object",
        "required": [
          "code",
          "message",
          "hint",
          "docs"
        ],
        "title": "ErrorInfo"
      },
      "ErrorResponse": {
        "properties": {
          "detail": {
            "title": "Detail",
            "description": "Mensagem original (string, objeto ou lista de validação)."
          },
          "error": {
            "$ref": "#/components/schemas/ErrorInfo"
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "ErrorResponse"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "Incident": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "instance_id": {
            "type": "string",
            "title": "Instance Id"
          },
          "instance_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Instance Name"
          },
          "server_host": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Server Host"
          },
          "started_at": {
            "type": "string",
            "title": "Started At",
            "description": "ISO 8601 (UTC)."
          },
          "resolved_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolved At",
            "description": "ISO 8601 (UTC); null se ainda aberto."
          },
          "duration_minutes": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Duration Minutes"
          },
          "trigger_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Trigger Type"
          },
          "min_health_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Health Score",
            "description": "Menor health score (0-100) durante o incidente."
          },
          "max_health_drop": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Health Drop"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "event_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Event Count"
          },
          "retention_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retention Days"
          },
          "detail_available": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Detail Available"
          },
          "root_cause": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Root Cause",
            "description": "Causa raiz classificada (tipo, rótulo, confiança, evidências)."
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "id",
          "instance_id",
          "started_at"
        ],
        "title": "Incident"
      },
      "IncidentList": {
        "properties": {
          "incidents": {
            "items": {
              "$ref": "#/components/schemas/Incident"
            },
            "type": "array",
            "title": "Incidents"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "period_days": {
            "type": "integer",
            "title": "Period Days"
          }
        },
        "type": "object",
        "required": [
          "incidents",
          "total",
          "period_days"
        ],
        "title": "IncidentList"
      },
      "InstanceItem": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "server_host": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Server Host"
          },
          "environment_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Environment Id"
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active"
          },
          "db_engine": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Db Engine",
            "description": "sqlserver ou postgres."
          },
          "agent_last_seen": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Last Seen",
            "description": "Último contato do agente (ISO 8601)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "is_active"
        ],
        "title": "InstanceItem"
      },
      "InstanceList": {
        "properties": {
          "instances": {
            "items": {
              "$ref": "#/components/schemas/InstanceItem"
            },
            "type": "array",
            "title": "Instances"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "instances",
          "total"
        ],
        "title": "InstanceList"
      },
      "OAuthError": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error",
            "description": "invalid_request, invalid_client, unsupported_grant_type, invalid_scope ou unauthorized_client."
          },
          "error_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error Description"
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "OAuthError"
      },
      "TokenResponse": {
        "properties": {
          "access_token": {
            "type": "string",
            "title": "Access Token",
            "description": "Use como Authorization: Bearer <access_token> na API v1 e no MCP."
          },
          "token_type": {
            "type": "string",
            "title": "Token Type",
            "default": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "title": "Expires In",
            "description": "Validade em segundos."
          },
          "scope": {
            "type": "string",
            "title": "Scope",
            "description": "Escopos concedidos, separados por espaço."
          }
        },
        "type": "object",
        "required": [
          "access_token",
          "expires_in",
          "scope"
        ],
        "title": "TokenResponse"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API Key cdb_v1_… criada no portal."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API Key ou access token de POST /oauth/token."
      },
      "OAuth2": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://api.codedb.com.br/oauth/token",
            "scopes": {
              "incidents:read": "Ler incidentes e causa raiz.",
              "instances:read": "Ler o inventário de instâncias monitoradas."
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "public-api",
      "description": "Consultas read-only da API v1."
    },
    {
      "name": "oauth",
      "description": "Emissão de access token (client_credentials)."
    },
    {
      "name": "mcp",
      "description": "Servidor Model Context Protocol."
    }
  ],
  "externalDocs": {
    "description": "Documentação da API",
    "url": "https://app.codedb.com.br/docs/api"
  }
}
