# HypeAi Integra — Referência completa da API (para LLMs) > 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). Base (Gestão/Connect): `https://api.hypeai.com.br` Base (Gateway WhatsApp): `https://api.hypeai.com.br` Contrato OpenAPI: https://integra.hypeai.com.br/openapi.json Documentação navegável: https://integra.hypeai.com.br/docs Operável por IA (MCP): https://mcp.integra.hypeai.com.br/mcp Autenticação: header `Authorization: Bearer hai_live_...` (chave gerada no painel). `{phone_number_id}` é o ID do número conectado. Substitua `PHONE_NUMBER_ID` e `hai_live_SEU_TOKEN`. Como o gateway REST funciona (evita os enganos mais comuns): - Todo caminho do WhatsApp é ESCOPADO POR NÚMERO: `/v1/{phone_number_id}/...`. Para DESCOBRIR seus números use `GET /v1` (lista os seus phone_number_id) ou o MCP (`integra_list_numbers`) / painel. Outros nomes de listagem (`GET /v1/numbers`, `/connections`, `/account`) NÃO existem → 404. - Recebimento é por WEBHOOK, não por polling: a plataforma é no-store/relay e NÃO guarda histórico. Você NÃO lê mensagens com `GET /v1/{phone_number_id}/messages` (responde 405) — mensagens são ENVIADAS com `POST /v1/{phone_number_id}/messages` e RECEBIDAS no seu endpoint de webhook. ## API de WhatsApp — Gateway 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. Auth: `Authorization: Bearer hai_live_... (aceita o header opcional Idempotency-Key p/ não duplicar em retentativa)` ### Mensagens #### Enviar texto `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` 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. Ferramenta de IA (MCP) equivalente: `whatsapp_send_text` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `body` (obrigatório): Texto — ex.: `Olá! 👋 Sua mensagem via HypeAi Integra.` - `preview_url` (opcional): Prévia de link (true/false) — ex.: `true` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "text", "text": { "body": "Olá! 👋 Sua mensagem via HypeAi Integra.", "preview_url": true } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "text", "text": { "body": "Olá! 👋 Sua mensagem via HypeAi Integra.", "preview_url": true } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar template `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Template aprovado: o único jeito de iniciar conversa fora da janela de 24h. Use `components` para preencher variáveis. Ferramenta de IA (MCP) equivalente: `whatsapp_send_template` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `name` (obrigatório): Nome do template — ex.: `hello_world` - `lang` (obrigatório): Idioma (code) — ex.: `en_US` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#template-object #### Enviar imagem `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Imagem por URL pública (JPG/PNG) ou por media id (após upload). Ferramenta de IA (MCP) equivalente: `whatsapp_send_media` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `link` (obrigatório): URL da imagem — ex.: `https://exemplo.com/foto.jpg` - `caption` (opcional): Legenda (opcional) Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "image", "image": { "link": "https://exemplo.com/foto.jpg" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "image", "image": { "link": "https://exemplo.com/foto.jpg" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar vídeo `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Vídeo por URL pública (MP4) ou media id. Ferramenta de IA (MCP) equivalente: `whatsapp_send_media` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `link` (obrigatório): URL do vídeo — ex.: `https://exemplo.com/video.mp4` - `caption` (opcional): Legenda (opcional) Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "video", "video": { "link": "https://exemplo.com/video.mp4" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "video", "video": { "link": "https://exemplo.com/video.mp4" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar áudio `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Áudio por URL pública (OGG/MP3) ou media id. Sem legenda. Ferramenta de IA (MCP) equivalente: `whatsapp_send_media` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `link` (obrigatório): URL do áudio — ex.: `https://exemplo.com/audio.ogg` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "audio", "audio": { "link": "https://exemplo.com/audio.ogg" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "audio", "audio": { "link": "https://exemplo.com/audio.ogg" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar documento `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Arquivo por URL pública (PDF, etc.) ou media id. Ferramenta de IA (MCP) equivalente: `whatsapp_send_media` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `link` (obrigatório): URL do arquivo — ex.: `https://exemplo.com/contrato.pdf` - `filename` (opcional): Nome do arquivo (opcional) — ex.: `contrato.pdf` - `caption` (opcional): Legenda (opcional) Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "document", "document": { "link": "https://exemplo.com/contrato.pdf", "filename": "contrato.pdf" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "document", "document": { "link": "https://exemplo.com/contrato.pdf", "filename": "contrato.pdf" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar localização `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Compartilha um ponto no mapa. Ferramenta de IA (MCP) equivalente: `whatsapp_send_location` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `lat` (obrigatório): Latitude — ex.: `-23.5613` - `lng` (obrigatório): Longitude — ex.: `-46.6565` - `name` (opcional): Nome (opcional) — ex.: `Av. Paulista` - `address` (opcional): Endereço (opcional) — ex.: `Av. Paulista, 1000 - São Paulo` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "location", "location": { "latitude": -23.5613, "longitude": -46.6565, "name": "Av. Paulista", "address": "Av. Paulista, 1000 - São Paulo" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "location", "location": { "latitude": -23.5613, "longitude": -46.6565, "name": "Av. Paulista", "address": "Av. Paulista, 1000 - São Paulo" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Enviar contato `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Envia um cartão de contato (vCard). Ferramenta de IA (MCP) equivalente: `whatsapp_send_contacts` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `cname` (obrigatório): Nome do contato — ex.: `Maria Souza` - `cphone` (obrigatório): Telefone do contato — ex.: `5511988887777` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "contacts", "contacts": [ { "name": { "formatted_name": "Maria Souza", "first_name": "Maria" }, "phones": [ { "phone": "5511988887777", "type": "CELL" } ] } ] } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "contacts", "contacts": [ { "name": { "formatted_name": "Maria Souza", "first_name": "Maria" }, "phones": [ { "phone": "5511988887777", "type": "CELL" } ] } ] }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages #### Reagir (emoji) `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Reage a uma mensagem recebida com um emoji. Use o wamid que chegou no seu webhook. Ferramenta de IA (MCP) equivalente: `whatsapp_send_reaction` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `mid` (obrigatório): ID da mensagem (wamid) — ex.: `wamid.HBgM...` - `emoji` (obrigatório): Emoji — ex.: `👍` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "to": "5511999999999", "type": "reaction", "reaction": { "message_id": "wamid.HBgM...", "emoji": "👍" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "5511999999999", "type": "reaction", "reaction": { "message_id": "wamid.HBgM...", "emoji": "👍" } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages ### Interativo #### Botões de resposta `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Até 3 botões de resposta rápida (dentro da janela de 24h). Ferramenta de IA (MCP) equivalente: `whatsapp_send_interactive` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `body` (obrigatório): Texto — ex.: `Como podemos ajudar?` - `b1` (obrigatório): Botão 1 — ex.: `Falar com vendas` - `b2` (opcional): Botão 2 (opcional) — ex.: `Suporte` - `b3` (opcional): Botão 3 (opcional) — ex.: `Outro assunto` Corpo de exemplo (JSON): ```json { "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" } } ] } } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" } } ] } } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#interactive-object #### Lista de opções `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Menu com seções e itens selecionáveis (dentro da janela de 24h). Ferramenta de IA (MCP) equivalente: `whatsapp_send_interactive` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `to` (obrigatório): Para (número com DDI) — ex.: `5511999999999` - `body` (obrigatório): Texto — ex.: `Escolha uma opção:` - `button` (obrigatório): Texto do botão — ex.: `Ver opções` - `r1` (obrigatório): Item 1 — ex.: `Plano Básico` - `r2` (opcional): Item 2 (opcional) — ex.: `Plano Pro` Corpo de exemplo (JSON): ```json { "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" } ] } ] } } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" } ] } ] } } }' ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#interactive-object ### Status #### Marcar como lida `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Marca uma mensagem recebida como lida (os ✓✓ azuis). Use o wamid que chegou no seu webhook. Ferramenta de IA (MCP) equivalente: `whatsapp_mark_read` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `mid` (obrigatório): ID da mensagem (wamid) — ex.: `wamid.HBgM...` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "status": "read", "message_id": "wamid.HBgM..." } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "status": "read", "message_id": "wamid.HBgM..." }' ``` #### Indicador de digitação `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages` Mostra “digitando…” ao contato (e marca como lida). Some sozinho em ~25s ou quando você responde. Ferramenta de IA (MCP) equivalente: `whatsapp_send_typing` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `mid` (obrigatório): ID da mensagem (wamid) — ex.: `wamid.HBgM...` Corpo de exemplo (JSON): ```json { "messaging_product": "whatsapp", "status": "read", "message_id": "wamid.HBgM...", "typing_indicator": { "type": "text" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "status": "read", "message_id": "wamid.HBgM...", "typing_indicator": { "type": "text" } }' ``` ### Mídia #### Baixar mídia recebida `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/media/{media_id}` 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). Ferramenta de IA (MCP) equivalente: `whatsapp_get_media_url` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/media/{media_id}" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media ### Número #### Dados do número `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID?fields=verified_name,display_phone_number,quality_rating,code_verification_status` Metadados do número conectado (nome verificado, qualidade, status de verificação). Ferramenta de IA (MCP) equivalente: `whatsapp_get_phone` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID?fields=verified_name,display_phone_number,quality_rating,code_verification_status" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Desconectar número `DELETE https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/connection` 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. Ferramenta de IA (MCP) equivalente: `integra_disconnect_number` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X DELETE \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/connection" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ## API de Instagram (beta) — Canal 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. Auth: `Authorization: Bearer hai_live_... (mesma chave da API de WhatsApp; aceita Idempotency-Key)` ### Mensagens (DM) #### Responder DM (texto) `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages` 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. Ferramenta de IA (MCP) equivalente: `instagram_send_message` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `recipient_id` (obrigatório): IGSID do destinatário (sender.id do webhook) — ex.: `6697308663720723` - `text` (obrigatório): Texto — ex.: `Oi! Recebemos sua mensagem 👋` Corpo de exemplo (JSON): ```json { "recipient": { "id": "6697308663720723" }, "message": { "text": "Oi! Recebemos sua mensagem 👋" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "recipient": { "id": "6697308663720723" }, "message": { "text": "Oi! Recebemos sua mensagem 👋" } }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api #### Responder DM (mídia por URL) `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages` 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). Ferramenta de IA (MCP) equivalente: `instagram_send_message` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `recipient_id` (obrigatório): IGSID do destinatário (sender.id do webhook) — ex.: `6697308663720723` - `type` (obrigatório): Tipo — ex.: `image` - `url` (obrigatório): URL https da mídia — ex.: `https://exemplo.com/foto.jpg` Corpo de exemplo (JSON): ```json { "recipient": { "id": "6697308663720723" }, "message": { "attachment": { "type": "image", "payload": { "url": "https://exemplo.com/foto.jpg" } } } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "recipient": { "id": "6697308663720723" }, "message": { "attachment": { "type": "image", "payload": { "url": "https://exemplo.com/foto.jpg" } } } }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api #### Responder DM com botões `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages` Texto + até 13 botões de resposta rápida. O clique volta pro seu webhook no evento ig_postbacks com o `payload` escolhido. Ferramenta de IA (MCP) equivalente: `instagram_send_message` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `recipient_id` (obrigatório): IGSID do destinatário (sender.id do webhook) — ex.: `6697308663720723` - `text` (obrigatório): Texto — ex.: `Como posso ajudar?` - `b1` (obrigatório): Botão 1 (rótulo) — ex.: `Ver preços` - `b2` (obrigatório): Botão 2 (rótulo) — ex.: `Falar com humano` Corpo de exemplo (JSON): ```json { "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" } ] } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" } ] } }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api #### Reagir a uma DM `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages` Reage (ou remove a reação) a uma mensagem recebida. `sender_action`: react | unreact. O message_id é o `mid` do webhook. Ferramenta de IA (MCP) equivalente: `instagram_send_message` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `recipient_id` (obrigatório): IGSID do destinatário (sender.id do webhook) — ex.: `6697308663720723` - `message_id` (obrigatório): mid da mensagem — ex.: `aWdfZAG1faXRlbToxOklHTWV…` Corpo de exemplo (JSON): ```json { "recipient": { "id": "6697308663720723" }, "sender_action": "react", "payload": { "message_id": "aWdfZAG1faXRlbToxOklHTWV…", "reaction": "love" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "recipient": { "id": "6697308663720723" }, "sender_action": "react", "payload": { "message_id": "aWdfZAG1faXRlbToxOklHTWV…", "reaction": "love" } }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api #### Responder comentário no privado `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages` 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'). Ferramenta de IA (MCP) equivalente: `instagram_private_reply` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `comment_id` (obrigatório): comment_id — ex.: `17984512345678901` - `text` (obrigatório): Texto da DM — ex.: `Oi! Respondendo por aqui 🙂` Corpo de exemplo (JSON): ```json { "recipient": { "comment_id": "17984512345678901" }, "message": { "text": "Oi! Respondendo por aqui 🙂" } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/messages" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "recipient": { "comment_id": "17984512345678901" }, "message": { "text": "Oi! Respondendo por aqui 🙂" } }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api ### Publicação #### Publicar foto (feed) `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts` 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. Ferramenta de IA (MCP) equivalente: `instagram_create_post` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `image_url` (obrigatório): URL https da imagem (JPEG) — ex.: `https://exemplo.com/foto.jpg` - `caption` (obrigatório): Legenda — ex.: `Nosso novo produto 🚀 #lancamento` Corpo de exemplo (JSON): ```json { "image_url": "https://exemplo.com/foto.jpg", "caption": "Nosso novo produto 🚀 #lancamento" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://exemplo.com/foto.jpg", "caption": "Nosso novo produto 🚀 #lancamento" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing #### Publicar Reel `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts` 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. Ferramenta de IA (MCP) equivalente: `instagram_create_post` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `video_url` (obrigatório): URL https do vídeo (MP4) — ex.: `https://exemplo.com/reel.mp4` - `caption` (obrigatório): Legenda — ex.: `Bastidores da semana 🎬` - `cover_url` (opcional): Capa (JPEG, opcional) — ex.: `https://exemplo.com/capa.jpg` Corpo de exemplo (JSON): ```json { "media_type": "REELS", "video_url": "https://exemplo.com/reel.mp4", "caption": "Bastidores da semana 🎬", "cover_url": "https://exemplo.com/capa.jpg" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "media_type": "REELS", "video_url": "https://exemplo.com/reel.mp4", "caption": "Bastidores da semana 🎬", "cover_url": "https://exemplo.com/capa.jpg" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing #### Publicar Story `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts` 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). Ferramenta de IA (MCP) equivalente: `instagram_create_post` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `image_url` (obrigatório): URL https da imagem (JPEG) — ex.: `https://exemplo.com/story.jpg` Corpo de exemplo (JSON): ```json { "media_type": "STORIES", "image_url": "https://exemplo.com/story.jpg" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "media_type": "STORIES", "image_url": "https://exemplo.com/story.jpg" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing #### Publicar carrossel `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts` 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. Ferramenta de IA (MCP) equivalente: `instagram_create_post` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `img1` (obrigatório): URL da imagem 1 (JPEG) — ex.: `https://exemplo.com/1.jpg` - `img2` (obrigatório): URL da imagem 2 (JPEG) — ex.: `https://exemplo.com/2.jpg` - `caption` (obrigatório): Legenda — ex.: `Antes e depois ✨` Corpo de exemplo (JSON): ```json { "children": [ { "image_url": "https://exemplo.com/1.jpg" }, { "image_url": "https://exemplo.com/2.jpg" } ], "caption": "Antes e depois ✨" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/posts" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "children": [ { "image_url": "https://exemplo.com/1.jpg" }, { "image_url": "https://exemplo.com/2.jpg" } ], "caption": "Antes e depois ✨" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing #### Concluir publicação (creation_id) `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/media_publish` 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. Ferramenta de IA (MCP) equivalente: `instagram_create_post` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `creation_id` (obrigatório): creation_id — ex.: `17998765432101234` Corpo de exemplo (JSON): ```json { "creation_id": "17998765432101234" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/media_publish" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "creation_id": "17998765432101234" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing #### Cota de publicação (24h) `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID/content_publishing_limit?fields=quota_usage,config` Quanto do teto de 100 publicações/24h da conta já foi usado. Cheque antes de rodadas grandes de publicação. Ferramenta de IA (MCP) equivalente: `instagram_get_publishing_limit` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/content_publishing_limit?fields=quota_usage,config" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/content-publishing ### Comentários #### Listar comentários de um post `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID/{media_id}/comments?fields=id,text,username,timestamp,like_count,hidden,replies{id,text,username}` 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. Ferramenta de IA (MCP) equivalente: `instagram_list_comments` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/{media_id}/comments?fields=id,text,username,timestamp,like_count,hidden,replies{id,text,username}" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation #### Responder comentário (público) `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}/replies` 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). Ferramenta de IA (MCP) equivalente: `instagram_reply_comment` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `message` (obrigatório): Resposta — ex.: `Obrigado pelo comentário! 💜` Corpo de exemplo (JSON): ```json { "message": "Obrigado pelo comentário! 💜" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}/replies" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "message": "Obrigado pelo comentário! 💜" }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation #### Ocultar / reexibir comentário `POST https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}` Oculta (hide=true) ou reexibe (hide=false) um comentário — substitua {comment_id}. Reversível — é a moderação recomendada; apagar é definitivo. Ferramenta de IA (MCP) equivalente: `instagram_moderate_comment` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `hide` (obrigatório): Ocultar? (true/false) — ex.: `true` Corpo de exemplo (JSON): ```json { "hide": true } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "hide": true }' ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation #### Apagar comentário `DELETE https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}` Apaga o comentário DEFINITIVAMENTE (irreversível) — substitua {comment_id}. Prefira ocultar quando a intenção for só tirar do público. Ferramenta de IA (MCP) equivalente: `instagram_moderate_comment` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X DELETE \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/{comment_id}" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/comment-moderation ### Insights #### Métricas de um post `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID/{media_id}/insights?metric=reach,likes,comments,saved,shares,views` 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. Ferramenta de IA (MCP) equivalente: `instagram_get_media_insights` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/{media_id}/insights?metric=reach,likes,comments,saved,shares,views" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/insights #### Métricas da conta `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID/insights?metric=reach,views,accounts_engaged&period=day&metric_type=total_value` 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. Ferramenta de IA (MCP) equivalente: `instagram_get_account_insights` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/insights?metric=reach,views,accounts_engaged&period=day&metric_type=total_value" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` Referência Meta: https://developers.facebook.com/docs/instagram-platform/insights ### Conta #### Perfil da conta `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID?fields=username,name,biography,website,followers_count,media_count,profile_picture_url,account_type` 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. Ferramenta de IA (MCP) equivalente: `instagram_get_profile` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID?fields=username,name,biography,website,followers_count,media_count,profile_picture_url,account_type" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Listar mídias publicadas `GET https://api.hypeai.com.br/v1/ig/IG_USER_ID/media?fields=id,media_type,media_url,permalink,caption,timestamp,like_count,comments_count&limit=25` 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. Ferramenta de IA (MCP) equivalente: `instagram_list_media` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/ig/IG_USER_ID/media?fields=id,media_type,media_url,permalink,caption,timestamp,like_count,comments_count&limit=25" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ## API HypeAi Integra (beta) — Gestão 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. Auth: `Authorization: Bearer hai_live_... (mesma chave da API de WhatsApp)` ### Analytics #### Analytics da conta `POST https://api.hypeai.com.br/client-analytics` Métricas ao vivo da Meta (conversas, custo, entrega) com cache. Corpo: { period }. Ferramenta de IA (MCP) equivalente: `integra_get_meta_analytics` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `period` (obrigatório): Período — ex.: `7d` Corpo de exemplo (JSON): ```json { "period": "7d" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/client-analytics" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "period": "7d" }' ``` ### Uso & Custo #### Pacotes de mensagens (listar) `POST https://api.hypeai.com.br/quota-manage` Lista os pacotes (quotas mensais com rollover) e o saldo/consumo do ciclo corrente. Ferramenta de IA (MCP) equivalente: `integra_get_quota` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Corpo de exemplo (JSON): ```json { "action": "list" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/quota-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "list" }' ``` #### Pacote de mensagens (criar/editar) `POST https://api.hypeai.com.br/quota-manage` 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. Ferramenta de IA (MCP) equivalente: `integra_set_quota` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `phone_number_id` (opcional): phone_number_id (opcional) — ex.: `123456789012345` - `monthly_allowance` (obrigatório): Limite mensal (msgs) — ex.: `1000` - `rollover_enabled` (obrigatório): Rollover (true/false) — ex.: `false` - `rollover_expiry_months` (opcional): Saldo vence em X meses (opcional) — ex.: `3` Corpo de exemplo (JSON): ```json { "action": "set", "phone_number_id": "123456789012345", "monthly_allowance": 1000, "rollover_enabled": false, "rollover_expiry_months": 3 } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/quota-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "set", "phone_number_id": "123456789012345", "monthly_allowance": 1000, "rollover_enabled": false, "rollover_expiry_months": 3 }' ``` ### Números #### Perfil do número (ler) `POST https://api.hypeai.com.br/number-profile-manage` Lê o perfil comercial do número (sobre, descrição, endereço, sites, vertical). Ferramenta de IA (MCP) equivalente: `integra_get_number_profile` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `phone_number_id` (obrigatório): phone_number_id — ex.: `123456789012345` Corpo de exemplo (JSON): ```json { "action": "get", "phone_number_id": "123456789012345" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/number-profile-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "get", "phone_number_id": "123456789012345" }' ``` #### Perfil do número (editar) `POST https://api.hypeai.com.br/number-profile-manage` Atualiza campos do perfil comercial (verified_name é read-only). Ferramenta de IA (MCP) equivalente: `integra_update_number_profile` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `phone_number_id` (obrigatório): phone_number_id — ex.: `123456789012345` - `about` (obrigatório): Sobre — ex.: `Atendimento oficial` - `description` (obrigatório): Descrição — ex.: `Sua empresa em uma linha.` Corpo de exemplo (JSON): ```json { "action": "update", "phone_number_id": "123456789012345", "about": "Atendimento oficial", "description": "Sua empresa em uma linha." } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/number-profile-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "update", "phone_number_id": "123456789012345", "about": "Atendimento oficial", "description": "Sua empresa em uma linha." }' ``` #### Re-sincronizar números `POST https://api.hypeai.com.br/sync-phone-numbers` Re-sincroniza seus números com a Meta (nome, qualidade, tier). Operação de manutenção. Ferramenta de IA (MCP) equivalente: `integra_sync_numbers` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Corpo de exemplo (JSON): ```json {} ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/sync-phone-numbers" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{}' ``` ### Templates #### Atualizar status de templates `POST https://api.hypeai.com.br/client-templates-status` 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. Ferramenta de IA (MCP) equivalente: `integra_refresh_templates` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `credential_id` (opcional): credential_id (multi-WABA, opcional) — ex.: `uuid da credencial` Corpo de exemplo (JSON): ```json { "force": true, "credential_id": "uuid da credencial" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/client-templates-status" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "force": true, "credential_id": "uuid da credencial" }' ``` #### Criar template `POST https://api.hypeai.com.br/manage-templates` 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). Ferramenta de IA (MCP) equivalente: `integra_create_template` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `template` (obrigatório): template (JSON da Cloud API) — ex.: `{"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` (opcional): credential_id (multi-WABA, opcional) — ex.: `uuid da credencial` - `client_id` (opcional): client_id (chave de agência: sub-cliente, opcional) — ex.: `uuid do sub-cliente` Corpo de exemplo (JSON): ```json { "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" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/manage-templates" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" }' ``` #### Editar template `POST https://api.hypeai.com.br/manage-templates` 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. Ferramenta de IA (MCP) equivalente: `integra_update_template` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `template_id` (obrigatório): template_id (id na Meta) — ex.: `123456789012345` - `template` (obrigatório): template (JSON: components e/ou category) — ex.: `{"components":[{"type":"BODY","text":"Novo texto {{1}}","example":{"body_text":[["Maria"]]}}]}` - `credential_id` (opcional): credential_id (multi-WABA, opcional) — ex.: `uuid da credencial` - `client_id` (opcional): client_id (chave de agência: sub-cliente, opcional) — ex.: `uuid do sub-cliente` Corpo de exemplo (JSON): ```json { "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" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/manage-templates" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" }' ``` #### Remover template `POST https://api.hypeai.com.br/manage-templates` 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). Ferramenta de IA (MCP) equivalente: `integra_delete_template` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `name` (obrigatório): Nome do template — ex.: `confirmacao_pedido` - `template_id` (opcional): template_id (opcional: só esta língua/edição) — ex.: `123456789012345` - `credential_id` (opcional): credential_id (multi-WABA, opcional) — ex.: `uuid da credencial` - `client_id` (opcional): client_id (chave de agência: sub-cliente, opcional) — ex.: `uuid do sub-cliente` Corpo de exemplo (JSON): ```json { "action": "delete", "name": "confirmacao_pedido", "template_id": "123456789012345", "credential_id": "uuid da credencial", "client_id": "uuid do sub-cliente" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/manage-templates" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "delete", "name": "confirmacao_pedido", "template_id": "123456789012345", "credential_id": "uuid da credencial", "client_id": "uuid do sub-cliente" }' ``` #### Subir mídia de exemplo (header) `POST https://api.hypeai.com.br/manage-templates` 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). Ferramenta de IA (MCP) equivalente: `integra_upload_template_example` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `file_url` (obrigatório): file_url (URL https pública) — ex.: `https://exemplo.com/banner.jpg` - `file_type` (opcional): file_type (MIME, opcional) — ex.: `image/jpeg` - `credential_id` (opcional): credential_id (multi-WABA, opcional) — ex.: `uuid da credencial` - `client_id` (opcional): client_id (chave de agência: sub-cliente, opcional) — ex.: `uuid do sub-cliente` Corpo de exemplo (JSON): ```json { "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" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/manage-templates" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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" }' ``` ### Webhooks #### Listar webhooks `POST https://api.hypeai.com.br/webhooks-manage` Lista os webhooks de saída configurados na conta. Ferramenta de IA (MCP) equivalente: `integra_list_webhooks` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Corpo de exemplo (JSON): ```json { "action": "list" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/webhooks-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "list" }' ``` #### Criar webhook `POST https://api.hypeai.com.br/webhooks-manage` 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 é. Ferramenta de IA (MCP) equivalente: `integra_create_webhook` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `name` (obrigatório): Nome — ex.: `Meu webhook` - `url` (obrigatório): URL de destino — ex.: `https://exemplo.com/webhook` - `events` (obrigatório): Eventos (separados por vírgula) — ex.: `messages,message_status` Corpo de exemplo (JSON): ```json { "action": "create", "name": "Meu webhook", "url": "https://exemplo.com/webhook", "events": [ "messages", "message_status" ], "all_numbers": true } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/webhooks-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "create", "name": "Meu webhook", "url": "https://exemplo.com/webhook", "events": [ "messages", "message_status" ], "all_numbers": true }' ``` #### Editar webhook `POST https://api.hypeai.com.br/webhooks-manage` 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. Ferramenta de IA (MCP) equivalente: `integra_update_webhook` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `id` (obrigatório): id do webhook — ex.: `uuid do webhook` - `events` (obrigatório): Eventos (CSV; lista COMPLETA — substitui a atual) — ex.: `messages,message_status,smb_message_echoes` - `url` (opcional): URL de destino (opcional) — ex.: `https://exemplo.com/webhook` - `is_active` (opcional): is_active (opcional; true/false) — ex.: `true` Corpo de exemplo (JSON): ```json { "action": "update", "id": "uuid do webhook", "events": [ "messages", "message_status", "smb_message_echoes" ], "url": "https://exemplo.com/webhook", "is_active": true } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/webhooks-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "update", "id": "uuid do webhook", "events": [ "messages", "message_status", "smb_message_echoes" ], "url": "https://exemplo.com/webhook", "is_active": true }' ``` #### Rotacionar secret `POST https://api.hypeai.com.br/webhooks-manage` 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. Ferramenta de IA (MCP) equivalente: `integra_rotate_webhook_secret` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `id` (obrigatório): id do webhook — ex.: `uuid do webhook` Corpo de exemplo (JSON): ```json { "action": "rotate", "id": "uuid do webhook" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/webhooks-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "rotate", "id": "uuid do webhook" }' ``` #### Remover webhook `POST https://api.hypeai.com.br/webhooks-manage` Remove um webhook de saída pelo id. Ferramenta de IA (MCP) equivalente: `integra_delete_webhook` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `id` (obrigatório): id do webhook — ex.: `uuid do webhook` Corpo de exemplo (JSON): ```json { "action": "delete", "id": "uuid do webhook" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/webhooks-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "delete", "id": "uuid do webhook" }' ``` ### Integrações #### Listar Typebot `POST https://api.hypeai.com.br/integrations-manage` Lista as integrações Typebot da conta. Ferramenta de IA (MCP) equivalente: `integra_list_typebot_integrations` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Corpo de exemplo (JSON): ```json { "action": "list" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/integrations-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "list" }' ``` #### Listar Chatwoot `POST https://api.hypeai.com.br/chatwoot-integrations-manage` Lista as integrações Chatwoot da conta. Ferramenta de IA (MCP) equivalente: `integra_list_chatwoot_integrations` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Corpo de exemplo (JSON): ```json { "action": "list" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/chatwoot-integrations-manage" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "list" }' ``` ## API HypeAi Connect (beta) — Embed 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. Auth: `Authorization: Bearer hai_live_... (chave de escopo AGÊNCIA)` ### Conexão #### Criar sessão de conexão `POST https://api.hypeai.com.br/connect-session` 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). Ferramenta de IA (MCP) equivalente: `integra_connect_create_session` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `external_customer_id` (obrigatório): external_customer_id — ex.: `petshop-001` - `customer_name` (obrigatório): customer_name — ex.: `Patas & Cia` - `flow` (opcional): flow (opcional; any | standard | coexistence — trava o modo e esconde o seletor na tela do cliente final; só p/ whatsapp) — ex.: `coexistence` - `channel` (opcional): channel (opcional; whatsapp | instagram — Instagram em beta fechado; muda os events default p/ ig_messages,connection) — ex.: `whatsapp` - `webhook_url` (opcional): webhook_url (opcional) — ex.: `https://seu-saas.com/webhooks/hypeai` - `events` (opcional): events (opcional, CSV; default messages,message_status,connection; coexistência opt-in: +smb_message_echoes = eco do que o dono envia pelo celular, +history/smb_app_state_sync = histórico/contatos) — ex.: `messages,message_status,connection` - `allowed_origin` (opcional): allowed_origin (opcional; valida o postMessage do popup — NÃO use iframe) — ex.: `https://app.seu-saas.com` - `return_url` (opcional): return_url (opcional; mesma origem de allowed_origin) — ex.: `https://app.seu-saas.com/whatsapp/ok` - `connection_limit` (opcional): config.connection_limit (opcional; teto de CONEXÕES do sub-cliente — 1 WhatsApp OU 1 Instagram = 1 conexão. Alias legado: number_limit) — ex.: `2` - `quota_monthly_allowance` (opcional): config.quota.monthly_allowance (opcional; pacote mensal) — ex.: `1000` - `quota_rollover_enabled` (opcional): config.quota.rollover_enabled (opcional; true/false) — ex.: `false` Corpo de exemplo (JSON): ```json { "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 } } } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/connect-session" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "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 } } }' ``` #### Pré-checar capacidade do pool `GET https://api.hypeai.com.br/connect-session` 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. Ferramenta de IA (MCP) equivalente: `integra_connect_capacity` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/connect-session" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Status de sessão (o cliente conectou?) `GET https://api.hypeai.com.br/connect-session?session=cs_...` A resposta server-to-server para "o cliente final chegou a conectar?" — NÃO dependa só do webhook. `?session=cs_...` (o session_token do create) devolve AQUELA sessão: status efetivo (pending | connected | expired — a sessão vive 15 min, renováveis enquanto a página /c/ está aberta — teto de 60 min; expired = crie outra, é idempotente), `connect_url` enquanto viva, `workspace_id`, `channel`, `flow` (qual modo a tela ofereceu: any | standard | coexistence) e as conexões ATIVAS do sub-cliente com `phone_number_id`, `coexistence` (true = o número segue no app do celular e a importação de histórico é possível) e `onboarding_ref` (carimbo do Embedded Signup — muda a cada reconexão). `?sessions=1&limit=50&status=pending` lista o funil da conta (com `external_customer_id` para correlacionar com o SEU sistema). Escopo: só sessões da SUA conta. Ferramenta de IA (MCP) equivalente: `integra_connect_session_status` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `session` (opcional): session (token cs_... — detalhe de UMA sessão) — ex.: `cs_ab12...` - `status` (opcional): status (só na listagem: pending | connected | expired) — ex.: `pending` - `limit` (opcional): limit (só na listagem; 1-200, default 50) — ex.: `50` Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/connect-session?session=cs_..." \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Saúde do seu webhook `GET https://api.hypeai.com.br/connect-session?webhook_health=1&days=7` A outra metade do diagnóstico "o evento não chegou": foi o SEU endpoint? Totais na janela (`delivered` · `dead` = entrega desistida após 4xx permanente ou retries esgotados · `pending`), último sucesso, o estado de cada webhook dos seus sub-clientes (`consecutive_failures` e — o sinal mais acionável — `is_active:false` + `disabled_reason`, quando a plataforma DESATIVOU o webhook por falhas seguidas) e as 10 últimas falhas terminais com `status_code` e `error`. Corrigiu o endpoint? Reative com `webhooks-manage` (`action:"update"`, `is_active:true`) e reenvie entregas passadas com `integra_resend_webhook`. **O conteúdo dos eventos NÃO é retornado** — a plataforma é relay: nem o `payload` nem o corpo da resposta do seu servidor saem por aqui. `days`: 1–30 (default 7). Ferramenta de IA (MCP) equivalente: `integra_connect_webhook_health` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `days` (opcional): days (janela; 1-30, default 7) — ex.: `7` Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/connect-session?webhook_health=1&days=7" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ## API de Histórico (coexistência) (beta) — Beta 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. Auth: `Authorization: Bearer hai_live_... (chaves em /v1/history/keys são de CONTA; o resto é por número; chave somente-leitura não faz POST/DELETE)` ### Chaves #### Registrar chave pública `POST https://api.hypeai.com.br/v1/history/keys` 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`. Parâmetros: - `public_key` (obrigatório): public_key (SPKI/DER base64) — ex.: `MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...` - `scope` (obrigatório): scope (account | client | number) — ex.: `client` - `phone_number_id` (obrigatório): phone_number_id (só p/ scope=number) Corpo de exemplo (JSON): ```json { "public_key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...", "scope": "client" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/history/keys" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "public_key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...", "scope": "client" }' ``` #### Provar posse da chave `POST https://api.hypeai.com.br/v1/history/keys/{fingerprint}/verify` 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. Parâmetros: - `plaintext_b64` (obrigatório): plaintext_b64 (campo `k` decifrado) — ex.: `sZ3q...` Corpo de exemplo (JSON): ```json { "plaintext_b64": "sZ3q..." } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/history/keys/{fingerprint}/verify" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "plaintext_b64": "sZ3q..." }' ``` #### Listar chaves `GET https://api.hypeai.com.br/v1/history/keys` Lista as chaves registradas da conta (escopo, fingerprint, verificada ou não, revogada ou não). NUNCA devolve material de chave. Ferramenta de IA (MCP) equivalente: `integra_history_keys` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/history/keys" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Revogar chave `DELETE https://api.hypeai.com.br/v1/history/keys/{fingerprint}` 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. Exemplo (cURL): ```bash curl -X DELETE \ "https://api.hypeai.com.br/v1/history/keys/{fingerprint}" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ### Sessão #### Estado da importação `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history` 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). Ferramenta de IA (MCP) equivalente: `integra_history_status` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Disparar a importação `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/sync` 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. Ferramenta de IA (MCP) equivalente: `integra_history_sync` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `sync_type` (obrigatório): sync_type (both | history) — ex.: `both` Corpo de exemplo (JSON): ```json { "sync_type": "both" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/sync" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "sync_type": "both" }' ``` #### Config efetiva `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/config` 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. Ferramenta de IA (MCP) equivalente: `integra_history_config` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/config" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Echo de decifragem (dry-run) `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/echo` 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": "" }`. Ferramenta de IA (MCP) equivalente: `integra_history_echo` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Parâmetros: - `plaintext` (obrigatório): plaintext (≤512) — ex.: `ping-decifragem-ci` Corpo de exemplo (JSON): ```json { "plaintext": "ping-decifragem-ci" } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/echo" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "plaintext": "ping-decifragem-ci" }' ``` ### Conteúdo #### Puxar mensagens (paginado) `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/messages?limit=200` 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). Parâmetros: - `limit` (opcional): limit (1-1000) — ex.: `200` - `cursor` (opcional): cursor (da página anterior) - `allow_partial` (opcional): allow_partial (true p/ ler antes do fim) Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/messages?limit=200" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Puxar agenda (paginado) `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/contacts?limit=200` 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. Parâmetros: - `limit` (opcional): limit (1-1000) — ex.: `200` - `cursor` (opcional): cursor (da página anterior) Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/contacts?limit=200" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` #### Resumo (sem PII) `GET https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/summary` 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. Ferramenta de IA (MCP) equivalente: `integra_history_summary` — mesma chave, servidor https://mcp.integra.hypeai.com.br/mcp. Exemplo (cURL): ```bash curl -X GET \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/summary" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ### Confirmação #### Confirmar entrega (apaga) `POST https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/ack` 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. Parâmetros: - `cursor` (obrigatório): cursor (next_cursor persistido) — ex.: `hc2...` - `decrypt_ok` (obrigatório): decrypt_ok (false = desistência) - `reason` (obrigatório): reason (com decrypt_ok=false) Corpo de exemplo (JSON): ```json { "cursor": "hc2..." } ``` Exemplo (cURL): ```bash curl -X POST \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history/ack" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "cursor": "hc2..." }' ``` #### Apagar o buffer agora `DELETE https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history` 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. Exemplo (cURL): ```bash curl -X DELETE \ "https://api.hypeai.com.br/v1/PHONE_NUMBER_ID/history" \ -H "Authorization: Bearer hai_live_SEU_TOKEN" ``` ## Histórico de coexistência — guia de decifragem (spec completa) O conteúdo do histórico é entregue SELADO com a chave pública P-256 que você registra em `POST /v1/history/keys`. A HypeAi não tem a sua privada e não consegue abrir o que guarda. Tudo o que é preciso para implementar a decifragem está abaixo — não há passo escondido. Suíte: `hai-hist-v1/P256-HKDF-SHA256-AESGCM256/bucket-v1` ### Formato de fio (envelope) ```text envelope (bytes, big-endian): ┌───────────┬─────────────┬────────────┬──────────────────────────┐ │ hdr (4) │ epk (65) │ nonce (12) │ ciphertext + tag GCM (16)│ └───────────┴─────────────┴────────────┴──────────────────────────┘ hdr[0] = versão do envelope (1) hdr[1] = suíte (1 = P-256; 2 = X25519, RESERVADO — rejeite o que não conhecer) hdr[2..3] = key_id (uint16 BE) — qual das SUAS chaves selou (casa com /history/keys) epk = pública EFÊMERA P-256, ponto não comprimido (0x04 || X || Y) CEK = HKDF-SHA256( ECDH(sua_privada, epk), salt = vazio, info = "hai-hist-v1" || hdr || epk || SUA_pública_raw(65), L = 32 ) AAD = hdr || "hai-hist-v1|||" kind: "m" mensagens (ref = msg_ref hex da linha) "c" agenda (ref = aad_ref "chunk_seq:row_index" da linha) "k" desafio de posse (ref = challenge_ref do registro) plaintext = [len_hi][len_lo] || JSON UTF-8 || zeros até o bucket (256|1024|4096|16384) → selados de 353 | 1.121 | 4.193 | 16.481 bytes (97 + bucket) 1 encapsulação ECDH por LOTE: a MESMA epk se repete em até ~2.000 linhas seguidas. ⚠️ NÃO é RFC 9180 (HPKE) — não use libs de HPKE esperando interoperar. ⚠️ A string do HKDF/AAD é SÓ "hai-hist-v1" — NUNCA o identificador completo da suíte ("hai-hist-v1/P256-HKDF-SHA256-AESGCM256/bucket-v1"). Usar o completo dá InvalidTag sem pista. DE ONDE VEM CADA PARÂMETRO DO AAD (a pergunta que trava quem integra): ┌───────────────┬──────────────────────────────────────────────────────────────────────────┐ │ session_id │ campo "session_id" da resposta de GET /v1/{pnid}/history/messages │ │ │ (e /contacts). Também em GET /v1/{pnid}/history. Para o kind "k", é o │ │ │ campo "id" devolvido no 201 de POST /v1/history/keys. │ │ ref (kind m) │ "msg_ref" da própria linha em data[] (32 caracteres hex) │ │ ref (kind c) │ "aad_ref" da própria linha em data[] — já vem pronto, "chunk_seq:row_idx" │ │ ref (kind k) │ "challenge_ref" do 201 de POST /v1/history/keys │ │ kind │ fixo por rota: "m" mensagens · "c" agenda · "k" desafio de posse │ └───────────────┴──────────────────────────────────────────────────────────────────────────┘ E SÓ ISSO entra no AAD. Os outros campos da linha (phase, type, timestamp, timestamp_iso) são para você rotear e exibir — nenhum deles participa da decifragem. A resposta também traz "suite_kdf": "hai-hist-v1", que é exatamente a string do HKDF/AAD, já pronta para colar. SUA pública em 65 bytes (o "myPubRaw" dos exemplos): são os ÚLTIMOS 65 BYTES do SPKI/DER que você registrou (o prefixo de 26 bytes é fixo). Confira que o primeiro deles é 0x04. NÃO use a SPKI inteira no info do HKDF — é o erro mais comum de quem começa. ROTAÇÃO: hdr[2..3] (key_id) diz QUAL das suas chaves selou aquela linha. Indexe suas privadas por key_id e escolha antes do ECDH; key_id desconhecido ⇒ falhe explícito, não tente abrir. ``` ### JSON de uma mensagem, depois de decifrar ```json // JSON de UMA mensagem, após decifrar (chaves curtas de propósito — padding por bucket) { "w": "wamid.HBgN…", // wamid real "t": "5511999997777", // thread (telefone do outro lado) — agrupe por ele "d": "in", // direção: "in" | "out" "y": "text", // tipo "ts": 1753612345, // unix (relógio do aparelho) "p": "5511999997777", // peer (presente quando conhecido) "b": "Bom dia, meu pedido 8842 chegou?", // corpo (texto); mídia vira placeholder sem arquivo "s": 3, // status (1=sent 2=delivered 3=read), quando a Meta informa "r": "wamid.ANTERIOR…" // reply-to, quando é resposta } // Integridade (opcional): msg_ref = os 16 primeiros BYTES do SHA-256 de (session_id || wamid), // em hex minúsculo -> 32 caracteres. Ambos concatenados como UTF-8, sem separador: // sha256(session_id + w).subarray(0, 16).toString("hex") === msg_ref da linha // Agenda ("kind":"c"): { "p": "5511977776666", "n": "Maria Souza", "f": "Maria" } + action add/remove. ``` ### Implementações completas #### Node.js ```js import { createDecipheriv, createPublicKey, diffieHellman, hkdfSync, } from "node:crypto"; const SUITE = "hai-hist-v1"; const cekCache = new Map(); // epk(hex) → CEK. Sem o cache, cada linha paga o ECDH: ~35× mais caro. function cekFor(priv, myPubRaw, hdr, epk) { const id = epk.toString("hex"); let cek = cekCache.get(id); if (!cek) { const epkKey = createPublicKey({ format: "jwk", key: { kty: "EC", crv: "P-256", x: epk.subarray(1, 33).toString("base64url"), y: epk.subarray(33, 65).toString("base64url"), }}); const z = diffieHellman({ privateKey: priv, publicKey: epkKey }); const info = Buffer.concat([Buffer.from(SUITE), hdr, epk, myPubRaw]); cek = Buffer.from(hkdfSync("sha256", z, Buffer.alloc(0), info, 32)); cekCache.set(id, cek); } return cek; } /** priv = createPrivateKey(pem da SUA privada) · myPubRaw = 65 bytes da SUA pública (0x04||X||Y) */ export function unseal(sealedB64, { priv, myPubRaw, sessionId, ref, kind }) { const env = Buffer.from(sealedB64, "base64"); const hdr = env.subarray(0, 4), epk = env.subarray(4, 69), nonce = env.subarray(69, 81); const ct = env.subarray(81, env.length - 16), tag = env.subarray(env.length - 16); if (hdr[0] !== 1 || hdr[1] !== 1) throw new Error("suite desconhecida — não tente abrir"); const d = createDecipheriv("aes-256-gcm", cekFor(priv, myPubRaw, hdr, epk), nonce); d.setAAD(Buffer.concat([hdr, Buffer.from(`${SUITE}|${sessionId}|${ref}|${kind}`)])); d.setAuthTag(tag); const padded = Buffer.concat([d.update(ct), d.final()]); // lança se AAD/tag não casarem const len = padded.readUInt16BE(0); return JSON.parse(padded.subarray(2, 2 + len).toString("utf8")); } ``` #### Python ```python # pip install cryptography import base64, json from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.ciphers.aead import AESGCM SUITE = b"hai-hist-v1" _cek_cache = {} # epk -> AESGCM. Sem o cache, cada linha paga o ECDH: ~35x mais caro. def _gcm(priv, my_pub_raw: bytes, hdr: bytes, epk: bytes) -> AESGCM: gcm = _cek_cache.get(epk) if gcm is None: peer = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), epk) z = priv.exchange(ec.ECDH(), peer) cek = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=SUITE + hdr + epk + my_pub_raw).derive(z) gcm = AESGCM(cek) _cek_cache[epk] = gcm return gcm def unseal(sealed_b64: str, priv, my_pub_raw: bytes, session_id: str, ref: str, kind: str): env = base64.b64decode(sealed_b64) hdr, epk, nonce, ct = env[:4], env[4:69], env[69:81], env[81:] # ct já inclui a tag if hdr[0] != 1 or hdr[1] != 1: raise ValueError("suite desconhecida — não tente abrir") aad = hdr + f"hai-hist-v1|{session_id}|{ref}|{kind}".encode() padded = _gcm(priv, my_pub_raw, hdr, epk).decrypt(nonce, ct, aad) # InvalidTag = AAD/chave errados ln = int.from_bytes(padded[:2], "big") return json.loads(padded[2:2 + ln]) ``` #### PHP ```php CEK. Sem o cache, cada linha paga o ECDH: ~35x mais caro. function hist_cek($priv, string $myPubRaw, string $hdr, string $epk): string { if (isset($GLOBALS['cek_cache'][$epk])) return $GLOBALS['cek_cache'][$epk]; // SPKI DER de uma pública EC P-256 = prefixo fixo de 26 bytes + o ponto de 65 $der = hex2bin('3059301306072a8648ce3d020106082a8648ce3d030107034200') . $epk; $pem = "-----BEGIN PUBLIC KEY-----\n" . chunk_split(base64_encode($der), 64, "\n") . "-----END PUBLIC KEY-----\n"; $z = openssl_pkey_derive(openssl_pkey_get_public($pem), $priv, 32); $cek = hash_hkdf('sha256', $z, 32, 'hai-hist-v1' . $hdr . $epk . $myPubRaw, ''); return $GLOBALS['cek_cache'][$epk] = $cek; } function hist_unseal(string $sealedB64, $priv, string $myPubRaw, string $sessionId, string $ref, string $kind): array { $env = base64_decode($sealedB64); $hdr = substr($env, 0, 4); $epk = substr($env, 4, 65); $nonce = substr($env, 69, 12); $ct = substr($env, 81, -16); $tag = substr($env, -16); if (ord($hdr[0]) !== 1 || ord($hdr[1]) !== 1) throw new Exception('suite desconhecida'); $aad = $hdr . "hai-hist-v1|$sessionId|$ref|$kind"; $padded = openssl_decrypt($ct, 'aes-256-gcm', hist_cek($priv, $myPubRaw, $hdr, $epk), OPENSSL_RAW_DATA, $nonce, $tag, $aad); if ($padded === false) throw new Exception('decifragem falhou — AAD/chave errados?'); $len = (ord($padded[0]) << 8) | ord($padded[1]); return json_decode(substr($padded, 2, $len), true); } ``` #### Go ```go package hist import ( "crypto/aes" "crypto/cipher" "crypto/ecdh" "crypto/sha256" "encoding/base64" "encoding/binary" "encoding/json" "errors" "io" "golang.org/x/crypto/hkdf" ) var cekCache = map[string][]byte{} // epk -> CEK. Sem o cache, cada linha paga o ECDH: ~35x mais caro. func cek(priv *ecdh.PrivateKey, myPubRaw, hdr, epk []byte) ([]byte, error) { if c, ok := cekCache[string(epk)]; ok { return c, nil } peer, err := ecdh.P256().NewPublicKey(epk) if err != nil { return nil, err } z, err := priv.ECDH(peer) if err != nil { return nil, err } info := make([]byte, 0, 11+len(hdr)+len(epk)+len(myPubRaw)) info = append(info, []byte("hai-hist-v1")...) info = append(info, hdr...) info = append(info, epk...) info = append(info, myPubRaw...) c := make([]byte, 32) if _, err := io.ReadFull(hkdf.New(sha256.New, z, nil, info), c); err != nil { return nil, err } cekCache[string(epk)] = c return c, nil } func Unseal(sealedB64 string, priv *ecdh.PrivateKey, myPubRaw []byte, sessionID, ref, kind string) (map[string]any, error) { env, err := base64.StdEncoding.DecodeString(sealedB64) if err != nil { return nil, err } hdr, epk, nonce, ct := env[:4], env[4:69], env[69:81], env[81:] if hdr[0] != 1 || hdr[1] != 1 { return nil, errors.New("suite desconhecida — não tente abrir") } key, err := cek(priv, myPubRaw, hdr, epk) if err != nil { return nil, err } block, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } aad := append(append([]byte{}, hdr...), []byte("hai-hist-v1|"+sessionID+"|"+ref+"|"+kind)...) padded, err := gcm.Open(nil, nonce, ct, aad) // erro = AAD/chave não casam if err != nil { return nil, err } ln := binary.BigEndian.Uint16(padded[:2]) var out map[string]any return out, json.Unmarshal(padded[2:2+int(ln)], &out) } ``` ### Erros do trilho de histórico | Erro | O que é | O que fazer | |---|---|---| | `403 history_not_enabled` | gate fechado | Falta ADT aceito, liberação da conta (beta) ou o recurso está pausado/desligado. | | `403 read_only_key` | chave somente-leitura | ack, sync, echo e DELETE exigem chave com escrita — a trava protege o apagamento. | | `409 sync_in_progress` | importação incompleta | Aguarde sync_complete: true, ou leia parcial com ?allow_partial=true (ack segue bloqueado). | | `409 sync_not_complete` | ack cedo demais | Confirmar importação furada apagaria o que ainda vai chegar — e a Meta não reenvia. | | `409 ack_beyond_served` | cursor além do servido | Confirme apenas next_cursor de página que você RECEBEU (watermark real no servidor). | | `409 history_recipient_key_unverified` | chave sem prova de posse | Complete o desafio em POST /history/keys/{fingerprint}/verify antes de disparar/echo. | | `409 key_in_use` | revogação recusada | Há buffer vivo selado para a chave; ?confirm=destroy_buffer revoga E apaga na hora. | | `400 private_key_rejected` | material privado enviado | Você mandou a chave PRIVADA — geramos recusa sem gravar. Envie a pública (SPKI). | | `400 invalid_cursor / 409 cursor_session_mismatch` | cursor inválido/trocado | Cursores são assinados por sessão; recomece a paginação sem cursor. | | `410 history_buffer_closed / history_buffer_purged` | buffer já apagado | Ack tardio, DELETE anterior ou TTL de 24h — não há o que ler; a Meta não reenvia. | | `(local) InvalidTag / Unsupported state` | a decifragem falhou no seu código | AAD montado com session_id/ref/kind errados; `hdr` esquecido no início do AAD; `myPubRaw` sendo a SPKI inteira em vez dos 65 bytes crus; ou a string completa da suíte usada no lugar de "hai-hist-v1". | ## Operar por IA — servidor MCP (74 ferramentas) Servidor: `https://mcp.integra.hypeai.com.br/mcp` (Streamable HTTP). Autenticação: a MESMA chave da API REST (`Authorization: Bearer hai_live_...`) ou login OAuth (conectores de browser, ex. Claude.ai). Cada ferramenta é escopada à conta da chave; contas de agência escolhem o cliente por chamada com o parâmetro `client` (descoberta via `integra_list_clients`). ### Connect (4) - `integra_connect_capacity` (leitura, nível conta): HypeAi Connect: pré-checa a capacidade do pool da SUA conta (fail-closed) ANTES de abrir uma conexão. Devolve { 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 da conta), contadas pela mesma fonte (WhatsApp + Instagram). DOIS LIMITES, NÃO UM — a confusão nº1 de quem revende: (1) POOL DA CONTA: quantas conexões você contratou no total; é o que esta tool mede e o que você compra. (2) ALOCAÇÃO DO SUB-CLIENTE (`config.connection_limit` do create_session): quantas daquele total cada cliente final pode usar. Uma conexão precisa passar nos DOIS. Pool cheio ⇒ reason 'pool_exhausted' (contrate mais). Alocação cheia com pool sobrando ⇒ reason 'client_exhausted' (eleve o connection_limit DAQUELE cliente) — são causas diferentes com soluções OPOSTAS, não confunda na sua UI. CONEXÃO = 1 número de WhatsApp OU 1 conta do Instagram; os dois canais somam nos dois limites. Planejamento: um revendedor com 10 clientes omnichannel (1 WhatsApp + 1 Instagram cada) precisa de pool >= 20 e connection_limit >= 2 em cada sub-cliente. NÍVEL-CONTA: NÃO passe `client`. Exige escopo AGÊNCIA ou OAuth. - `integra_connect_create_session` (escrita, nível conta): HypeAi Connect (Embedded Signup as a Service): provisiona (idempotente por external_customer_id) uma conexão WhatsApp oficial p/ um cliente final do SEU SaaS e devolve connect_url (tela hospedada NEUTRA p/ abrir em POPUP/nova aba — NÃO iframe, o Embedded Signup da Meta exige janela top-level), webhook_secret (UMA vez, SENSÍVEL — não logar), capacity e o `client_id` do sub-cliente. Guarde o client_id: com ELE + esta chave de agência você configura o resto do sub-cliente (integra_set_quota, Typebot, Chatwoot…) passando client= — inclusive ANTES de o cliente final conectar. `config` já deixa number_limit/quota prontos na MESMA chamada. MULTI-INBOX (vários números no MESMO cliente final): repita esta chamada com o MESMO external_customer_id e config.number_limit >= N — reaproveita sub-cliente+WABA, números ADITIVOS; guarde uma LISTA de phone_number_id por cliente (1 por inbox). MODO DA CONEXÃO: por default quem escolhe é o cliente final DENTRO da tela — Coexistência (número segue no app do celular; histórico importável) ou API Oficial (só Cloud API). Se o SEU produto só opera em um dos modos, passe `flow` e a tela mostra SÓ esse — sem seletor e sem 'Recomendado' no modo errado. O modo chega no campo `coexistence` do connection.completed e no GET /v1. ⚠️ RECONECTAR como API Oficial um número que era coexistência ENCERRA o histórico em definitivo — avise o usuário antes de reconexões. Acompanhe a sessão com integra_connect_session_status; desconecte com integra_disconnect_number. NÍVEL-CONTA: NÃO passe `client`. Exige chave de escopo AGÊNCIA ou login OAuth. - `integra_connect_session_status` (leitura, nível conta): HypeAi Connect: estado das SESSÕES de conexão da sua conta — a resposta server-to-server para "o cliente final chegou a conectar?". Sem session_token, lista o funil (status pending | connected | expired — a sessão vive 15 min; expired = o cliente não concluiu e basta criar outra, é idempotente). Com session_token (o cs_... devolvido pelo create_session), devolve AQUELA sessão + as conexões ATIVAS do sub-cliente: phone_number_id, coexistence (true = número segue no app do celular e o histórico é importável) e onboarding_ref (carimbo do Embedded Signup — muda a cada reconexão). Use quando o webhook connection.completed não chegou: isto diz se a conexão aconteceu de fato. NÍVEL-CONTA: NÃO passe `client`. Exige escopo AGÊNCIA ou OAuth. - `integra_connect_webhook_health` (leitura, nível conta): HypeAi Connect: saúde das ENTREGAS do SEU webhook nos sub-clientes — o diagnóstico de "o evento não chegou: foi o meu endpoint?". Devolve totais por estado na janela (delivered | dead = desistida após 4xx permanente ou retries esgotados | pending), o último sucesso, o estado de cada webhook (consecutive_failures, e `is_active:false` + `disabled_reason` quando a plataforma o DESATIVOU por falhas seguidas) e as últimas 10 falhas terminais com status_code e erro. Corrigiu o endpoint? Reative com integra_update_webhook (is_active:true, passando client=) e reenvie entregas passadas com integra_resend_webhook. O CONTEÚDO dos eventos não é retornado (a plataforma é relay, não guarda mensagem). NÍVEL-CONTA: NÃO passe `client`. Exige escopo AGÊNCIA ou OAuth. ### Gestão (46) - `integra_chatwoot_webhook_url` (escrita): Retorna a webhook URL do Chatwoot (embute o secret HMAC — SENSÍVEL, não logar) pra colar no inbox. - `integra_create_chatwoot` (escrita): Cria uma integração Chatwoot (per-número ou central) e devolve a webhook_url (que embute um secret — SENSÍVEL). api_token vai pro Vault e nunca é devolvido. enable_sync começa desligado. - `integra_create_template` (escrita): Cria um template de mensagem na Meta (entra como PENDING; a aprovação é ASSÍNCRONA — minutos a 24h+). Suporta TODOS os tipos via `components` (formato cru da Cloud API): HEADER text/IMAGE/VIDEO/DOCUMENT/LOCATION (header de mídia EXIGE example.header_handle — obtenha antes com integra_upload_template_example), BODY com variáveis {{1}} (+ example), FOOTER, BUTTONS (quick_reply, url dinâmica, phone_number, copy_code, OTP p/ AUTHENTICATION) e carousel. Nome: minúsculas/números/underscore. allow_category_change fica TRUE por default (a Meta recategoriza em vez de rejeitar). Acompanhe a aprovação com integra_refresh_templates / integra_list_templates OU assine o evento 'templates' no webhook (push de APPROVED/REJECTED). Multi-WABA: passe credential_id (descubra em integra_list_wabas). - `integra_create_typebot` (escrita): Cria uma conexão Typebot e atribui os números que ela atende (exclusivo: 1 número = 1 conexão Typebot). api_token (opcional) é gravado no Vault e nunca é devolvido. - `integra_create_webhook` (escrita): Cria um webhook de saída (eventos explícitos) e devolve o secret HMAC UMA vez (SENSÍVEL, não logar). - `integra_delete_chatwoot` (escrita): Remove uma integração Chatwoot (derruba o espelhamento). Destrutivo — confirme antes. - `integra_delete_template` (escrita): Apaga um template na Meta. Destrutivo — confirme antes. Sem template_id apaga TODAS as línguas com esse nome; com template_id (hsm_id) apaga só aquela edição. Nome apagado fica 30 dias indisponível p/ recriar (regra da Meta). - `integra_delete_typebot` (escrita): Remove uma conexão Typebot e suas atribuições de número. Destrutivo — confirme antes. - `integra_delete_webhook` (escrita): Remove um webhook de saída. Destrutivo — confirme antes. - `integra_disconnect_number` (escrita): Desconecta um número DESTA conta na HypeAi Integra e libera a vaga do pool. Destrutivo — confirme antes. NÃO mexe na Meta: o número continua na WABA e no Business Manager do dono, e o app segue assinado; remover de lá é decisão do dono, no Business Manager. Idempotente (chamar de novo devolve already_disconnected). Use quando o seu sistema desligar o número no lado de vocês — sem esta chamada a Integra continua, corretamente, mostrando o número conectado. Para reconectar, gere uma sessão do Connect; reconectar em COEXISTÊNCIA preserva a importação de histórico, reconectar como API Oficial a encerra de forma permanente. - `integra_get_api_usage` (leitura): Resumo de uso da SUA API num período (chamadas, erros, rate-limited, latência média, por dia, por status HTTP e por chave). Janela em dias (1-90, default 7). - `integra_get_meta_analytics` (escrita): Analytics ao vivo da Meta (WhatsApp) das suas WABAs: conversas por categoria, custo (pricing) e performance de templates (enviado/entregue/lido/clicado), no período escolhido. Pode vir de cache (SWR; a resposta traz fetched_at/cached/stale). - `integra_get_number` (leitura): Detalhe de UM número da conta + status da credencial (precisa reconectar?). Útil pra checar qualidade/tier e se o número está pronto pra enviar antes de tentar. - `integra_get_number_profile` (escrita): Perfil comercial AO VIVO do número na Meta (sobre, endereço, descrição, e-mail, sites, vertical, foto) + status read-only (nome verificado, qualidade, verificação). Faz chamada ao Graph (latência). - `integra_get_phone_quality` (leitura): KPIs de saúde da conta: quantos números por qualidade (GREEN/YELLOW/RED) e quantos templates aprovados. - `integra_get_quota` (leitura): Pacotes de mensagens (quotas) da conta: limite mensal, consumido, restante e rollover do ciclo corrente, por número e/ou da conta inteira. Vazio = envios ilimitados. - `integra_get_usage_cost` (leitura): Consumo de mensagens por categoria Meta (service/utility/authentication/marketing) por número e o CUSTO ESTIMADO em US$ (volume × tarifa; selo 'estimate' até a Meta publicar tarifas oficiais — cobrança de mensagens não-template começa em 01/10/2026). Janela em dias (1-90, default 30). Fonte local (webhooks de status); p/ analytics oficiais da Meta use integra_get_meta_analytics. - `integra_history_config` (leitura): Config EFETIVA do histórico do número (herança conta→cliente→número + veto do dono resolvidos) + contacts_effective (a agenda exige aceite legal SEPARADO — include_contacts sozinho não basta). Somente leitura: escrever é via Connect (config.history) ou painel. - `integra_history_echo` (escrita): Echo de decifragem (dry-run, SEM PII e sem gastar nada): envia um plaintext (≤512 chars) e recebe-o SELADO com a chave verificada do parceiro, com o bloco `aad` pronto (session_id 'echo'). Se o pipeline do parceiro decifra o echo, decifra o histórico real — rode ANTES de integra_history_sync para não queimar a janela única da Meta com decifragem quebrada. Exige chave registrada E verificada (409 history_recipient_key_unverified sem ela). Foi o passo que faltou no incidente de 04/08: o parceiro tinha como TESTAR antes de concluir qualquer coisa sobre a janela. - `integra_history_keys` (leitura): Lista as chaves públicas de decifragem registradas na CONTA (escopo, fingerprint, verificada/revogada). NUNCA devolve material de chave. Registro, prova de posse e revogação são REST (POST/DELETE /v1/history/keys*) — atos do parceiro, não de agente. - `integra_history_status` (leitura): Estado da importação de histórico de coexistência do número: sync_complete (o SINAL DE FIM — não há evento push), progress_by_phase, missing_chunks e retenção do buffer selado (≤24h). 403 history_not_enabled = falta ADT aceito/liberação do beta. - `integra_history_summary` (leitura): Resumo SEM PII do buffer de histórico: contagens, distribuição por tipo, faixa de datas, progresso. Conteúdo e telefones NUNCA aparecem aqui — o conteúdo é selado para a chave do parceiro e só sai pelo pull REST (o MCP não o carrega, por desenho). - `integra_history_sync` (escrita): Dispara a importação de histórico de coexistência do número (POST /v1/{pnid}/history/sync). ⚠️ CONSOME A JANELA ÚNICA: a Meta entrega o histórico UMA vez por Embedded Signup (onboarding_ref) e não reenvia — CONFIRME com o usuário antes de chamar e rode integra_history_echo primeiro para provar a decifragem. O gate recusa sem chave VERIFICADA e sem coexistência; com sessão já viva a chamada é IDEMPOTENTE (already:true, sem novo pedido à Meta) — seguro re-chamar para conferir. sync_type: 'both' (histórico + agenda; a agenda exige o aceite legal separado history_contacts) ou 'history'. Acompanhe com integra_history_status (sync_complete é o sinal de fim; não há evento push). - `integra_list_chatwoot_integrations` (leitura): Lista as integrações Chatwoot da conta (config de pausa/sync, inbox) e números atendidos. Não retorna tokens — apenas has_token/has_webhook_secret. - `integra_list_clients` (leitura): Lista os CLIENTES que esta conexão gerencia (portfólio de agência). Se você atende vários clientes, comece AQUI: cada item traz o `client` (id) que você passa no parâmetro `client` das demais ferramentas para escolher em qual cliente operar. Se você gerencia um único cliente, não precisa usar isto nem passar `client`. - `integra_list_numbers` (leitura): Lista os números WhatsApp ativos da SUA conta (phone_number_id, nome verificado, qualidade, tier). Use ISTO PRIMEIRO para descobrir os phone_number_id que as demais tools precisam. - `integra_list_templates` (leitura): Lista os templates de mensagem da conta (nome, idioma, categoria, status de aprovação, motivo de rejeição, credential_id da WABA). Filtros opcionais: status (APPROVED/PENDING/REJECTED) e credential_id (uma WABA). - `integra_list_typebot_integrations` (leitura): Lista as conexões Typebot da conta e quais números cada uma atende (sem expor tokens). - `integra_list_wabas` (leitura): Lista as WABAs (contas WhatsApp Business) ativas da conta — cada uma com credential_id, waba_id e os números que atende. Use o credential_id como seletor de WABA em integra_refresh_templates / integra_list_templates (necessário quando há mais de uma WABA). - `integra_list_webhooks` (leitura): Lista os webhooks de saída da conta (URL, eventos, ativo, números atribuídos). Não retorna o secret HMAC. - `integra_provision_chatwoot_inbox` (escrita): Cria automaticamente um inbox 'API' no Chatwoot do cliente apontando pra nossa webhook (fallback manual se falhar). - `integra_refresh_templates` (escrita): Força a re-sincronização AO VIVO do status de aprovação dos templates com a Meta (PENDING→APPROVED/REJECTED). Com uma WABA é automático; com mais de uma, descubra o credential_id em integra_list_wabas e passe aqui. - `integra_resend_webhook` (escrita): Reenvia uma entrega de webhook passada (mesmo event_id) — útil pra recuperar de falhas transitórias. - `integra_rotate_webhook_secret` (escrita): Rotaciona o secret HMAC de um webhook e devolve o NOVO secret UMA vez (SENSÍVEL, não logar). Use quando o secret foi perdido ou pode ter vazado — sem recriar o webhook (URL/eventos/histórico intactos). Efeito imediato: entregas passam a ser assinadas com o novo secret (uma entrega em trânsito pode falhar 1x e o retry reassina sozinho). Sequência: chame → grave o novo secret no seu sistema IMEDIATAMENTE (não é re-exibido). - `integra_set_quota` (escrita): Cria/atualiza um PACOTE de mensagens (quota mensal com rollover) — por número (phone_number_id) ou da conta inteira (omita phone_number_id). EFEITO REAL: com mode='enforce', ao esgotar o pacote os envios são BLOQUEADOS (HTTP 429 quota_exceeded) até o próximo ciclo — confirme com o usuário antes. mode='warn' só avisa. active=false remove o pacote. Rollover: saldo não usado passa ao mês seguinte, acumulando no máximo rollover_expiry_months × franquia (omita p/ nunca vencer). - `integra_sync_numbers` (escrita): Re-sincroniza com a Meta os números já conectados (atualiza nome verificado/qualidade/throughput) e roda a reconciliação: desativa um número SÓ quando a WABA respondeu, ele não está nela E um GET direto não o alcança. Quando a Meta está inalcançável a checagem é PULADA e reportada em `reconciliation.skipped` — deactivated=0 com skipped preenchido significa 'não deu para checar', NUNCA 'está tudo lá'. NÃO ativa números novos nem consome pool. Manutenção (pode demorar — N chamadas ao Graph). - `integra_test_chatwoot` (escrita): Valida credenciais do Chatwoot e lista os inboxes. Use {id} salvo OU {base_url, account_id, api_token} inline. - `integra_test_typebot` (escrita): Dispara um startChat real no Typebot pra validar a conexão (não muda nada). - `integra_test_webhook` (escrita): Envia um POST de teste assinado (HMAC) pra URL do webhook e registra a entrega. - `integra_update_chatwoot` (escrita): Edita uma integração Chatwoot. enable_sync=true liga o espelhamento bidirecional (precisa de inbox provisionado). - `integra_update_number_photo` (escrita): Troca a foto de perfil do número (upload na Meta). Envie a imagem em base64 (máx 5MB). Só o próprio número. - `integra_update_number_profile` (escrita): Edita o perfil comercial do número na Meta (about, address, description, email, websites[máx 2], vertical). verified_name é read-only (a Meta exige review). Só edita o PRÓPRIO número. - `integra_update_template` (escrita): Edita um template existente na Meta (components e/ou categoria; volta a PENDING p/ nova aprovação). Regras da Meta: só templates APPROVED/REJECTED/PAUSED podem ser editados; APPROVED = 1 edição/24h e 10/mês. template_id = o id da Meta (veja em integra_list_templates). - `integra_update_typebot` (escrita): Edita uma conexão Typebot (qualquer subconjunto de campos). is_active=false desativa preservando a config. - `integra_update_webhook` (escrita): Edita um webhook de saída. is_active=false desativa preservando a config. Não troca o secret (p/ isso use integra_rotate_webhook_secret). Use p/ ADICIONAR eventos, ex.: incluir 'smb_message_echoes' num webhook existente (coexistência). - `integra_upload_template_example` (escrita): Sobe a MÍDIA DE EXEMPLO do header de um template (Resumable Upload da Meta) e devolve o handle. Necessário ANTES de integra_create_template com HEADER de IMAGE/VIDEO/DOCUMENT: use o handle 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: baixa → repassa à Meta → devolve o handle). ### Instagram (12) - `instagram_create_post` (escrita): PUBLICA na conta IG (container→processamento→publish numa chamada): foto (SÓ JPEG), carrossel (children 2-10), Reel (media_type REELS) ou Story (media_type STORIES). A Meta baixa a mídia da SUA URL pública NA HORA. Vídeo pode não ficar pronto em ~100s: resposta 202 {published:false, creation_id} — conclua re-chamando depois OU via POST cru /v1/ig/{id}/media_publish. Teto Meta: 100 posts/24h (instagram_get_publishing_limit). AGENDAMENTO NÃO EXISTE na API: o scheduler é SEU — chame isto na hora certa. - `instagram_get_account_insights` (leitura): Métricas agregadas da CONTA (reach, views, accounts_engaged, profile_views, follower_count…) num período. `period` day|week|days_28 (algumas métricas exigem metric_type=total_value — a Meta responde com erro claro se faltar; re-chame ajustando). - `instagram_get_media_insights` (leitura): Métricas de UM post/reel/story (reach, likes, comments, saved, shares, views…). As métricas válidas variam por tipo de mídia — a Meta rejeita métrica inválida com erro claro (ajuste `metric`). Story expira em 24h: leia as métricas antes. - `instagram_get_profile` (leitura): Lê o perfil da PRÓPRIA conta IG ao vivo na Meta (username, nome, bio, site, seguidores, nº de mídias, foto). Leitura; a API oficial NÃO permite editar perfil. - `instagram_get_publishing_limit` (leitura): Quanto do teto de publicação da Meta (100 posts/24h por conta) já foi usado. Cheque antes de rodadas grandes de publicação (o excedente é rejeitado pela Meta). - `instagram_list_accounts` (leitura): Lista as contas do INSTAGRAM conectadas ao cliente (beta fechado): ig_user_id (o id que TODAS as demais tools instagram_* usam), @username, tipo, seguidores e saúde do token (dias p/ expirar, needs_reconnect). Use ISTO PRIMEIRO em qualquer fluxo de Instagram. - `instagram_list_comments` (leitura): Lista os comentários de um post/reel (texto, @autor, likes, ocultos e respostas). O comment_id alimenta instagram_reply_comment, instagram_private_reply e instagram_moderate_comment. Prefira PUSH: assine o evento ig_comments no webhook. - `instagram_list_media` (leitura): Lista as mídias publicadas da conta (posts/reels/carrosséis) com id, tipo, URL, permalink, legenda, likes e nº de comentários. Paginação por cursor (`after` da resposta anterior). - `instagram_moderate_comment` (escrita): Modera um comentário: hide (oculta do público — reversível), unhide (reexibe) ou delete (APAGA — IRREVERSÍVEL; confirme com o usuário antes). - `instagram_private_reply` (escrita): Responde um COMENTÁRIO de um post seu no PRIVADO (vira DM) — a única ponte comentário→DM. Regra da Meta: 1× por comentário, dentro de 7 dias. O comment_id vem do webhook ig_comments ou de instagram_list_comments. - `instagram_reply_comment` (escrita): Responde um comentário PUBLICAMENTE (resposta aninhada no post). Para responder no privado (DM), use instagram_private_reply. - `instagram_send_message` (escrita): Envia DM no Instagram — SÓ RESPOSTA dentro da janela de 24h após a última mensagem do usuário (recipient_id = IGSID que chegou no webhook ig_messages como sender.id). NÃO existe DM fria no Instagram. Conteúdo: texto, mídia por URL (image/audio/video/file), sticker like_heart, reação a uma mensagem, compartilhar um post seu (media_share) ou quick replies (botões de texto). ### Plataforma (1) - `integra_about` (leitura): BRIEFING COMPLETO para construir um sistema de WhatsApp e/ou Instagram sobre a Integra: o que É a plataforma (infraestrutura oficial Meta — WhatsApp GA + Instagram em beta fechado) e o que NÃO é, o mapa de capacidades, as RECEITAS ponta-a-ponta (receber+responder, bot+humano, campanha, embutir via Connect, Instagram completo), o modelo de eventos do webhook (incl. ig_*), os limites/tiers da Meta e as superfícies (MCP + API REST + docs). Chame ISTO PRIMEIRO ao projetar ou construir qualquer coisa aqui, ou em dúvida sobre as capacidades. Não exige `client`. ### WhatsApp (11) - `whatsapp_get_media_url` (leitura): Resolve os metadados de uma mídia recebida (mime/sha256/tamanho + a URL temporária da Meta). Para BAIXAR o binário, use a API REST GET /v1/{phone_number_id}/media/{media_id} — a Integra faz o download autenticado e devolve os bytes (a URL da Meta expira em ~5min e exige o token, que fica com a Integra). - `whatsapp_get_phone` (leitura): Lê metadados ao vivo do número na Meta (nome verificado, número exibido, qualidade, tier, verificação). - `whatsapp_mark_read` (escrita): Marca uma mensagem recebida como lida (os ✓✓ azuis). Use o wamid do seu webhook. Sem custo Meta. - `whatsapp_send_contacts` (escrita): Envia um ou mais cartões de contato (vCard). Passe o array `contacts` no formato da Cloud API. - `whatsapp_send_interactive` (escrita): Envia uma mensagem interativa (botões de resposta ou lista de opções), dentro da janela de 24h. Passe o objeto `interactive` no formato da Cloud API (type: 'button' | 'list'). - `whatsapp_send_location` (escrita): Compartilha um ponto no mapa (latitude/longitude + nome/endereço opcionais). - `whatsapp_send_media` (escrita): Envia imagem, vídeo, áudio ou documento — por URL pública (link) OU por media id já carregado. Dentro da janela de 24h. - `whatsapp_send_reaction` (escrita): Reage com um emoji a uma mensagem recebida. Use o wamid que chegou no seu webhook. - `whatsapp_send_template` (escrita): Envia um template APROVADO — o único jeito de iniciar conversa fora da janela de 24h. Crie/gerencie templates por aqui mesmo (integra_create_template e afins). `components` preenche as variáveis no formato cru da Cloud API — cobre todos os tipos: header (text/image/video/document/location), body (positional/named), buttons (url dinâmica, quick_reply, copy_code, OTP) e carousel. - `whatsapp_send_text` (escrita): Envia mensagem de texto livre. Só funciona dentro da janela de 24h após a última mensagem do contato; fora dela a Meta rejeita (use whatsapp_send_template para iniciar conversa). - `whatsapp_send_typing` (escrita): Mostra 'digitando…' ao contato (e marca a mensagem como lida). Some sozinho em ~25s ou quando você responde.