{"openapi":"3.1.0","info":{"title":"FlipperHub API para agentes","version":"1.0.0","summary":"Superfície pública do FlipperHub para assistentes de IA: servidor MCP remoto, Authorization Server OAuth 2.1 e descoberta.","description":"Este documento descreve APENAS a superfície que um agente externo alcança: o\nservidor MCP remoto (`POST /mcp`), o Authorization Server OAuth 2.1 que o protege\ne os endpoints de descoberta e saúde. A API REST interna do aplicativo (funil,\nfinanceiro, garimpo, conversas) NÃO faz parte deste contrato: ela exige sessão de\nusuário e contexto de tenant, e não é oferecida a integradores.\n\n**Como conectar**\n\n1. **claude.ai (conector remoto):** cole `https://api.flipperhub.com.br/mcp` como URL do servidor MCP.\n   O cliente registra-se sozinho em `POST /register` (RFC 7591), manda o usuário\n   para `GET /authorize`, o usuário aprova os escopos na tela de consentimento do\n   FlipperHub e o cliente troca o código em `POST /token`. Sem colar chave nenhuma.\n2. **Claude Code, Cursor, scripts:** crie um token pessoal em Configurações >\n   Conexões de IA e mande `Authorization: Bearer fh_mcp_...` no `POST /mcp`.\n\n**Audience (RFC 8707)**\n\nO recurso protegido é `https://api.flipperhub.com.br/mcp`. O parâmetro `resource` do fluxo OAuth, quando\nenviado, precisa ser exatamente esse valor: token emitido para outro público é\nrecusado (sem token passthrough).\n\n**Escopos**\n\n`read` está sempre incluso; os escopos de escrita são opt-in, marcados um a um pelo\nusuário no consentimento, e valem para o token inteiro (não dá para ampliar depois\nsem novo consentimento).\n\n**Tenant e identidade**\n\nA conta e o usuário vêm SEMPRE do token, nunca de cabeçalho ou argumento de tool.\nUm token só enxerga os dados da conta em que foi criado.\n\n**Versionamento e depreciação**\n\nA versão do contrato é `info.version` (semver): mudança incompatível (remover campo ou\noperação, apertar formato, mudar semântica) sobe a MAJOR; adição retrocompatível sobe a\nMINOR. A extensão `x-api-versioning`, na raiz do documento, traz essa política em forma\nlegível por máquina.\n\nAntes de aposentar uma operação, ela passa por um período de transição sinalizado nas\nrespostas pelos cabeçalhos `Deprecation` (a data em que a depreciação começou) e `Sunset`\n(RFC 8594, a data em que a operação deixa de responder). O intervalo entre os dois é o\nprazo mínimo de migração. Enquanto uma operação é corrente, esses cabeçalhos não são\nemitidos. O aviso também sai pelo contato em `info.contact` e por este documento, que\nreflete sempre a versão no ar.\n\n**Limites de requisição**\n\nAs respostas trazem os cabeçalhos padrão `RateLimit-Limit`, `RateLimit-Remaining` e\n`RateLimit-Reset` (segundos até reiniciar) da janela mais restritiva aplicável, e\n`Retry-After` (segundos) na resposta 429. Os endpoints OAuth (`/register`, `/authorize`,\n`/token`, `/revoke`) têm limites próprios por IP, descritos em cada operação. Os endpoints\nservidos pela aplicação (`/health`, `/version`) ainda emitem, por compatibilidade, os\ncabeçalhos legados `X-RateLimit-Limit-<janela>` (`long` e `short` por IP, `user-long` e\n`user-burst` por usuário). O limite do `POST /mcp` é imposto na borda (Cloudflare), cuja\nresposta 429 traz `Retry-After`.","termsOfService":"https://app.flipperhub.com.br/legal/termos","contact":{"name":"FlipperHub","url":"https://flipperhub.com.br"},"x-privacy-policy":"https://app.flipperhub.com.br/legal/privacidade","x-build":{"commitSha":"6851c9ef3b4e9d91c18b6512871c76dfdc47781d"}},"x-api-versioning":{"scheme":"semver","currentVersion":"1.0.0","policy":"Mudança incompatível sobe a MAJOR de info.version; adição retrocompatível sobe a MINOR.","deprecation":{"signalHeaders":["Deprecation","Sunset"],"specifications":["RFC 8594"],"minimumNoticeDays":90},"noticeChannels":{"responseHeaders":"Cabeçalhos Deprecation e Sunset nas respostas das operações afetadas.","document":"https://api.flipperhub.com.br/openapi.json","contact":"https://flipperhub.com.br"}},"externalDocs":{"description":"Guia para agentes e LLMs (llms.txt)","url":"https://flipperhub.com.br/llms.txt"},"servers":[{"url":"https://api.flipperhub.com.br","description":"API pública (borda Cloudflare)"}],"tags":[{"name":"mcp","description":"Servidor MCP remoto (Streamable HTTP, stateless). É por aqui que o agente lista e chama as tools."},{"name":"oauth","description":"Authorization Server OAuth 2.1 próprio: registro dinâmico, autorização com PKCE, emissão, renovação e revogação de token."},{"name":"descoberta","description":"Metadados legíveis por máquina: RFC 9728 (recurso protegido), RFC 8414 (authorization server) e este próprio documento."},{"name":"saude","description":"Sinal de vida e identidade do build implantado."}],"components":{"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth 2.1 com PKCE S256 obrigatório (o método `plain` é recusado).\n\nO cliente pode registrar-se sozinho em `POST /register` (RFC 7591): é um\npublic client, sem segredo, com `token_endpoint_auth_method: \"none\"`.\nO `redirect_uri` é restrito aos endereços oficiais do Claude (https://claude.ai/api/mcp/auth_callback, https://claude.com/api/mcp/auth_callback); qualquer outro é recusado já no registro.\n\nO parâmetro `resource` (RFC 8707) precisa ser `https://api.flipperhub.com.br/mcp`.\nO access token vale 3600 segundos; o refresh token é rotacionado a\ncada uso, e reapresentar um refresh já rotacionado revoga a família inteira.","flows":{"authorizationCode":{"authorizationUrl":"https://api.flipperhub.com.br/authorize","tokenUrl":"https://api.flipperhub.com.br/token","refreshUrl":"https://api.flipperhub.com.br/token","scopes":{"read":"Ver seus contatos, empresas, oportunidades, tarefas e notas da conta ativa. Sempre incluso.","write:tarefas":"Criar tarefas.","write:notas":"Criar notas em contatos, empresas e oportunidades.","write:contatos":"Criar contatos (pessoas) no CRM."}}}},"mcpToken":{"type":"http","scheme":"bearer","bearerFormat":"fh_mcp_<token>","description":"Token pessoal (PAT), criado pelo próprio usuário em Configurações > Conexões\nde IA. O valor aparece uma única vez na criação; o servidor guarda só o hash.\n\nOs escopos são fixados na criação do token e não mudam depois: para liberar\numa escrita nova, crie um token novo. `read` está sempre incluso.\n\nÉ a forma indicada para clientes que mandam cabeçalho (Claude Code, Cursor,\nscripts). Clientes de navegador usam o fluxo OAuth."}},"schemas":{"JsonRpcRequest":{"type":"object","description":"Mensagem JSON-RPC 2.0 do protocolo MCP. Os métodos são os do MCP (`initialize`, `tools/list`, `tools/call`), não endpoints REST.","required":["jsonrpc","method"],"properties":{"jsonrpc":{"const":"2.0","description":"Versão do JSON-RPC. Sempre `2.0`."},"id":{"type":["string","integer"],"description":"Correlaciona pedido e resposta. Ausente = notificação (o servidor responde 202 sem corpo).","examples":[1]},"method":{"type":"string","description":"Método MCP.","examples":["initialize","tools/list","tools/call"]},"params":{"type":"object","additionalProperties":true,"description":"Parâmetros do método. Em `tools/call`: `{ name, arguments }`, com o `arguments` validado contra o schema publicado da tool no `tools/list`."}},"additionalProperties":true},"JsonRpcError":{"type":"object","description":"Erro JSON-RPC 2.0. É o corpo de toda falha do `/mcp`, inclusive das que chegam com status HTTP 4xx ou 5xx.","required":["jsonrpc","error","id"],"properties":{"jsonrpc":{"const":"2.0"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","description":"Código JSON-RPC. `-32001` = não autenticado, `-32002` = recurso não habilitado no plano, `-32603` = erro interno, `-32700` = JSON inválido.","examples":[-32001]},"message":{"type":"string","description":"Mensagem legível, em português, sem stack trace."},"data":{"type":"object","additionalProperties":true,"description":"Detalhe estruturado quando existe. No 403 de plano traz `code`, `featureKey`, `currentPlan` e `upgradeUrl`."}}},"id":{"type":["string","integer","null"],"description":"Eco do `id` do pedido. Nos erros de transporte sai `null`."}}},"ProtectedResourceMetadata":{"type":"object","description":"Metadados do recurso protegido (RFC 9728).","required":["resource","authorization_servers","scopes_supported","resource_name"],"properties":{"resource":{"type":"string","format":"uri","description":"Identificador do recurso protegido (o audience do token).","examples":["https://api.flipperhub.com.br/mcp"]},"authorization_servers":{"type":"array","items":{"type":"string","format":"uri"},"description":"Authorization Servers que emitem token para este recurso.","examples":[["https://api.flipperhub.com.br/"]]},"scopes_supported":{"type":"array","items":{"type":"string","enum":["read","write:tarefas","write:notas","write:contatos"]},"description":"Escopos que este recurso reconhece.","examples":[["read","write:tarefas","write:notas","write:contatos"]]},"resource_name":{"const":"FlipperHub MCP","description":"Nome legível do recurso, exibido pelo cliente ao usuário."}}},"AuthorizationServerMetadata":{"type":"object","description":"Metadados do Authorization Server (RFC 8414), emitidos pelo SDK do MCP a partir da configuração real do servidor.","required":["issuer","authorization_endpoint","token_endpoint","response_types_supported","code_challenge_methods_supported","grant_types_supported","token_endpoint_auth_methods_supported","scopes_supported","registration_endpoint","revocation_endpoint"],"properties":{"issuer":{"type":"string","format":"uri","examples":["https://api.flipperhub.com.br/"]},"authorization_endpoint":{"type":"string","format":"uri","examples":["https://api.flipperhub.com.br/authorize"]},"token_endpoint":{"type":"string","format":"uri","examples":["https://api.flipperhub.com.br/token"]},"registration_endpoint":{"type":"string","format":"uri","description":"Registro dinâmico de cliente (RFC 7591).","examples":["https://api.flipperhub.com.br/register"]},"revocation_endpoint":{"type":"string","format":"uri","description":"Revogação de token (RFC 7009).","examples":["https://api.flipperhub.com.br/revoke"]},"response_types_supported":{"type":"array","items":{"type":"string"},"const":["code"],"description":"Só o fluxo de código de autorização."},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"},"const":["S256"],"description":"PKCE S256 obrigatório."},"grant_types_supported":{"type":"array","items":{"type":"string"},"const":["authorization_code","refresh_token"]},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"},"const":["client_secret_post","none"],"description":"O cliente registrado por DCR é sempre public client (`none`) e usa PKCE."},"revocation_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"},"const":["client_secret_post"]},"scopes_supported":{"type":"array","items":{"type":"string","enum":["read","write:tarefas","write:notas","write:contatos"]},"examples":[["read","write:tarefas","write:notas","write:contatos"]]}}},"ClientRegistrationRequest":{"type":"object","description":"Metadados de registro dinâmico (RFC 7591). Campos fora desta lista são aceitos e descartados em silêncio pelo servidor.","required":["redirect_uris"],"properties":{"redirect_uris":{"type":"array","minItems":1,"items":{"type":"string","format":"uri"},"description":"Obrigatório. Cada URI é validada contra a allowlist oficial do Claude (https://claude.ai/api/mcp/auth_callback, https://claude.com/api/mcp/auth_callback); qualquer outra recusa o registro.","examples":[["https://claude.ai/api/mcp/auth_callback"]]},"client_name":{"type":"string","description":"Nome do cliente, exibido ao usuário na tela de consentimento.","examples":["Claude"]},"grant_types":{"type":"array","items":{"type":"string"},"description":"Padrão quando ausente: `authorization_code` e `refresh_token`."},"response_types":{"type":"array","items":{"type":"string"},"description":"Padrão quando ausente: `code`."},"scope":{"type":"string","description":"Escopos pretendidos, separados por espaço.","examples":["read write:tarefas write:notas write:contatos"]},"token_endpoint_auth_method":{"type":"string","description":"Ignorado: o servidor grava sempre `none` (public client com PKCE), qualquer que seja o valor enviado."}},"additionalProperties":true},"ClientInformation":{"type":"object","description":"Cliente registrado (RFC 7591). Public client: nunca há segredo.","required":["client_id","redirect_uris","token_endpoint_auth_method"],"properties":{"client_id":{"type":"string","description":"Identificador gerado pelo servidor."},"client_id_issued_at":{"type":"integer","description":"Emissão do `client_id`, em segundos desde a época Unix."},"redirect_uris":{"type":"array","items":{"type":"string","format":"uri"}},"client_name":{"type":"string"},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"scope":{"type":"string"},"token_endpoint_auth_method":{"const":"none","description":"Sempre `none`: o cliente autentica pelo PKCE, não por segredo."}}},"TokenResponse":{"type":"object","description":"Par de tokens emitido pelo `/token`.","required":["access_token","token_type","expires_in","refresh_token","scope"],"properties":{"access_token":{"type":"string","description":"Token de acesso, com o mesmo prefixo do token pessoal (`fh_mcp_`). Vai no cabeçalho `Authorization: Bearer` do `POST /mcp`."},"token_type":{"const":"Bearer"},"expires_in":{"type":"integer","description":"Validade do access token, em segundos.","const":3600},"refresh_token":{"type":"string","description":"Prefixo `fh_mcpr_`. Rotacionado a cada uso: guarde sempre o mais recente."},"scope":{"type":"string","description":"Escopos concedidos, separados por espaço.","examples":["read","read write:tarefas write:notas write:contatos"]}}},"OAuthError":{"type":"object","description":"Erro OAuth 2.1 (RFC 6749 §5.2).","required":["error"],"properties":{"error":{"type":"string","description":"Código do erro.","examples":["invalid_request","invalid_grant","invalid_client_metadata"]},"error_description":{"type":"string","description":"Detalhe legível, em português."},"error_uri":{"type":"string","format":"uri"}}},"Health":{"type":"object","required":["status","timestamp","uptime"],"properties":{"status":{"const":"ok"},"timestamp":{"type":"string","format":"date-time","description":"Instante da resposta, em UTC."},"uptime":{"type":"number","description":"Segundos desde o start do processo.","examples":[1234.56]}}},"Version":{"type":"object","description":"Identidade do build implantado (usado no smoke pós-deploy).","required":["commitSha","buildId","buildTime","nodeEnv"],"properties":{"commitSha":{"type":"string","description":"SHA do commit implantado, ou `unknown` fora de deploy."},"buildId":{"type":"string","description":"Identificador do build, ou `local`."},"buildTime":{"type":["string","null"],"description":"Instante do build, quando a esteira informa."},"nodeEnv":{"type":"string","description":"Ambiente do processo.","examples":["production","staging","development"]}}},"McpEventStream":{"type":"string","description":"Stream SSE (`text/event-stream`) da resposta 200 do `POST /mcp`. Cada evento carrega uma mensagem JSON-RPC 2.0 no campo `data`."},"TokenRequest":{"type":"object","description":"Corpo `application/x-www-form-urlencoded` do `POST /token`, nas duas modalidades de `grant_type`.","required":["grant_type"],"properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"],"description":"Modalidade da troca."},"code":{"type":"string","description":"Código de autorização. Obrigatório em `authorization_code`."},"code_verifier":{"type":"string","description":"Verificador PKCE do `code_challenge`. Obrigatório em `authorization_code`."},"refresh_token":{"type":"string","description":"Obrigatório em `refresh_token`. Prefixo `fh_mcpr_`."},"client_id":{"type":"string","description":"Identifica o public client (que não tem segredo para enviar)."},"redirect_uri":{"type":"string","format":"uri","description":"Opcional em `authorization_code`; se vier, tem que ser idêntico ao da autorização."},"scope":{"type":"string","description":"Opcional em `refresh_token`, para reduzir os escopos do par novo."},"resource":{"type":"string","format":"uri","description":"Audience (RFC 8707). Quando enviado, precisa ser `https://api.flipperhub.com.br/mcp`.","examples":["https://api.flipperhub.com.br/mcp"]}}},"TokenRevocationRequest":{"type":"object","description":"Corpo `application/x-www-form-urlencoded` do `POST /revoke` (RFC 7009).","required":["token"],"properties":{"token":{"type":"string","description":"O token a revogar."},"token_type_hint":{"type":"string","description":"Dica opcional. O servidor decide pelo prefixo do token, então a dica não altera o resultado.","examples":["access_token","refresh_token"]},"client_id":{"type":"string","description":"Cliente dono do token."}}},"TokenRevocationResult":{"type":"object","additionalProperties":false,"description":"Corpo vazio (`{}`) da revogação: a resposta é 200 tanto para token revogado quanto para token desconhecido (idempotente, para não virar oráculo de validade)."},"OpenApiDocumentResponse":{"type":"object","additionalProperties":true,"description":"Documento OpenAPI 3.1 desta superfície pública (o próprio contrato servido em `/openapi.json`)."}}},"paths":{"/mcp":{"post":{"tags":["mcp"],"operationId":"mcpJsonRpc","summary":"Endpoint MCP (Streamable HTTP, stateless)","description":"Endpoint único do servidor MCP. Não há sessão nem `Mcp-Session-Id`: cada POST\né atendido por um transporte novo, então o cliente não precisa manter estado\nentre chamadas e `initialize` é aceito como qualquer outra requisição, sem ser\npré-requisito de `tools/list` ou `tools/call`.\n\nO cabeçalho `Mcp-Protocol-Version` é opcional; se vier com uma versão que o\nservidor não suporta, a resposta é 400.\n\nO cliente precisa mandar `Content-Type: application/json` (senão 415) e\n`Accept: application/json, text/event-stream` com os DOIS tipos (senão 406).\nA resposta de um pedido sai como stream `text/event-stream`; um lote só com\nnotificações responde 202 sem corpo.\n\nOutros métodos HTTP no mesmo caminho: `GET` com `Accept: text/event-stream`\nabre o stream do servidor, `DELETE` encerra o transporte com 200, e qualquer\noutro método responde 405 com o cabeçalho `Allow: GET, POST, DELETE`. Todos\npassam pela mesma autenticação do `POST`.\n\nO recurso depende da funcionalidade `integracao.mcp` estar no plano da conta.\n\n**Tools disponíveis**\n\n| Tool | Escopo exigido | O que faz |\n| --- | --- | --- |\n| `buscar_contatos` | `read` | Busca contatos (pessoas) do CRM por nome/e-mail/telefone/CPF. Retorna uma página resumida — sem CPF. Use obter_contato para o detalhe completo de um contato. |\n| `obter_contato` | `read` | Detalhe completo de um contato pelo ID (UUID) ou pelo número curto (displayId). Inclui CPF, endereço, observações e oportunidades recentes. |\n| `buscar_empresas` | `read` | Busca empresas do CRM por nome/CNPJ. Retorna uma página resumida. |\n| `obter_empresa` | `read` | Detalhe de uma empresa pelo ID. Inclui endereço e contatos vinculados. Dados bancários/fiscais sensíveis NÃO são expostos. |\n| `listar_notas` | `read` | Lista as notas (comentários) de um contato, empresa ou oportunidade. Retorna texto puro. |\n| `buscar_oportunidades` | `read` | Busca oportunidades do funil (imóveis em negociação de compra). Filtra por texto, pipeline e estágio. Retorna uma página resumida. |\n| `listar_tarefas` | `read` | Lista tarefas do usuário. Filtro: 'hoje' (vencem hoje), 'atrasadas' (vencidas) ou 'todas'. Pode filtrar por status e responsável. Retorna uma página resumida. |\n| `obter_tarefa` | `read` | Detalhe de uma tarefa pelo ID (UUID) ou número curto (displayId), com vínculos e comentários. |\n| `criar_tarefa` | `write:tarefas` | Cria uma tarefa. Campos mínimos: título (obrigatório), descrição, prazo, responsável e um vínculo opcional a um contato/empresa/oportunidade/imóvel. |\n| `criar_nota` | `write:notas` | Cria uma nota (comentário) em um contato, empresa ou oportunidade. O texto é puro; o servidor formata em parágrafos (não aceita HTML). |\n| `criar_contato` | `write:contatos` | Cria um contato (pessoa) no CRM. Nome é obrigatório. Duplicatas (e-mail/CPF já cadastrado) são recusadas com mensagem clara. |\n\nA lista autoritativa é sempre a do `tools/list`; esta tabela é a mesma origem,\npublicada aqui para leitura sem conexão.","security":[{"oauth2":["read"]},{"mcpToken":[]}],"x-mcp-tools":[{"name":"buscar_contatos","description":"Busca contatos (pessoas) do CRM por nome/e-mail/telefone/CPF. Retorna uma página resumida — sem CPF. Use obter_contato para o detalhe completo de um contato.","required_scope":"read"},{"name":"obter_contato","description":"Detalhe completo de um contato pelo ID (UUID) ou pelo número curto (displayId). Inclui CPF, endereço, observações e oportunidades recentes.","required_scope":"read"},{"name":"buscar_empresas","description":"Busca empresas do CRM por nome/CNPJ. Retorna uma página resumida.","required_scope":"read"},{"name":"obter_empresa","description":"Detalhe de uma empresa pelo ID. Inclui endereço e contatos vinculados. Dados bancários/fiscais sensíveis NÃO são expostos.","required_scope":"read"},{"name":"listar_notas","description":"Lista as notas (comentários) de um contato, empresa ou oportunidade. Retorna texto puro.","required_scope":"read"},{"name":"buscar_oportunidades","description":"Busca oportunidades do funil (imóveis em negociação de compra). Filtra por texto, pipeline e estágio. Retorna uma página resumida.","required_scope":"read"},{"name":"listar_tarefas","description":"Lista tarefas do usuário. Filtro: 'hoje' (vencem hoje), 'atrasadas' (vencidas) ou 'todas'. Pode filtrar por status e responsável. Retorna uma página resumida.","required_scope":"read"},{"name":"obter_tarefa","description":"Detalhe de uma tarefa pelo ID (UUID) ou número curto (displayId), com vínculos e comentários.","required_scope":"read"},{"name":"criar_tarefa","description":"Cria uma tarefa. Campos mínimos: título (obrigatório), descrição, prazo, responsável e um vínculo opcional a um contato/empresa/oportunidade/imóvel.","required_scope":"write:tarefas"},{"name":"criar_nota","description":"Cria uma nota (comentário) em um contato, empresa ou oportunidade. O texto é puro; o servidor formata em parágrafos (não aceita HTML).","required_scope":"write:notas"},{"name":"criar_contato","description":"Cria um contato (pessoa) no CRM. Nome é obrigatório. Duplicatas (e-mail/CPF já cadastrado) são recusadas com mensagem clara.","required_scope":"write:contatos"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"}}}},"responses":{"200":{"description":"Resposta do método MCP, como stream de eventos (um evento por mensagem JSON-RPC).","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/McpEventStream"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}},"202":{"description":"Lote só com notificações ou respostas (nenhum pedido): aceito, sem corpo.","headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}},"400":{"description":"JSON inválido ou mensagem JSON-RPC malformada.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}},"401":{"description":"Token ausente, inválido ou expirado. A resposta traz o cabeçalho `WWW-Authenticate: Bearer resource_metadata=\"...\"` apontando o metadata do recurso protegido (e `error=\"invalid_token\"` quando veio um token que não vale), que é o gatilho do fluxo OAuth no cliente.","headers":{"WWW-Authenticate":{"description":"Desafio RFC 6750 com o endereço do metadata RFC 9728.","schema":{"type":"string"},"example":"Bearer resource_metadata=\"https://api.flipperhub.com.br/.well-known/oauth-protected-resource/mcp\""}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}},"403":{"description":"Sem permissão: a funcionalidade `integracao.mcp` não está no plano da conta, ou a tool chamada exige um escopo de escrita que o token não tem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}},"406":{"description":"Cabeçalho `Accept` sem `application/json` e `text/event-stream` juntos.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}},"415":{"description":"`Content-Type` diferente de `application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}},"429":{"description":"Limite de requisições da borda (Cloudflare) atingido para o IP de origem.","headers":{"Retry-After":{"description":"Segundos a aguardar antes de repetir a requisição (RFC 9110). Presente na resposta 429.","required":false,"schema":{"type":"integer"},"example":60}}},"500":{"description":"Falha interna do servidor MCP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcError"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["descoberta"],"operationId":"protectedResourceMetadataRoot","security":[],"summary":"Metadados do recurso protegido na raiz (RFC 9728)","description":"Mesmo corpo da variante com sufixo `/mcp`, servido na raiz porque parte dos clientes sonda aqui primeiro. Público, sem autenticação.","responses":{"200":{"description":"Metadados do recurso protegido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedResourceMetadata"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"tags":["descoberta"],"operationId":"protectedResourceMetadata","security":[],"summary":"Metadados do recurso protegido (RFC 9728)","description":"Endereço canônico do metadata, derivado do caminho do recurso (`/mcp`). É o endereço citado no `WWW-Authenticate` do 401 do `/mcp`. Público, com CORS aberto.","responses":{"200":{"description":"Metadados do recurso protegido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedResourceMetadata"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["descoberta"],"operationId":"authorizationServerMetadata","security":[],"summary":"Metadados do Authorization Server (RFC 8414)","description":"Descoberta do Authorization Server: endereços de autorização, token, registro e revogação, métodos de PKCE e escopos suportados. Público, com CORS aberto.","responses":{"200":{"description":"Metadados do Authorization Server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizationServerMetadata"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}}}}},"/register":{"post":{"tags":["oauth"],"operationId":"registerClient","security":[],"summary":"Registro dinâmico de cliente (RFC 7591)","description":"O cliente de IA registra-se sozinho antes do primeiro consentimento. O\nservidor gera o `client_id` e força public client sem segredo.\n\nCada `redirect_uri` é conferida contra a allowlist oficial do Claude no\nregistro e de novo na autorização. Limite de 20 registros por hora por IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRegistrationRequest"}}}},"responses":{"201":{"description":"Cliente registrado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientInformation"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}},"400":{"description":"Metadados inválidos: `redirect_uris` ausente ou vazio, ou `redirect_uri` fora da allowlist oficial do Claude.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Mais de 20 registros na última hora para o mesmo IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}},"headers":{"Retry-After":{"description":"Segundos a aguardar antes de repetir a requisição (RFC 9110). Presente na resposta 429.","required":false,"schema":{"type":"integer"},"example":60},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/authorize":{"get":{"tags":["oauth"],"operationId":"authorize","security":[],"summary":"Início do fluxo de autorização (código + PKCE)","description":"Valida cliente, `redirect_uri`, PKCE e audience, grava um pedido pendente e\nredireciona o navegador para a tela de consentimento em `https://app.flipperhub.com.br/oauth/consent?req=<id>`.\n\nO usuário aprova (leitura sempre inclusa, escritas uma a uma) e só então nasce\no código de autorização, que volta ao cliente pelo `redirect_uri` com o `state`\noriginal. O código vale 60 segundos e é de uso único; o pedido pendente expira\nem 10 minutos se ninguém decidir.\n\nSem `scope`, a tela oferece todos os escopos, com as escritas desmarcadas.\nLimite de 100 requisições por 15 minutos por IP.","parameters":[{"name":"response_type","in":"query","required":true,"description":"Único valor aceito.","schema":{"const":"code"}},{"name":"client_id","in":"query","required":true,"description":"`client_id` obtido no registro dinâmico.","schema":{"type":"string"}},{"name":"redirect_uri","in":"query","required":true,"description":"Precisa estar entre as URIs registradas pelo cliente E na allowlist oficial do Claude (https://claude.ai/api/mcp/auth_callback, https://claude.com/api/mcp/auth_callback).","schema":{"type":"string","format":"uri"}},{"name":"code_challenge","in":"query","required":true,"description":"Desafio PKCE (S256) do `code_verifier`.","schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","required":true,"description":"Único método aceito.","schema":{"const":"S256"}},{"name":"scope","in":"query","required":false,"description":"Escopos pedidos, separados por espaço. Subconjunto dos escopos suportados; `read` é sempre acrescentado.","schema":{"type":"string","examples":["read write:tarefas write:notas write:contatos"]}},{"name":"state","in":"query","required":false,"description":"Opaco para o cliente, devolvido no redirect final.","schema":{"type":"string"}},{"name":"resource","in":"query","required":false,"description":"Audience (RFC 8707). Quando enviado, precisa ser `https://api.flipperhub.com.br/mcp`.","schema":{"type":"string","format":"uri","examples":["https://api.flipperhub.com.br/mcp"]}}],"responses":{"302":{"description":"Redireciona para a tela de consentimento do FlipperHub. Depois da decisão do usuário, o navegador volta ao `redirect_uri` do cliente com `code` e `state` (ou com `error`, se recusado).","headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42},"Location":{"description":"Tela de consentimento, no domínio do aplicativo.","schema":{"type":"string","format":"uri"},"example":"https://app.flipperhub.com.br/oauth/consent?req=6f1b2c..."}}},"400":{"description":"`client_id` desconhecido, `redirect_uri` fora da allowlist, PKCE ausente ou `resource` de outro público. Erros anteriores à validação do redirect saem direto, sem redirecionar.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Mais de 100 autorizações em 15 minutos para o mesmo IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}},"headers":{"Retry-After":{"description":"Segundos a aguardar antes de repetir a requisição (RFC 9110). Presente na resposta 429.","required":false,"schema":{"type":"integer"},"example":60},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/token":{"post":{"tags":["oauth"],"operationId":"token","security":[],"summary":"Emissão e renovação de token","description":"Duas modalidades, escolhidas pelo `grant_type`:\n\n- `authorization_code`: troca o código do consentimento pelo par de tokens.\n  Exige `code` e `code_verifier` (PKCE). O `redirect_uri`, quando enviado,\n  precisa ser idêntico ao usado na autorização.\n- `refresh_token`: renova sem novo consentimento. O par é rotacionado, e o\n  `scope` opcional só REDUZ o que já foi concedido, nunca amplia.\n\nLimite de 50 requisições por 15 minutos por IP.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"Par de tokens emitido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}},"400":{"description":"Código expirado, já usado ou desconhecido; PKCE que não confere; refresh revogado (o que também revoga a família inteira, por suspeita de roubo); `resource` de outro público; ou `grant_type` não suportado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Mais de 50 trocas em 15 minutos para o mesmo IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}},"headers":{"Retry-After":{"description":"Segundos a aguardar antes de repetir a requisição (RFC 9110). Presente na resposta 429.","required":false,"schema":{"type":"integer"},"example":60},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/revoke":{"post":{"tags":["oauth"],"operationId":"revokeToken","security":[],"summary":"Revogação de token (RFC 7009)","description":"Revoga um access token (`fh_mcp_`) ou um refresh token (`fh_mcpr_`). Revogar\no refresh derruba junto o access do mesmo par.\n\nIdempotente por desenho: token desconhecido ou já revogado também responde 200,\npara não virar oráculo de validade. Limite de 50 requisições por 15 minutos.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRevocationRequest"}}}},"responses":{"200":{"description":"Revogado, ou nada a fazer. Corpo vazio (`{}`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRevocationResult"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}},"400":{"description":"Requisição malformada ou cliente inválido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Mais de 50 revogações em 15 minutos para o mesmo IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}},"headers":{"Retry-After":{"description":"Segundos a aguardar antes de repetir a requisição (RFC 9110). Presente na resposta 429.","required":false,"schema":{"type":"integer"},"example":60},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/health":{"get":{"tags":["saude"],"operationId":"health","security":[],"summary":"Sinal de vida","description":"Público, sem autenticação. Responde enquanto o processo aceita tráfego.","responses":{"200":{"description":"Serviço no ar.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/version":{"get":{"tags":["saude"],"operationId":"version","security":[],"summary":"Identidade do build implantado","description":"Público, sem autenticação. Diz qual commit está no ar, o que permite conferir se um deploy realmente publicou o código pedido.","responses":{"200":{"description":"Identidade do build.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Version"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"},"RateLimit-Limit":{"description":"Teto de requisições da janela mais restritiva aplicável a esta resposta (draft-ietf-httpapi-ratelimit-headers).","required":false,"schema":{"type":"integer"},"example":600},"RateLimit-Remaining":{"description":"Requisições ainda permitidas na janela antes de atingir o teto.","required":false,"schema":{"type":"integer"},"example":599},"RateLimit-Reset":{"description":"Segundos até a janela reiniciar e o `RateLimit-Remaining` voltar ao teto.","required":false,"schema":{"type":"integer"},"example":42}}}}}},"/openapi.json":{"get":{"tags":["descoberta"],"operationId":"openApiDocument","security":[],"summary":"Este documento","description":"Público, com CORS aberto e cache de 5 minutos. Gerado em tempo de execução a partir do código: escopos, tools e endereços saem das mesmas fontes que o servidor usa para servir, então o documento não pode divergir do que roda.","responses":{"200":{"description":"Documento OpenAPI 3.1 desta superfície.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocumentResponse"}}},"headers":{"Deprecation":{"description":"Presente APENAS quando a operação está em transição de aposentadoria (draft-ietf-httpapi-deprecation-header): a data em que a depreciação passou a valer, como HTTP-date. Enquanto a operação é corrente, não é emitido.","required":false,"schema":{"type":"string"},"example":"Wed, 01 Jul 2026 00:00:00 GMT"},"Sunset":{"description":"Acompanha o `Deprecation` (RFC 8594): a data a partir da qual a operação deixa de responder. O intervalo entre os dois cabeçalhos é o prazo mínimo de migração.","required":false,"schema":{"type":"string"},"example":"Thu, 01 Oct 2026 00:00:00 GMT"}}}}}}}}