Skip to main content
As rotas de chat começam com /integrations/external/chats. Envie a chave de integração no header Authorization: Bearer <chave>. A empresa é definida pela chave; as operações usam o usuário que criou a chave como ator e respeitam suas permissões e acesso aos números e contas.

Canais e consulta de conversas

GET /integrations/external/chats reúne conversas WhatsApp e Instagram. Use channel_type=WHATSAPP ou channel_type=INSTAGRAM para restringir o canal. phone_id identifica um número WhatsApp; channel_account_id, sem channel_type, direciona a consulta para Instagram.
A listagem retorna total, records e next_cursor. Envie o valor de next_cursor no parâmetro cursor para continuar com os mesmos filtros; null indica o fim. A ordenação pode mudar quando chegam mensagens, por isso prefira cursor para percorrer a listagem combinada. skip continua disponível. O padrão é take=10, com limite efetivo de 50 registros por página. Os filtros positivos de agendamento, Copilot e resposta do cliente excluem Instagram. Os registros contêm channel_type, channel_account_id, channel_account, external_contact e legacy. No Instagram, wa_contact_id é null e legacy é vazio. Nos registros de WhatsApp da listagem, ai_attendance resume o atendimento por agente de IA: state (AI, TRANSFERRED ou TEAM), agent, since, end_reason e transferred_to. O campo é null quando a conversa nunca teve agente de IA ou o recurso está desativado, e não faz parte dos detalhes nem dos registros de Instagram. Use GET /{id} para detalhes, GET /{id}/messages para mensagens e GET /{id}/history para eventos operacionais. As listagens de mensagens usam search, skip, take e order=asc|desc, com padrão de 20 registros e limite efetivo de 100. total representa todos os registros encontrados. Uma mensagem citada pode incluir quoted_message.page. Em mensagens WhatsApp, media é um objeto ou null; em mensagens Instagram, media e attachments são arrays. content_payload guarda o conteúdo estruturado e pode ser null. Instagram também expõe provider_message_id, shared_content e metadados do provedor; nesse canal, status vem em maiúsculas (PROCESSING, SENT, DELIVERED, READ, FAILED ou DELETED) e error_code é um texto. WhatsApp inclui transcription, error_code, error_message e dados de ligação quando disponíveis. whatsapp_ai_agent_id identifica o agente de IA que enviou a mensagem e é null nas mensagens de pessoas e automações. URLs de mídia e avatares podem ser temporárias. A timeline GET /{id}/timeline é de WhatsApp e combina eventos MESSAGE e CALL em uma paginação única. Ao usar search, retorna somente mensagens cujo corpo corresponde à busca.

Criar conversa e enviar mensagens

A criação manual é de WhatsApp. POST /integrations/external/chats exige whatsapp_phone_id, template e pelo menos um identificador de contato: wa_contact_id ou person_contact_id. O segundo é o UUID de um contato telefônico de uma pessoa do CRM. O serviço pode reutilizar uma conversa existente e envia o template inicial.
crm_person_id, assigned_agent_id e status também são opcionais. assigned_agent_id é o UUID do agente; as rotas de responsável e participante recebem user_id. Essa rota não recebe arquivos: se o template tiver mídia no cabeçalho, informe uma URL http(s) no value do campo. Consulte GET /{id}/templates para obter templates da conta WhatsApp e os respectivos required_fields. Esse retorno é um array direto, sem total e records. O filtro category aceita AUTHENTICATION, MARKETING, UTILITY e SERVICE. POST /{id}/messages envia texto, template ou arquivos pelo WhatsApp e aguarda o retorno imediato do provedor. Consulte can_send_open_message e session_expires_at: fora da janela de atendimento, use template.
type assume text quando omitido. Para enviar um template, informe type: "template" junto com template e não envie body: com body preenchido, a API envia o texto e não o template. Para responder a uma mensagem específica, acrescente reference_wamid, que aceita o identificador do WhatsApp ou o UUID local da mensagem. Nas rotas /{id}/messages/{messageId}, messageId é sempre o UUID local. Uploads usam multipart/form-data, com arquivos nos campos files ou file, até 10 arquivos em cada campo. template e template_fields podem ser enviados como JSON serializado no formulário. O envio normal pode gerar uma mensagem de texto separada e uma mensagem por arquivo; leia todos os itens de records. total nesse retorno é a quantidade de mensagens enviadas pela operação. O envio manual também pode atribuir responsável e pausar um fluxo WhatsApp ativo. Cada arquivo aceita até 100 MB, ou 16 MB quando é áudio. O body é enviado como texto separado e também como legenda de cada imagem, vídeo ou documento. A falha no envio de um arquivo não interrompe a operação: o item correspondente volta em records com status: "failed", ainda com resposta 201. Confira o status de cada item. Em templates com mídia no cabeçalho, o value do campo IMAGE, VIDEO ou DOCUMENT aceita uma URL http(s) ou file:<n>, em que n é a posição, a partir de 0, do arquivo enviado no mesmo formulário, contando primeiro os de files e depois os de file. Com type: "template", os arquivos enviados servem apenas como mídia do cabeçalho e não geram mensagens separadas. Arquivo ausente, ou de tipo diferente do exigido pelo cabeçalho, retorna 400. Mensagens interativas e localização possuem rotas próprias: Exemplo de botões em POST /{id}/messages/interactive:
button aceita de 1 a 3 botões em action.buttons. list exige action.button e action.sections, com no máximo 10 linhas no total. Não misture as duas estruturas; os IDs das opções devem ser únicos. O texto do corpo aceita até 1.024 caracteres; cabeçalho e rodapé, 60 cada. Localização aceita latitude de -90 a 90 e longitude de -180 a 180. Esses envios exigem janela de atendimento aberta.
Na versão atual da API, POST /{id}/messages/location valida o corpo como mensagem interativa e retorna 400 (“Payload da mensagem interativa inválido.”) mesmo com latitude e longitude válidas. Não dependa dessa rota até que o comportamento seja corrigido.
Para iniciar digitação, informe uma referência inbound das últimas 24 horas ou deixe o serviço localizar uma mensagem elegível recente. Com is_typing=false, o retorno é uma confirmação local com reference_wamid=null.
A consulta de chats e mensagens já é multicanal, mas o envio externo síncrono, criação manual, templates, interativos, localização e digitação descritos acima usam WhatsApp. Não assuma que uma conversa Instagram listada aceita essas operações.

