{
  "openapi": "3.1.0",
  "info": {
    "title": "HypeAi Integra API",
    "version": "1.0.0",
    "description": "A HypeAi Integra é a infraestrutura para operar comunicação sobre o ecossistema da Meta, multi-tenant, para agências e SaaS — dois canais oficiais: WhatsApp (Cloud API da Meta, GA) e Instagram (beta fechado). Autenticação é por chave de API (Bearer hai_live_...), gerada no painel. Toda a API também é operável por IA via servidor MCP (mcp.integra.hypeai.com.br).",
    "contact": {
      "name": "HypeAi Integra",
      "url": "https://integra.hypeai.com.br/docs"
    },
    "x-mcp": {
      "server": "https://mcp.integra.hypeai.com.br/mcp",
      "transport": "streamable-http",
      "tools": 74,
      "description": "Toda a plataforma também é operável por IA via MCP — mesma chave (Authorization: Bearer hai_live_...) ou login OAuth. Operações marcadas com x-mcp-tool têm ferramenta equivalente."
    }
  },
  "servers": [
    {
      "url": "https://api.hypeai.com.br",
      "description": "API HypeAi Integra — Gestão e Connect. Endpoints de WhatsApp usam a mesma base com o prefixo /v1/{phone_number_id} (ver cada operação)."
    }
  ],
  "tags": [
    {
      "name": "API de WhatsApp",
      "description": "Gateway transparente sobre a WhatsApp Cloud API oficial da Meta. Encaminha 1:1 para o Graph da Meta sob /v1/{phone_number_id}/... — você fala o dialeto oficial da Meta, sem gerenciar tokens. Texto livre só dentro da janela de 24h; para iniciar conversa fora dela, use um template aprovado."
    },
    {
      "name": "API de Instagram",
      "description": "API oficial do Instagram (2º canal · beta fechado): DMs, publicação (foto JPEG/carrossel/reel/story), comentários e insights sob /v1/ig/{ig_user_id}/... — mesma chave e gateway do WhatsApp, corpo cru da Meta (exceto POST /posts, conveniência que publica em uma chamada). Sem DM fria (não há template no Instagram); janela de 24h; 100 posts/24h; a API oficial NÃO tem agendamento nem edição de perfil — o scheduler é do seu sistema. Eventos de webhook ig_* são todos opt-in explícito."
    },
    {
      "name": "API HypeAi Integra",
      "description": "Camada de Gestão (integra_*): analytics da conta, uso & custo estimado, pacotes de mensagens (quotas mensais com rollover — revenda planos limitados), perfil do número, status de templates, webhooks de saída e integrações (Typebot/Chatwoot). Chamadas POST { action, ... } nas edge functions."
    },
    {
      "name": "API HypeAi Connect",
      "description": "HypeAi Connect (Embedded Signup as a Service): um SaaS parceiro (chave de escopo agência) provisiona, server-to-server, uma conexão WhatsApp oficial para cada cliente final dele e recebe um connect_url hospedado para embutir (popup/iframe). Ideal para embutir o WhatsApp oficial dentro do seu produto."
    },
    {
      "name": "API de Histórico (coexistência)",
      "description": "Histórico de coexistência (beta fechado): importação ÚNICA das conversas do WhatsApp Business App (até 180 dias, só texto) quando o número entra em coexistência. O conteúdo fica bufferizado SELADO com a chave pública P-256 do parceiro — a HypeAi não tem a privada e não lê — por no máximo 24h, e é apagado no ack. Fluxo: registrar chave → provar posse (desafio de decifragem) → disparar sync → paginar mensagens/agenda → confirmar (ack). Suíte de fio: hai-hist-v1/P256-HKDF-SHA256-AESGCM256/bucket-v1 (guia de decifragem em Node/Python/PHP/Go na doc). Exige aceite do Adendo de Tratamento de Dados + liberação por conta; a agenda exige aceite legal separado."
    }
  ],
  "paths": {
    "/v1/{phone_number_id}/messages": {
      "post": {
        "tags": [
          "API de WhatsApp"
        ],
        "summary": "Enviar texto …",
        "description": "Mensagem de texto livre. Só funciona dentro da janela de 24h após a última mensagem do contato. Link no corpo NÃO gera prévia sozinho: envie `preview_url: true` dentro de `text` para o card com imagem/título — a Meta renderiza só o 1º link (http/https) e a página precisa de metadados Open Graph públicos.\n\nReferência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages",
        "operationId": "post_v1_phone_number_id_messages",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "whatsapp_send_text",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway WhatsApp (proxy da Cloud API oficial da Meta)"
          }
        ],
        "parameters": [
          {
            "name": "phone_number_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "PHONE_NUMBER_ID",
            "description": "ID do número conectado (phone_number_id)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "send_text": {
                  "summary": "Enviar texto",
                  "description": "Mensagem de texto livre. Só funciona dentro da janela de 24h após a última mensagem do contato. Link no corpo NÃO gera prévia sozinho: envie `preview_url: true` dentro de `text` para o card com imagem/título — a Meta renderiza só o 1º link (http/https) e a página precisa de metadados Open Graph públicos.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "text",
                    "text": {
                      "body": "Olá! 👋 Sua mensagem via HypeAi Integra.",
                      "preview_url": true
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_text"
                },
                "send_template": {
                  "summary": "Enviar template",
                  "description": "Template aprovado: o único jeito de iniciar conversa fora da janela de 24h. Use `components` para preencher variáveis.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "template",
                    "template": {
                      "name": "hello_world",
                      "language": {
                        "code": "en_US"
                      }
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_template"
                },
                "send_image": {
                  "summary": "Enviar imagem",
                  "description": "Imagem por URL pública (JPG/PNG) ou por media id (após upload).",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "image",
                    "image": {
                      "link": "https://exemplo.com/foto.jpg"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_media"
                },
                "send_video": {
                  "summary": "Enviar vídeo",
                  "description": "Vídeo por URL pública (MP4) ou media id.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "video",
                    "video": {
                      "link": "https://exemplo.com/video.mp4"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_media"
                },
                "send_audio": {
                  "summary": "Enviar áudio",
                  "description": "Áudio por URL pública (OGG/MP3) ou media id. Sem legenda.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "audio",
                    "audio": {
                      "link": "https://exemplo.com/audio.ogg"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_media"
                },
                "send_document": {
                  "summary": "Enviar documento",
                  "description": "Arquivo por URL pública (PDF, etc.) ou media id.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "document",
                    "document": {
                      "link": "https://exemplo.com/contrato.pdf",
                      "filename": "contrato.pdf"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_media"
                },
                "send_location": {
                  "summary": "Enviar localização",
                  "description": "Compartilha um ponto no mapa.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "location",
                    "location": {
                      "latitude": -23.5613,
                      "longitude": -46.6565,
                      "name": "Av. Paulista",
                      "address": "Av. Paulista, 1000 - São Paulo"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_location"
                },
                "send_contacts": {
                  "summary": "Enviar contato",
                  "description": "Envia um cartão de contato (vCard).",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "contacts",
                    "contacts": [
                      {
                        "name": {
                          "formatted_name": "Maria Souza",
                          "first_name": "Maria"
                        },
                        "phones": [
                          {
                            "phone": "5511988887777",
                            "type": "CELL"
                          }
                        ]
                      }
                    ]
                  },
                  "x-mcp-tool": "whatsapp_send_contacts"
                },
                "send_reaction": {
                  "summary": "Reagir (emoji)",
                  "description": "Reage a uma mensagem recebida com um emoji. Use o wamid que chegou no seu webhook.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "reaction",
                    "reaction": {
                      "message_id": "wamid.HBgM...",
                      "emoji": "👍"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_reaction"
                },
                "send_buttons": {
                  "summary": "Botões de resposta",
                  "description": "Até 3 botões de resposta rápida (dentro da janela de 24h).",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "body": {
                        "text": "Como podemos ajudar?"
                      },
                      "action": {
                        "buttons": [
                          {
                            "type": "reply",
                            "reply": {
                              "id": "btn_1",
                              "title": "Falar com vendas"
                            }
                          },
                          {
                            "type": "reply",
                            "reply": {
                              "id": "btn_2",
                              "title": "Suporte"
                            }
                          },
                          {
                            "type": "reply",
                            "reply": {
                              "id": "btn_3",
                              "title": "Outro assunto"
                            }
                          }
                        ]
                      }
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_interactive"
                },
                "send_list": {
                  "summary": "Lista de opções",
                  "description": "Menu com seções e itens selecionáveis (dentro da janela de 24h).",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "list",
                      "body": {
                        "text": "Escolha uma opção:"
                      },
                      "action": {
                        "button": "Ver opções",
                        "sections": [
                          {
                            "title": "Opções",
                            "rows": [
                              {
                                "id": "row_1",
                                "title": "Plano Básico"
                              },
                              {
                                "id": "row_2",
                                "title": "Plano Pro"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_interactive"
                },
                "mark_read": {
                  "summary": "Marcar como lida",
                  "description": "Marca uma mensagem recebida como lida (os ✓✓ azuis). Use o wamid que chegou no seu webhook.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "status": "read",
                    "message_id": "wamid.HBgM..."
                  },
                  "x-mcp-tool": "whatsapp_mark_read"
                },
                "typing": {
                  "summary": "Indicador de digitação",
                  "description": "Mostra “digitando…” ao contato (e marca como lida). Some sozinho em ~25s ou quando você responde.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "status": "read",
                    "message_id": "wamid.HBgM...",
                    "typing_indicator": {
                      "type": "text"
                    }
                  },
                  "x-mcp-tool": "whatsapp_send_typing"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/{phone_number_id}/media/{media_id}": {
      "get": {
        "tags": [
          "API de WhatsApp"
        ],
        "summary": "Baixar mídia recebida",
        "description": "Baixa o BINÁRIO de uma mídia recebida (áudio/voz, imagem, vídeo, documento). A Integra resolve o media_id na Meta com o seu token (que nunca sai do cofre) e transmite os bytes de volta com o Content-Type real (nota de voz = audio/ogg). Substitua {media_id} pelo id que chega no webhook (campo id do objeto de mídia). Boa prática: baixe no recebimento (webhook) em background e guarde no seu storage — a Meta expira a mídia, e o 1º download leva ~1-2s (2 hops obrigatórios à Meta). Só metadados? use a Gestão; aqui vêm os bytes. Chave de AGÊNCIA: funciona direto para números de sub-clientes do Connect — o gateway resolve o dono pelo phone_number_id, sem parâmetro extra (vale para TODA a API REST; GET /v1 lista o portfólio inteiro com o client_id de cada número).\n\nReferência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media",
        "operationId": "get_v1_phone_number_id_media_media_id",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "whatsapp_get_media_url",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway WhatsApp (proxy da Cloud API oficial da Meta)"
          }
        ],
        "parameters": [
          {
            "name": "phone_number_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "PHONE_NUMBER_ID",
            "description": "ID do número conectado (phone_number_id)."
          },
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "1699154617978078",
            "description": "ID da mídia recebida (campo `id` do objeto de mídia no webhook)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/{phone_number_id}": {
      "get": {
        "tags": [
          "API de WhatsApp"
        ],
        "summary": "Dados do número",
        "description": "Metadados do número conectado (nome verificado, qualidade, status de verificação).",
        "operationId": "get_v1_phone_number_id",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "whatsapp_get_phone",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway WhatsApp (proxy da Cloud API oficial da Meta)"
          }
        ],
        "parameters": [
          {
            "name": "phone_number_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "PHONE_NUMBER_ID",
            "description": "ID do número conectado (phone_number_id)."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "verified_name,display_phone_number,quality_rating,code_verification_status",
            "description": "Campos a retornar (lista separada por vírgula)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/{phone_number_id}/connection": {
      "delete": {
        "tags": [
          "API de WhatsApp"
        ],
        "summary": "Desconectar número",
        "description": "Desliga o número DESTA conta e libera a vaga do pool. Chame quando o SEU sistema desconectar o número no lado de vocês — sem esta chamada a Integra continua mostrando o número conectado, corretamente, porque ninguém a avisou. **Não mexe na Meta**: o número segue na WABA e no Business Manager do dono, e o app segue assinado; tirar de lá é decisão do dono, no Business Manager. Idempotente (`already_disconnected: true` na repetição). Para reconectar, gere uma sessão do Connect — em COEXISTÊNCIA para preservar a importação de histórico; como API Oficial, ela se encerra de forma permanente.",
        "operationId": "delete_v1_phone_number_id_connection",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_disconnect_number",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway WhatsApp (proxy da Cloud API oficial da Meta)"
          }
        ],
        "parameters": [
          {
            "name": "phone_number_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "PHONE_NUMBER_ID",
            "description": "ID do número conectado (phone_number_id)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/messages": {
      "post": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Responder DM (texto) …",
        "description": "Responde uma DM. SÓ dentro da janela de 24h após a última mensagem do usuário — o Instagram NÃO tem template, então não existe DM fria: a conversa sempre começa pelo usuário. O `recipient.id` é o IGSID que chegou em entry[].messaging[].sender.id no evento ig_messages.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api",
        "operationId": "post_v1_ig_ig_user_id_messages",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_send_message",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "ig_send_text": {
                  "summary": "Responder DM (texto)",
                  "description": "Responde uma DM. SÓ dentro da janela de 24h após a última mensagem do usuário — o Instagram NÃO tem template, então não existe DM fria: a conversa sempre começa pelo usuário. O `recipient.id` é o IGSID que chegou em entry[].messaging[].sender.id no evento ig_messages.",
                  "value": {
                    "recipient": {
                      "id": "6697308663720723"
                    },
                    "message": {
                      "text": "Oi! Recebemos sua mensagem 👋"
                    }
                  },
                  "x-mcp-tool": "instagram_send_message"
                },
                "ig_send_media": {
                  "summary": "Responder DM (mídia por URL)",
                  "description": "Envia imagem, áudio, vídeo ou arquivo na DM por URL pública (a Meta baixa na hora). Tipos: image, audio, video, file. Também aceita 'like_heart' (sticker) e 'media_share' (compartilhar um post seu, payload.id = media_id).",
                  "value": {
                    "recipient": {
                      "id": "6697308663720723"
                    },
                    "message": {
                      "attachment": {
                        "type": "image",
                        "payload": {
                          "url": "https://exemplo.com/foto.jpg"
                        }
                      }
                    }
                  },
                  "x-mcp-tool": "instagram_send_message"
                },
                "ig_send_quick_replies": {
                  "summary": "Responder DM com botões",
                  "description": "Texto + até 13 botões de resposta rápida. O clique volta pro seu webhook no evento ig_postbacks com o `payload` escolhido.",
                  "value": {
                    "recipient": {
                      "id": "6697308663720723"
                    },
                    "message": {
                      "text": "Como posso ajudar?",
                      "quick_replies": [
                        {
                          "content_type": "text",
                          "title": "Ver preços",
                          "payload": "OPCAO_1"
                        },
                        {
                          "content_type": "text",
                          "title": "Falar com humano",
                          "payload": "OPCAO_2"
                        }
                      ]
                    }
                  },
                  "x-mcp-tool": "instagram_send_message"
                },
                "ig_react": {
                  "summary": "Reagir a uma DM",
                  "description": "Reage (ou remove a reação) a uma mensagem recebida. `sender_action`: react | unreact. O message_id é o `mid` do webhook.",
                  "value": {
                    "recipient": {
                      "id": "6697308663720723"
                    },
                    "sender_action": "react",
                    "payload": {
                      "message_id": "aWdfZAG1faXRlbToxOklHTWV…",
                      "reaction": "love"
                    }
                  },
                  "x-mcp-tool": "instagram_send_message"
                },
                "ig_private_reply": {
                  "summary": "Responder comentário no privado",
                  "description": "Transforma um comentário em DM (private reply) — a única ponte comentário→DM. Regra da Meta: 1× por comentário, dentro de 7 dias. `recipient.comment_id` no lugar do id do usuário (o id vem do evento ig_comments ou de 'Listar comentários').",
                  "value": {
                    "recipient": {
                      "comment_id": "17984512345678901"
                    },
                    "message": {
                      "text": "Oi! Respondendo por aqui 🙂"
                    }
                  },
                  "x-mcp-tool": "instagram_private_reply"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/posts": {
      "post": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Publicar foto (feed) …",
        "description": "Publica uma foto no feed numa chamada só (criamos o container, aguardamos o processamento e publicamos). ATENÇÃO: o Instagram aceita SÓ JPEG em foto — PNG é rejeitado pela Meta. A imagem é baixada da SUA URL pública no momento da chamada. Teto da Meta: 100 publicações/24h.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing",
        "operationId": "post_v1_ig_ig_user_id_posts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_create_post",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "ig_publish_photo": {
                  "summary": "Publicar foto (feed)",
                  "description": "Publica uma foto no feed numa chamada só (criamos o container, aguardamos o processamento e publicamos). ATENÇÃO: o Instagram aceita SÓ JPEG em foto — PNG é rejeitado pela Meta. A imagem é baixada da SUA URL pública no momento da chamada. Teto da Meta: 100 publicações/24h.",
                  "value": {
                    "image_url": "https://exemplo.com/foto.jpg",
                    "caption": "Nosso novo produto 🚀 #lancamento"
                  },
                  "x-mcp-tool": "instagram_create_post"
                },
                "ig_publish_reel": {
                  "summary": "Publicar Reel",
                  "description": "Publica um Reel (media_type REELS). Vídeo é processado de forma assíncrona pela Meta: se não ficar pronto em ~100s, a resposta é 202 com `creation_id` — conclua depois com POST /media_publish (ou re-chamando). `share_to_feed` controla se também aparece no feed.",
                  "value": {
                    "media_type": "REELS",
                    "video_url": "https://exemplo.com/reel.mp4",
                    "caption": "Bastidores da semana 🎬",
                    "cover_url": "https://exemplo.com/capa.jpg"
                  },
                  "x-mcp-tool": "instagram_create_post"
                },
                "ig_publish_story": {
                  "summary": "Publicar Story",
                  "description": "Publica um Story (media_type STORIES) de imagem (image_url, JPEG) ou vídeo (video_url). Stories não têm legenda e expiram em 24h — leia as métricas antes disso (insights da mídia).",
                  "value": {
                    "media_type": "STORIES",
                    "image_url": "https://exemplo.com/story.jpg"
                  },
                  "x-mcp-tool": "instagram_create_post"
                },
                "ig_publish_carousel": {
                  "summary": "Publicar carrossel",
                  "description": "Publica um carrossel de 2 a 10 itens: cada filho vira um container (is_carousel_item) e o pai é publicado como CAROUSEL. Aceita mistura de imagem e vídeo.",
                  "value": {
                    "children": [
                      {
                        "image_url": "https://exemplo.com/1.jpg"
                      },
                      {
                        "image_url": "https://exemplo.com/2.jpg"
                      }
                    ],
                    "caption": "Antes e depois ✨"
                  },
                  "x-mcp-tool": "instagram_create_post"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/media_publish": {
      "post": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Concluir publicação (creation_id)",
        "description": "Endpoint CRU da Meta: publica um container já processado. É o que você chama quando 'Publicar Reel' devolveu 202 com creation_id (vídeo ainda processando). Para checar o estado antes: GET /v1/ig/{ig_user_id}/{creation_id}?fields=status_code.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing",
        "operationId": "post_v1_ig_ig_user_id_media_publish",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_create_post",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "ig_media_publish": {
                  "summary": "Concluir publicação (creation_id)",
                  "description": "Endpoint CRU da Meta: publica um container já processado. É o que você chama quando 'Publicar Reel' devolveu 202 com creation_id (vídeo ainda processando). Para checar o estado antes: GET /v1/ig/{ig_user_id}/{creation_id}?fields=status_code.",
                  "value": {
                    "creation_id": "17998765432101234"
                  },
                  "x-mcp-tool": "instagram_create_post"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/content_publishing_limit": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Cota de publicação (24h)",
        "description": "Quanto do teto de 100 publicações/24h da conta já foi usado. Cheque antes de rodadas grandes de publicação.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing",
        "operationId": "get_v1_ig_ig_user_id_content_publishing_limit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_get_publishing_limit",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "quota_usage,config",
            "description": "Campos a retornar (lista separada por vírgula)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/{media_id}/comments": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Listar comentários de um post",
        "description": "Lista os comentários de um post/reel — substitua {media_id} pelo id da mídia ('Listar mídias publicadas'). O `id` de cada comentário alimenta a resposta pública, a private reply e a moderação. Para receber em tempo real, assine o evento ig_comments no seu webhook.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation",
        "operationId": "get_v1_ig_ig_user_id_media_id_comments",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_list_comments",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "id,text,username,timestamp,like_count,hidden,replies{id,text,username}",
            "description": "Campos a retornar (lista separada por vírgula)."
          },
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "1699154617978078",
            "description": "ID da mídia recebida (campo `id` do objeto de mídia no webhook)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/{comment_id}/replies": {
      "post": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Responder comentário (público)",
        "description": "Publica uma resposta aninhada ao comentário, visível no post — substitua {comment_id} pelo id do comentário. Para responder no privado, use 'Responder comentário no privado' (DM).\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation",
        "operationId": "post_v1_ig_ig_user_id_comment_id_replies",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_reply_comment",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "comment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "{comment_id}"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "ig_reply_comment": {
                  "summary": "Responder comentário (público)",
                  "description": "Publica uma resposta aninhada ao comentário, visível no post — substitua {comment_id} pelo id do comentário. Para responder no privado, use 'Responder comentário no privado' (DM).",
                  "value": {
                    "message": "Obrigado pelo comentário! 💜"
                  },
                  "x-mcp-tool": "instagram_reply_comment"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/{comment_id}": {
      "post": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Ocultar / reexibir comentário",
        "description": "Oculta (hide=true) ou reexibe (hide=false) um comentário — substitua {comment_id}. Reversível — é a moderação recomendada; apagar é definitivo.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation",
        "operationId": "post_v1_ig_ig_user_id_comment_id",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_moderate_comment",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "comment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "{comment_id}"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "ig_hide_comment": {
                  "summary": "Ocultar / reexibir comentário",
                  "description": "Oculta (hide=true) ou reexibe (hide=false) um comentário — substitua {comment_id}. Reversível — é a moderação recomendada; apagar é definitivo.",
                  "value": {
                    "hide": true
                  },
                  "x-mcp-tool": "instagram_moderate_comment"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      },
      "delete": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Apagar comentário",
        "description": "Apaga o comentário DEFINITIVAMENTE (irreversível) — substitua {comment_id}. Prefira ocultar quando a intenção for só tirar do público.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation",
        "operationId": "delete_v1_ig_ig_user_id_comment_id",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_moderate_comment",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "comment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "{comment_id}"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/{media_id}/insights": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Métricas de um post",
        "description": "Métricas de UMA mídia (post, reel ou story) — substitua {media_id}. As métricas válidas variam por tipo — a Meta responde com erro claro listando as aceitas; ajuste o parâmetro `metric` e repita. Story expira em 24h: leia antes.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/insights",
        "operationId": "get_v1_ig_ig_user_id_media_id_insights",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_get_media_insights",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "metric",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "reach,likes,comments,saved,shares,views"
          },
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "1699154617978078",
            "description": "ID da mídia recebida (campo `id` do objeto de mídia no webhook)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/insights": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Métricas da conta",
        "description": "Métricas agregadas da conta no período (day | week | days_28). Algumas métricas exigem metric_type=total_value; a Meta indica no erro quando faltar.\n\nReferência Meta: https://developers.facebook.com/docs/instagram-platform/insights",
        "operationId": "get_v1_ig_ig_user_id_insights",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_get_account_insights",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "metric",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "reach,views,accounts_engaged"
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "day"
          },
          {
            "name": "metric_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "total_value"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Perfil da conta",
        "description": "Lê o perfil da própria conta. LEITURA apenas: a API oficial do Instagram NÃO permite editar perfil, bio ou foto — nem por aqui, nem por nenhum provedor.",
        "operationId": "get_v1_ig_ig_user_id",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_get_profile",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "username,name,biography,website,followers_count,media_count,profile_picture_url,account_type",
            "description": "Campos a retornar (lista separada por vírgula)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/v1/ig/{ig_user_id}/media": {
      "get": {
        "tags": [
          "API de Instagram"
        ],
        "summary": "Listar mídias publicadas",
        "description": "Lista as mídias já publicadas (id, tipo, URL, permalink, legenda, likes, comentários), com paginação por cursor. O `id` alimenta insights e comentários.",
        "operationId": "get_v1_ig_ig_user_id_media",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "instagram_list_media",
        "servers": [
          {
            "url": "https://api.hypeai.com.br",
            "description": "Gateway Instagram (trilho /v1/ig sobre a API oficial da Meta · beta fechado)"
          }
        ],
        "parameters": [
          {
            "name": "ig_user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "IG_USER_ID",
            "description": "ID da conta do Instagram conectada (ig_user_id — liste com GET /v1, campo instagram)."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "id,media_type,media_url,permalink,caption,timestamp,like_count,comments_count",
            "description": "Campos a retornar (lista separada por vírgula)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "25"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/client-analytics": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Analytics da conta",
        "description": "Métricas ao vivo da Meta (conversas, custo, entrega) com cache. Corpo: { period }.",
        "operationId": "post_client_analytics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_get_meta_analytics",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_analytics": {
                  "summary": "Analytics da conta",
                  "description": "Métricas ao vivo da Meta (conversas, custo, entrega) com cache. Corpo: { period }.",
                  "value": {
                    "period": "7d"
                  },
                  "x-mcp-tool": "integra_get_meta_analytics"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/quota-manage": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Pacotes de mensagens (listar) …",
        "description": "Lista os pacotes (quotas mensais com rollover) e o saldo/consumo do ciclo corrente.",
        "operationId": "post_quota_manage",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_get_quota",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_quota_list": {
                  "summary": "Pacotes de mensagens (listar)",
                  "description": "Lista os pacotes (quotas mensais com rollover) e o saldo/consumo do ciclo corrente.",
                  "value": {
                    "action": "list"
                  },
                  "x-mcp-tool": "integra_get_quota"
                },
                "integra_quota_set": {
                  "summary": "Pacote de mensagens (criar/editar)",
                  "description": "Define o limite mensal de envios por número (omita phone_number_id p/ a conta inteira). Ao esgotar, envios são bloqueados (mode enforce) até o próximo ciclo. Rollover opcional.",
                  "value": {
                    "action": "set",
                    "phone_number_id": "123456789012345",
                    "monthly_allowance": 1000,
                    "rollover_enabled": false,
                    "rollover_expiry_months": 3
                  },
                  "x-mcp-tool": "integra_set_quota"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/number-profile-manage": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Perfil do número (ler) …",
        "description": "Lê o perfil comercial do número (sobre, descrição, endereço, sites, vertical).",
        "operationId": "post_number_profile_manage",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_get_number_profile",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_number_profile_get": {
                  "summary": "Perfil do número (ler)",
                  "description": "Lê o perfil comercial do número (sobre, descrição, endereço, sites, vertical).",
                  "value": {
                    "action": "get",
                    "phone_number_id": "123456789012345"
                  },
                  "x-mcp-tool": "integra_get_number_profile"
                },
                "integra_number_profile_update": {
                  "summary": "Perfil do número (editar)",
                  "description": "Atualiza campos do perfil comercial (verified_name é read-only).",
                  "value": {
                    "action": "update",
                    "phone_number_id": "123456789012345",
                    "about": "Atendimento oficial",
                    "description": "Sua empresa em uma linha."
                  },
                  "x-mcp-tool": "integra_update_number_profile"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/sync-phone-numbers": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Re-sincronizar números",
        "description": "Re-sincroniza seus números com a Meta (nome, qualidade, tier). Operação de manutenção.",
        "operationId": "post_sync_phone_numbers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_sync_numbers",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_sync_numbers": {
                  "summary": "Re-sincronizar números",
                  "description": "Re-sincroniza seus números com a Meta (nome, qualidade, tier). Operação de manutenção.",
                  "value": {},
                  "x-mcp-tool": "integra_sync_numbers"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/client-templates-status": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Atualizar status de templates",
        "description": "Força a releitura do status dos templates na Meta (PENDING→APPROVED/REJECTED). Em contas multi-WABA, informe credential_id. Prefira acompanhar por push: assine o evento 'templates' no seu webhook.",
        "operationId": "post_client_templates_status",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_refresh_templates",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_refresh_templates": {
                  "summary": "Atualizar status de templates",
                  "description": "Força a releitura do status dos templates na Meta (PENDING→APPROVED/REJECTED). Em contas multi-WABA, informe credential_id. Prefira acompanhar por push: assine o evento 'templates' no seu webhook.",
                  "value": {
                    "force": true,
                    "credential_id": "uuid da credencial"
                  },
                  "x-mcp-tool": "integra_refresh_templates"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/manage-templates": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Criar template …",
        "description": "Cria um template na Meta (entra PENDING; aprovação assíncrona — acompanhe pelo evento 'templates' do webhook ou pelo refresh). `template` segue o formato cru da Cloud API e cobre TODOS os tipos: HEADER text/IMAGE/VIDEO/DOCUMENT/LOCATION (mídia exige example.header_handle — gere na ação 'Subir mídia de exemplo'), BODY com variáveis {{1}} (+ example), FOOTER, BUTTONS (quick_reply, url dinâmica, phone_number, copy_code, OTP). Recomendado allow_category_change:true (a Meta recategoriza em vez de rejeitar). Chave de agência: passe client_id do sub-cliente p/ criar em nome dele (Connect).",
        "operationId": "post_manage_templates",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_create_template",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_templates_create": {
                  "summary": "Criar template",
                  "description": "Cria um template na Meta (entra PENDING; aprovação assíncrona — acompanhe pelo evento 'templates' do webhook ou pelo refresh). `template` segue o formato cru da Cloud API e cobre TODOS os tipos: HEADER text/IMAGE/VIDEO/DOCUMENT/LOCATION (mídia exige example.header_handle — gere na ação 'Subir mídia de exemplo'), BODY com variáveis {{1}} (+ example), FOOTER, BUTTONS (quick_reply, url dinâmica, phone_number, copy_code, OTP). Recomendado allow_category_change:true (a Meta recategoriza em vez de rejeitar). Chave de agência: passe client_id do sub-cliente p/ criar em nome dele (Connect).",
                  "value": {
                    "action": "create",
                    "template": {
                      "name": "confirmacao_pedido",
                      "language": "pt_BR",
                      "category": "UTILITY",
                      "allow_category_change": true,
                      "components": [
                        {
                          "type": "BODY",
                          "text": "Oi {{1}}, seu pedido {{2}} foi confirmado!",
                          "example": {
                            "body_text": [
                              [
                                "Maria",
                                "#123"
                              ]
                            ]
                          }
                        }
                      ]
                    },
                    "credential_id": "uuid da credencial",
                    "client_id": "uuid do sub-cliente"
                  },
                  "x-mcp-tool": "integra_create_template"
                },
                "integra_templates_update": {
                  "summary": "Editar template",
                  "description": "Edita components/categoria de um template existente (volta a PENDING p/ nova aprovação). Regras da Meta: só APPROVED/REJECTED/PAUSED; APPROVED = 1 edição/24h e 10/mês.",
                  "value": {
                    "action": "update",
                    "template_id": "123456789012345",
                    "template": {
                      "components": [
                        {
                          "type": "BODY",
                          "text": "Novo texto {{1}}",
                          "example": {
                            "body_text": [
                              [
                                "Maria"
                              ]
                            ]
                          }
                        }
                      ]
                    },
                    "credential_id": "uuid da credencial",
                    "client_id": "uuid do sub-cliente"
                  },
                  "x-mcp-tool": "integra_update_template"
                },
                "integra_templates_delete": {
                  "summary": "Remover template",
                  "description": "Apaga um template na Meta. Sem template_id apaga TODAS as línguas com esse nome; com template_id (hsm_id), só aquela edição. Nome apagado fica 30 dias indisponível p/ recriar (regra da Meta).",
                  "value": {
                    "action": "delete",
                    "name": "confirmacao_pedido",
                    "template_id": "123456789012345",
                    "credential_id": "uuid da credencial",
                    "client_id": "uuid do sub-cliente"
                  },
                  "x-mcp-tool": "integra_delete_template"
                },
                "integra_templates_upload_example": {
                  "summary": "Subir mídia de exemplo (header)",
                  "description": "Sobe a mídia de EXEMPLO do header (Resumable Upload da Meta) e devolve o handle — obrigatório ANTES de criar template com HEADER de IMAGE/VIDEO/DOCUMENT (use em example.header_handle). Aceita URL https pública: image/jpeg|png ≤5MB, video/mp4 ≤16MB, application/pdf ≤25MB. A mídia não fica na Integra (relay).",
                  "value": {
                    "action": "upload_example",
                    "file_url": "https://exemplo.com/banner.jpg",
                    "file_type": "image/jpeg",
                    "credential_id": "uuid da credencial",
                    "client_id": "uuid do sub-cliente"
                  },
                  "x-mcp-tool": "integra_upload_template_example"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/webhooks-manage": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Listar webhooks …",
        "description": "Lista os webhooks de saída configurados na conta.",
        "operationId": "post_webhooks_manage",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_list_webhooks",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_webhooks_list": {
                  "summary": "Listar webhooks",
                  "description": "Lista os webhooks de saída configurados na conta.",
                  "value": {
                    "action": "list"
                  },
                  "x-mcp-tool": "integra_list_webhooks"
                },
                "integra_webhooks_create": {
                  "summary": "Criar webhook",
                  "description": "Cria um webhook de saída. O secret HMAC é retornado UMA única vez, na criação (perdeu? use a ação rotate). Eventos: messages, message_status, templates, account_update, connection, quota.threshold; coexistência (opt-in explícito): smb_message_echoes (eco do que você envia pelo app do celular), history, smb_app_state_sync. **`connection` inclui `connection.removed`** — um número saiu, e este chega a QUALQUER conta que assine `connection` (os outros eventos de ciclo de vida são exclusivos de contas do Connect). O campo `source` distingue o eco da sua própria chamada a `DELETE /v1/{phone_number_id}/connection` (`api`) de uma remoção que você não pediu (`panel`, `cron`, `meta_webhook`). Em `cron`/`meta_webhook` o motivo é `not_in_waba`: o número não está mais na WABA que temos para ele e não conseguimos alcançá-lo com aquela credencial — a API da Meta não distingue \"foi apagado\" de \"esta credencial não enxerga\", então não afirmamos qual dos dois é.",
                  "value": {
                    "action": "create",
                    "name": "Meu webhook",
                    "url": "https://exemplo.com/webhook",
                    "events": [
                      "messages",
                      "message_status"
                    ],
                    "all_numbers": true
                  },
                  "x-mcp-tool": "integra_create_webhook"
                },
                "integra_webhooks_update": {
                  "summary": "Editar webhook",
                  "description": "Edita um webhook de saída (nome, URL, eventos, ativo). `events` substitui a lista atual — inclua os já assinados. Ex.: adicionar smb_message_echoes (coexistência) a um webhook existente. Não troca o secret (use rotate). `is_active: true` também REATIVA um webhook desativado automaticamente (20 falhas consecutivas de entrega desligam sozinho; 401/403/410 são permanentes, sem reentrega) — reativar zera o contador.",
                  "value": {
                    "action": "update",
                    "id": "uuid do webhook",
                    "events": [
                      "messages",
                      "message_status",
                      "smb_message_echoes"
                    ],
                    "url": "https://exemplo.com/webhook",
                    "is_active": true
                  },
                  "x-mcp-tool": "integra_update_webhook"
                },
                "integra_webhooks_rotate": {
                  "summary": "Rotacionar secret",
                  "description": "Gera um NOVO secret HMAC para o webhook e o devolve UMA única vez ({ id, secret, rotated_at }). Use se perdeu o secret ou suspeita de vazamento — sem recriar o webhook (URL/eventos/histórico intactos). Efeito imediato: as entregas passam a ser assinadas com o novo; uma entrega em trânsito pode falhar 1x e o retry (1 min+) reassina sozinho.",
                  "value": {
                    "action": "rotate",
                    "id": "uuid do webhook"
                  },
                  "x-mcp-tool": "integra_rotate_webhook_secret"
                },
                "integra_webhooks_delete": {
                  "summary": "Remover webhook",
                  "description": "Remove um webhook de saída pelo id.",
                  "value": {
                    "action": "delete",
                    "id": "uuid do webhook"
                  },
                  "x-mcp-tool": "integra_delete_webhook"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/integrations-manage": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Listar Typebot",
        "description": "Lista as integrações Typebot da conta.",
        "operationId": "post_integrations_manage",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_list_typebot_integrations",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_typebot_list": {
                  "summary": "Listar Typebot",
                  "description": "Lista as integrações Typebot da conta.",
                  "value": {
                    "action": "list"
                  },
                  "x-mcp-tool": "integra_list_typebot_integrations"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/chatwoot-integrations-manage": {
      "post": {
        "tags": [
          "API HypeAi Integra"
        ],
        "summary": "Listar Chatwoot",
        "description": "Lista as integrações Chatwoot da conta.",
        "operationId": "post_chatwoot_integrations_manage",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_list_chatwoot_integrations",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "integra_chatwoot_list": {
                  "summary": "Listar Chatwoot",
                  "description": "Lista as integrações Chatwoot da conta.",
                  "value": {
                    "action": "list"
                  },
                  "x-mcp-tool": "integra_list_chatwoot_integrations"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/connect-session": {
      "post": {
        "tags": [
          "API HypeAi Connect"
        ],
        "summary": "Criar sessão de conexão",
        "description": "Provisiona (idempotente por external_customer_id) um sub-cliente p/ um cliente final do seu SaaS e devolve connect_url (Embedded Signup hospedado) + webhook_secret (UMA vez) + capacity + o client_id do sub-cliente (use-o + a chave de agência p/ configurar o resto: quota, Typebot, Chatwoot). `events` escolhe o que o webhook assina (default messages,message_status,connection). `config` deixa o sub-cliente já pronto na MESMA chamada (connection_limit + quota). **CONEXÃO = 1 número de WhatsApp OU 1 conta do Instagram** — os dois canais somam no mesmo teto e cada conexão ativa consome 1 vaga do pool da conta; um cliente omnichannel precisa de `connection_limit >= 2`. Multi-inbox: eleve o teto e crie UMA sessão por conexão (mesmo `external_customer_id` reaproveita sub-cliente e WABA; as conexões são aditivas). ⚠️ `connection_limit` só AUMENTA: numa re-chamada, valor menor que o teto atual é ignorado e a resposta traz `connection_limit_kept` — para o default do seu integrador não desfazer em silêncio um limite elevado no painel. O MODO da conexão é escolhido pelo cliente final DENTRO da tela — Coexistência (número segue no app do celular; histórico importável) ou API Oficial — e chega no campo `coexistence` do connection.completed e do GET /v1. Se o SEU produto só opera em um dos modos, mande `flow` (`coexistence` ou `standard`): a tela passa a mostrar SÓ ele, sem seletor. ⚠️ Reconectar como API Oficial um número que era coexistência encerra o histórico em definitivo. Acompanhe a sessão em ?session=cs_... (endpoint abaixo).",
        "operationId": "post_connect_session",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_connect_create_session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "connect_create": {
                  "summary": "Criar sessão de conexão",
                  "description": "Provisiona (idempotente por external_customer_id) um sub-cliente p/ um cliente final do seu SaaS e devolve connect_url (Embedded Signup hospedado) + webhook_secret (UMA vez) + capacity + o client_id do sub-cliente (use-o + a chave de agência p/ configurar o resto: quota, Typebot, Chatwoot). `events` escolhe o que o webhook assina (default messages,message_status,connection). `config` deixa o sub-cliente já pronto na MESMA chamada (connection_limit + quota). **CONEXÃO = 1 número de WhatsApp OU 1 conta do Instagram** — os dois canais somam no mesmo teto e cada conexão ativa consome 1 vaga do pool da conta; um cliente omnichannel precisa de `connection_limit >= 2`. Multi-inbox: eleve o teto e crie UMA sessão por conexão (mesmo `external_customer_id` reaproveita sub-cliente e WABA; as conexões são aditivas). ⚠️ `connection_limit` só AUMENTA: numa re-chamada, valor menor que o teto atual é ignorado e a resposta traz `connection_limit_kept` — para o default do seu integrador não desfazer em silêncio um limite elevado no painel. O MODO da conexão é escolhido pelo cliente final DENTRO da tela — Coexistência (número segue no app do celular; histórico importável) ou API Oficial — e chega no campo `coexistence` do connection.completed e do GET /v1. Se o SEU produto só opera em um dos modos, mande `flow` (`coexistence` ou `standard`): a tela passa a mostrar SÓ ele, sem seletor. ⚠️ Reconectar como API Oficial um número que era coexistência encerra o histórico em definitivo. Acompanhe a sessão em ?session=cs_... (endpoint abaixo).",
                  "value": {
                    "external_customer_id": "petshop-001",
                    "customer_name": "Patas & Cia",
                    "flow": "coexistence",
                    "webhook_url": "https://seu-saas.com/webhooks/hypeai",
                    "allowed_origin": "https://app.seu-saas.com",
                    "return_url": "https://app.seu-saas.com/whatsapp/ok",
                    "events": [
                      "messages",
                      "message_status",
                      "connection"
                    ],
                    "config": {
                      "connection_limit": 2,
                      "quota": {
                        "monthly_allowance": 1000
                      }
                    }
                  },
                  "x-mcp-tool": "integra_connect_create_session"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      },
      "get": {
        "tags": [
          "API HypeAi Connect"
        ],
        "summary": "Pré-checar capacidade do pool …",
        "description": "Lê a capacidade do pool da conta (fail-closed) ANTES de abrir a tela. Resposta: { capacity: { pool, active, available, reason }, pool_exhausted, breakdown } — `breakdown` separa `active_connect` (conexões de sub-clientes do Connect) de `active_own` (conexões próprias), contadas pela mesma fonte (WhatsApp + Instagram). Sem efeitos colaterais.",
        "operationId": "get_connect_session",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_connect_capacity",
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        },
        "parameters": [
          {
            "name": "session",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "cs_..."
          }
        ]
      }
    },
    "/history/keys": {
      "post": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Registrar chave pública",
        "description": "Registra a chave PÚBLICA P-256 (SPKI/DER em base64) que selará o histórico. Devolve `id`, `fingerprint`, `key_id`, `scope`, `challenge_ref`, `challenge_sealed` e `expires_in_seconds` (900). O `challenge_sealed` é um blob cifrado de verdade, para você provar a decifragem ANTES de gastar a janela única da Meta — abra com **`kind: \"k\"`, `ref` = `challenge_ref`, `session_id` = o `id` desta resposta** (o desafio não pertence a uma sessão de sincronização), e devolva o campo `k` do JSON. Material PRIVADO enviado por engano é recusado (`private_key_rejected`) sem gravar. Escopos: `account` (cobre toda a cadeia Connect), `client` (default) ou `number`.",
        "operationId": "post_history_keys",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "history_keys_register": {
                  "summary": "Registrar chave pública",
                  "description": "Registra a chave PÚBLICA P-256 (SPKI/DER em base64) que selará o histórico. Devolve `id`, `fingerprint`, `key_id`, `scope`, `challenge_ref`, `challenge_sealed` e `expires_in_seconds` (900). O `challenge_sealed` é um blob cifrado de verdade, para você provar a decifragem ANTES de gastar a janela única da Meta — abra com **`kind: \"k\"`, `ref` = `challenge_ref`, `session_id` = o `id` desta resposta** (o desafio não pertence a uma sessão de sincronização), e devolva o campo `k` do JSON. Material PRIVADO enviado por engano é recusado (`private_key_rejected`) sem gravar. Escopos: `account` (cobre toda a cadeia Connect), `client` (default) ou `number`.",
                  "value": {
                    "public_key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...",
                    "scope": "client"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      },
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Listar chaves",
        "description": "Lista as chaves registradas da conta (escopo, fingerprint, verificada ou não, revogada ou não). NUNCA devolve material de chave.",
        "operationId": "get_history_keys",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_keys",
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/keys/{fingerprint}/verify": {
      "post": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Provar posse da chave",
        "description": "Fecha a prova de posse: decifre o `challenge_sealed` recebido no registro e devolva o campo `k` do JSON decifrado. Sem esta verificação o disparo do histórico é RECUSADO — é o teste de que sua decifragem funciona antes de a Meta mandar o dado real (ela manda UMA vez). A verificação é permanente por chave.",
        "operationId": "post_history_keys_fingerprint_verify",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "fingerprint",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "{fingerprint}"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "history_keys_verify": {
                  "summary": "Provar posse da chave",
                  "description": "Fecha a prova de posse: decifre o `challenge_sealed` recebido no registro e devolva o campo `k` do JSON decifrado. Sem esta verificação o disparo do histórico é RECUSADO — é o teste de que sua decifragem funciona antes de a Meta mandar o dado real (ela manda UMA vez). A verificação é permanente por chave.",
                  "value": {
                    "plaintext_b64": "sZ3q..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/keys/{fingerprint}": {
      "delete": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Revogar chave",
        "description": "Revoga a chave em TODOS os escopos onde o mesmo material apareça. Se houver importação viva cifrada para ela, a rota recusa e explica: revogar tornaria aquele buffer ilegível para sempre (a Meta não reenvia) — repita com `?confirm=destroy_buffer` para revogar E apagar o buffer imediatamente.",
        "operationId": "delete_history_keys_fingerprint",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "fingerprint",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "{fingerprint}"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history": {
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Estado da importação",
        "description": "Estado da sessão de importação deste número: `sync_complete` (progresso 100 em toda fase E nenhum chunk faltando — é o SINAL DE FIM; não existe evento push de fim), `progress_by_phase`, `missing_chunks`, retenção. Rota do trilho por número (autentica pela chave hai_live_ do dono/agência; chave somente-leitura não faz POST/DELETE).",
        "operationId": "get_history",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_status",
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      },
      "delete": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Apagar o buffer agora",
        "description": "Apaga TODO o buffer deste número imediatamente, entregue ou não — a Meta não reenvia. É o \"terminei/desisto\" explícito. Sem ele, o TTL de 24h apaga sozinho de qualquer forma: o ack e o DELETE só ADIANTAM o apagamento, nunca o adiam.",
        "operationId": "delete_history",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/sync": {
      "post": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Disparar a importação",
        "description": "Dispara a sync manual (config `mode: manual`; em `auto` o onboarding já disparou). A janela da Meta é ÚNICA e de ~24h pós-onboarding de coexistência: o disparo exige chave VERIFICADA e consome a chance — por isso o desafio de posse vem antes. `sync_type`: `both` (default) ou `history` (sem agenda). A resposta traz `retention_hours_effective`, `retention_hours_configured` e `retention_reason`: na PRIMEIRA importação da conta o prazo é forçado a 24h (`first_sync_grace`) porque a Meta não reenvia — se você configurou menos, o seu prazo volta a valer da segunda em diante.",
        "operationId": "post_history_sync",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_sync",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "history_sync": {
                  "summary": "Disparar a importação",
                  "description": "Dispara a sync manual (config `mode: manual`; em `auto` o onboarding já disparou). A janela da Meta é ÚNICA e de ~24h pós-onboarding de coexistência: o disparo exige chave VERIFICADA e consome a chance — por isso o desafio de posse vem antes. `sync_type`: `both` (default) ou `history` (sem agenda). A resposta traz `retention_hours_effective`, `retention_hours_configured` e `retention_reason`: na PRIMEIRA importação da conta o prazo é forçado a 24h (`first_sync_grace`) porque a Meta não reenvia — se você configurou menos, o seu prazo volta a valer da segunda em diante.",
                  "value": {
                    "sync_type": "both"
                  },
                  "x-mcp-tool": "integra_history_sync"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/config": {
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Config efetiva",
        "description": "Config EFETIVA do número (herança conta→cliente→número + veto do dono já resolvidos) + `contacts_effective`: a agenda só sincroniza com o aceite legal SEPARADO `history_contacts` — o `include_contacts` da config sozinho não basta. `max_age_days` (1–180) é o corte de idade da importação, aplicado no INGEST (mensagem mais antiga que o corte, contado do disparo, não é gravada); `retention_hours` (1–24) é quanto o buffer vive — forçado a 24h na primeira importação da conta (`first_sync_grace`). Somente leitura DE PROPÓSITO: escrever é pelo Connect (config.history no create_session) ou painel, nunca por esta rota — o veto do dono não pode ser sobrescrevível pela API do parceiro.",
        "operationId": "get_history_config",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_config",
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/echo": {
      "post": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Echo de decifragem (dry-run)",
        "description": "Mande um `plaintext` (≤512 chars) e receba-o SELADO com a sua chave verificada — o teste de fumaça do seu pipeline de decifragem com o formato de fio real, sem gastar nada. Use no CI: se o echo abre, o histórico abre. A resposta traz `sealed` (base64 do envelope) e o bloco **`aad`** já pronto — `{ \"session_id\": \"echo\", \"ref\": \"echo\", \"kind\": \"m\" }` —, além de `key_fingerprint` e `suite`. O JSON decifrado é `{ \"b\": \"<seu plaintext>\" }`.",
        "operationId": "post_history_echo",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_echo",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "history_echo": {
                  "summary": "Echo de decifragem (dry-run)",
                  "description": "Mande um `plaintext` (≤512 chars) e receba-o SELADO com a sua chave verificada — o teste de fumaça do seu pipeline de decifragem com o formato de fio real, sem gastar nada. Use no CI: se o echo abre, o histórico abre. A resposta traz `sealed` (base64 do envelope) e o bloco **`aad`** já pronto — `{ \"session_id\": \"echo\", \"ref\": \"echo\", \"kind\": \"m\" }` —, além de `key_fingerprint` e `suite`. O JSON decifrado é `{ \"b\": \"<seu plaintext>\" }`.",
                  "value": {
                    "plaintext": "ping-decifragem-ci"
                  },
                  "x-mcp-tool": "integra_history_echo"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/messages": {
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Puxar mensagens (paginado)",
        "description": "Página de mensagens SELADAS na ordem canônica (ts, msg_ref). `next_cursor` vem em TODA página com linha servida (inclusive a última) — fim é `has_more: false`, nunca a nulidade do cursor; é o cursor que você manda no ack. Corte por bytes (`truncated_by_bytes`) para páginas caberem no seu teto de request. Antes de `sync_complete: true` a rota recusa com 409 (`?allow_partial=true` lê o parcial, mas o ack fica bloqueado — confirmar importação furada apagaria o que ainda vai chegar).",
        "operationId": "get_history_messages",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "200"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/contacts": {
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Puxar agenda (paginado)",
        "description": "Página da agenda importada, SELADA, em ordem de aplicação `(chunk_seq, row_index)` — aplicar fora de ordem inverte add/remove. Cada linha traz `aad_ref` (`\"chunk_seq:row_index\"`): é EXATAMENTE a string do AAD da decifragem. Só existe com o aceite legal `history_contacts` na conta. O `next_cursor` daqui confirma a AGENDA no mesmo POST /history/ack.",
        "operationId": "get_history_contacts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "200"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/summary": {
      "get": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Resumo (sem PII)",
        "description": "Contagens e distribuição por tipo, faixa de datas — SEM conteúdo e SEM telefones. Resposta com cache de até 60s (`as_of` diz de quando é; `cached` diz se veio do cache) — pode fazer polling sem custo. Não existe `/history/threads` de propósito: agrupar por conversa no servidor exigiria pseudônimo de telefone (~33 bits de entropia — reversível em segundos), o que quebraria a garantia de ilegibilidade. Agrupe DEPOIS de decifrar, do seu lado.",
        "operationId": "get_history_summary",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-mcp-tool": "integra_history_summary",
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    },
    "/history/ack": {
      "post": {
        "tags": [
          "API de Histórico (coexistência)"
        ],
        "summary": "Confirmar entrega (apaga)",
        "description": "Confirme o `next_cursor` da última página que você PERSISTIU — apagamos tudo até ali, imediatamente. Cursor de /messages confirma MENSAGENS; cursor de /contacts confirma AGENDA (`scope` na resposta). A sessão fecha (`drained: true`) quando AS DUAS zeram. Clamp real: confirmar além do servido = 409 `ack_beyond_served`. Desistência por perda da chave privada: `{\"decrypt_ok\": false, \"reason\": \"...\"}` apaga o buffer inteiro na hora. Retry-safe e idempotente.",
        "operationId": "post_history_ack",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "examples": {
                "history_ack": {
                  "summary": "Confirmar entrega (apaga)",
                  "description": "Confirme o `next_cursor` da última página que você PERSISTIU — apagamos tudo até ali, imediatamente. Cursor de /messages confirma MENSAGENS; cursor de /contacts confirma AGENDA (`scope` na resposta). A sessão fecha (`drained: true`) quando AS DUAS zeram. Clamp real: confirmar além do servido = 409 `ack_beyond_served`. Desistência por perda da chave privada: `{\"decrypt_ok\": false, \"reason\": \"...\"}` apaga o buffer inteiro na hora. Retry-safe e idempotente.",
                  "value": {
                    "cursor": "hc2..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "4XX": {
            "description": "Erro de validação/autorização"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "hai_live_...",
        "description": "Chave de API HypeAi Integra (hai_live_...), gerada no painel."
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ]
}