Atendimento, pessoas e responsáveis

create-person exige ambas as permissões crm/chats.update e crm/person.create, mesmo quando vincula uma pessoa existente. Sem person_id, envie name; também aceita birth_date, gender, notes, contacts, documents, address e addresses. O serviço vincula o contato do canal à pessoa. Exemplo de troca do responsável:
update_chat assume true; update_leads e update_deals, false. A propagação atualiza os registros abertos, não arquivados e não excluídos associados à pessoa do chat. Quando solicitada, exige também crm/lead.update e/ou crm/deal.update na chave. Essas mutações retornam os detalhes do chat; alguns enriquecimentos da consulta, como assignable_agents, podem ser omitidos.

Reações, exclusão e edição

Use POST /{id}/messages/{messageId}/reaction com { "emoji": "👍" } para reagir e DELETE no mesmo caminho para remover a reação da empresa. O retorno é a mensagem atualizada; as rotas suportam WhatsApp e Instagram conforme as regras de acesso e do provedor. No Instagram, só são aceitas as reações love, like, dislike, smile, angry, sad e wow, informadas pelo nome ou pelo emoji correspondente; qualquer outra retorna 400. DELETE /{id}/messages/{messageId} solicita exclusão de uma mensagem WhatsApp enviada pela empresa. Mensagens inbound não são elegíveis. Se a Meta recusar a exclusão, a API retorna 400; quando aceita, retorna a mensagem com status=deleted.
PATCH /{id}/messages/{messageId} está exposto, mas a edição de mensagens enviadas não está implementada pelo provedor. A API valida o acesso, registra a tentativa e retorna 400 com a mensagem: “A API oficial da Meta não suporta edição de mensagens enviadas via WhatsApp Business Platform.” Não trate essa operação como uma atualização bem-sucedida.

Mensagens agendadas

POST /{id}/scheduled-messages cria um agendamento WhatsApp. Informe scheduled_at no futuro, com fuso horário, e conteúdo: body, anexos ou template. type aceita text ou template; se omitido, é inferido pela presença de template.
Substitua a data e o nome do template pelos valores do seu envio. Texto aberto e anexos só podem ser agendados até session_expires_at; após a janela, use template. Com cancel_on_inbound=true, uma interação inbound cancela o envio pendente; o padrão é false. Na edição, campos ausentes preservam o valor anterior, inclusive type. Novos arquivos substituem todos os anexos; replace_files=true sem arquivos limpa os anexos. Criação e edição aceitam JSON ou multipart, seguindo os mesmos campos de upload de mensagens. Agendamentos criados por um agente de IA aparecem na listagem com whatsapp_ai_agent_id preenchido. Eles podem ser cancelados, mas a edição retorna 400: cancele e crie um novo agendamento. Os retornos incluem is_scheduled, status, message_kind, payload, attachments, scheduled_at, sent_at, canceled_at, failure_reason e sent_message_ids. Os estados são PENDING, PROCESSING, SENT, CANCELED e FAILED. Cancelamentos informam cancel_reason e cancel_reason_description.

Permissões e status HTTP

Os POST bem-sucedidos retornam 201, inclusive ações como marcar lido, aplicar reação e cancelar agendamento. GET, PATCH e DELETE retornam 200 quando a operação tem sucesso. A exceção de edição de mensagens descrita acima retorna erro. Consulte os schemas completos de cada operação na seção Rotas da API.