Buscar mensagens em um chat
POST /message/find
Busca mensagens com múltiplos filtros disponíveis. Este endpoint permite:
- Busca por ID específico: Use
idpara encontrar uma mensagem exata - Filtrar por chat: Use
chatidpara mensagens de uma conversa específica - Filtrar por rastreamento: Use
track_sourceetrack_idpara mensagens com dados de tracking - Histórico de ligações: Use apenas
messageType: call,limiteoffsetpara listar as chamadas mais recentes. A resposta pode trazercallPeer(identidade conhecida do contato) econtent.isVideo. - Status dos contatos: Use
chatid: status@broadcastpara os Status recebidos, mesmo sem webhookstatus_posts. Sem essechatid, a busca não traz Status. Eles ficam guardados por 24 horas, como no WhatsApp (a limpeza roda uma vez por dia, então filtremessageTimestampse precisar do corte exato), e o Status que o autor apaga sai da lista. Cada um vem com o autor emsender_pn,sender_lidesender_image_preview_url(foto, quando conhecida) e, nos de imagem, vídeo ou link, com a miniatura emcontent.JPEGThumbnail. Baixe a mídia pelo/message/download. Um Status que não abriu vem commessageType: errore só o ID, o autor e o horário. Status de grupo (enviados e recebidos) ficam na conversa de cada grupo commessageType: GroupStatusMessagee o texto emtext: liste todos commessageType: GroupStatusMessage, semchatid. Saem em 24 horas, como os outros Status (os de campanha do/senderficam com a campanha). - Limitar resultados: Use
limitpara controlar quantas mensagens retornar - Ordenação: Resultados ordenados por data (mais recentes primeiro)
Fora dos Status, as mensagens guardadas só trazem no content as
miniaturas em base64 que não têm cópia no servidor (prévia de link sem
cópia, localização, anúncio, convites); as de mídia que pode ser baixada de
novo (JPEGThumbnail e afins) chegam só no webhook, na hora da mensagem.
Nas mensagens enviadas pela API nos últimos 7 dias, sendPayload traz o
pedido de envio, sem os arquivos em base64 (links vêm). Depois do envio (em
conversa individual, 1 hora depois), o arquivo em base64 guardado vira o
texto [arquivo removido após o envio: tipo, N bytes].
Autenticação
[
{
"token": []
}
]
{
"token": {
"name": "token",
"type": "apiKey",
"in": "header"
}
}
Corpo da requisição
{
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "ID específico da mensagem para busca exata",
"example": "user123:r3EB0538"
},
"chatid": {
"type": "string",
"description": "ID do chat no formato internacional",
"example": "5511999999999@s.whatsapp.net"
},
"messageType": {
"type": "string",
"description": "Tipo da mensagem. Use `call` com `limit` e `offset` para o histórico de ligações.",
"example": "call"
},
"track_source": {
"type": "string",
"description": "Origem do rastreamento para filtrar mensagens",
"example": "chatwoot"
},
"track_id": {
"type": "string",
"description": "ID de rastreamento para filtrar mensagens",
"example": "msg_123456789"
},
"limit": {
"type": "integer",
"description": "Número máximo de mensagens a retornar (padrão 100, sem máximo). Para muitas mensagens, prefira páginas de até 1000 e avance com `pagination.nextOffset`.",
"minimum": 1,
"default": 100,
"example": 20
},
"offset": {
"type": "integer",
"description": "Deslocamento para paginacao (0 retorna as mensagens mais recentes)",
"default": 0
}
}
},
"examples": {
"chatSearch": {
"summary": "Buscar por chat especifico",
"description": "Busca mensagens de uma conversa especifica",
"value": {
"chatid": "5511999999999@s.whatsapp.net",
"limit": 20,
"offset": 0
}
},
"idSearch": {
"summary": "Buscar por ID especifico",
"description": "Busca uma mensagem especifica pelo seu ID",
"value": {
"id": "user123:r3EB0538"
}
},
"trackingSearch": {
"summary": "Buscar por rastreamento",
"description": "Busca mensagens usando dados de tracking com paginacao",
"value": {
"track_source": "chatwoot",
"track_id": "conv_123456",
"limit": 50,
"offset": 100
}
},
"callHistory": {
"summary": "Histórico de ligações",
"value": {
"messageType": "call",
"limit": 40,
"offset": 0
}
}
}
}
}
}
Respostas
{
"200": {
"description": "Lista de mensagens encontradas com metadados de paginacao",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"messages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Message"
}
},
"pagination": {
"type": "object",
"description": "Dados da página, como nas outras listas, sem `totalRecords` (contar as mensagens pesaria a cada página).",
"properties": {
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"hasMore": {
"type": "boolean",
"description": "Há mais mensagens depois desta página."
},
"nextOffset": {
"type": "integer",
"description": "Offset da próxima página."
}
}
}
}
}
}
}
},
"400": {
"description": "Parametros invalidos"
},
"401": {
"description": "Token invalido ou expirado"
},
"404": {
"description": "Chat nao encontrado"
},
"500": {
"description": "Erro interno do servidor"
}
}
#/components/schemas/Message
{
"type": "object",
"description": "Representa uma mensagem trocada no sistema",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "ID único interno da mensagem (formato r + 7 caracteres hex aleatórios)"
},
"messageid": {
"type": "string",
"description": "ID original da mensagem no provedor"
},
"chatid": {
"type": "string",
"description": "ID da conversa relacionada"
},
"sender": {
"type": "string",
"description": "ID do remetente da mensagem"
},
"senderName": {
"type": "string",
"description": "Nome exibido do remetente"
},
"isGroup": {
"type": "boolean",
"description": "Indica se é uma mensagem de grupo",
"default": false
},
"fromMe": {
"type": "boolean",
"description": "Indica se a mensagem foi enviada pelo usuário",
"default": false
},
"messageType": {
"type": "string",
"description": "Tipo de conteúdo da mensagem"
},
"source": {
"type": "string",
"description": "Plataforma de origem da mensagem"
},
"messageTimestamp": {
"type": "integer",
"description": "Timestamp original da mensagem em milissegundos",
"default": 0
},
"status": {
"type": "string",
"description": "Status do ciclo de vida da mensagem.\nExemplos comuns: `Queued`, `Canceled`, `Failed`, `Sent`, `Delivered`, `Read`.\nEm mensagem de grupo, segue o participante mais adiantado: `Delivered` quando pelo menos um recebeu, `Read` quando pelo menos um leu e `Played` quando pelo menos um ouviu.\n"
},
"text": {
"type": "string",
"description": "Texto original da mensagem",
"default": ""
},
"quoted": {
"type": "string",
"description": "ID da mensagem citada/respondida",
"default": ""
},
"edited": {
"type": "string",
"description": "Histórico de edições da mensagem",
"default": ""
},
"reaction": {
"type": "string",
"description": "ID da mensagem reagida",
"default": ""
},
"vote": {
"type": "string",
"description": "Dados de votação de enquete e listas",
"default": ""
},
"convertOptions": {
"type": "string",
"description": "Conversão de opções da mensagem, lista, enquete e botões",
"default": ""
},
"buttonOrListid": {
"type": "string",
"description": "ID do botão ou item de lista selecionado",
"default": ""
},
"owner": {
"type": "string",
"description": "Dono da mensagem",
"default": ""
},
"error": {
"type": "string",
"description": "Mensagem de erro caso o envio tenha falhado",
"default": ""
},
"content": {
"description": "Conteúdo bruto da mensagem (JSON serializado ou texto)",
"oneOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "string",
"description": "Texto bruto quando não for JSON"
}
]
},
"wasSentByApi": {
"type": "boolean",
"description": "Indica se a mensagem foi enviada via API"
},
"pinned": {
"type": "boolean",
"description": "Mensagem fixada na conversa (fixar e desafixar chegam também em `messages_update`, tipos `Pinned` e `Unpinned`)"
},
"sendFunction": {
"type": "string",
"description": "Função usada para enviar a mensagem (quando enviada via API)"
},
"sendPayload": {
"description": "Payload usado no envio quando disponível. Dados de mídia em base64 são omitidos.",
"oneOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "string",
"description": "Texto bruto quando não for JSON"
}
]
},
"fileURL": {
"type": "string",
"description": "URL ou referência de arquivo da mensagem"
},
"callPeer": {
"type": "object",
"description": "Contato conhecido associado a uma ligação, quando disponível em `messageType: call`.",
"properties": {
"jid": {
"type": "string"
},
"name": {
"type": "string"
},
"imagePreviewUrl": {
"type": "string"
}
}
},
"send_folder_id": {
"type": "string",
"description": "Pasta associada ao envio (quando aplicável)"
},
"track_source": {
"type": "string",
"description": "Origem de rastreamento"
},
"track_id": {
"type": "string",
"description": "ID de rastreamento (pode repetir)"
},
"ai_metadata": {
"type": "object",
"description": "Registro de uma rodada da IA. O completo (pedido ao modelo, resposta e `outcome`) fica uma vez, na última mensagem do contato que a rodada respondeu, também quando nada saiu (erro, resposta descartada). Cada mensagem enviada pela IA leva só `agent_id` e `turn` (o `id` dessa mensagem do contato).",
"properties": {
"agent_id": {
"type": "string",
"description": "ID do agente de IA responsável"
},
"turn": {
"type": "string",
"description": "Na mensagem enviada pela IA: o `id` da mensagem do contato onde está o registro completo da rodada."
},
"flow_id": {
"type": "string",
"description": "Mensagem enviada por um fluxo: o `id` do fluxo. A mensagem enviada pela IA traz o `agent_id`."
},
"request": {
"type": "object",
"description": "Dados da requisição à API de IA",
"properties": {
"messages": {
"type": "array",
"description": "Histórico de mensagens enviadas para a API"
},
"tools": {
"type": "array",
"description": "Ferramentas disponíveis para o agente"
},
"options": {
"type": "object",
"description": "Opções de configuração da API",
"properties": {
"model": {
"type": "string"
},
"temperature": {
"type": "number"
},
"maxTokens": {
"type": "integer"
},
"topP": {
"type": "number"
},
"frequencyPenalty": {
"type": "number"
},
"presencePenalty": {
"type": "number"
}
}
}
}
},
"response": {
"type": "object",
"description": "Resposta da API de IA",
"properties": {
"choices": {
"type": "array",
"description": "Resultados retornados pela API"
},
"toolResults": {
"type": "array",
"description": "Resultados da execução de ferramentas"
},
"error": {
"type": "string",
"description": "Mensagem de erro, se houver"
}
}
},
"outcome": {
"type": "object",
"description": "O que a rodada fez de fato (só no registro completo).",
"properties": {
"status": {
"type": "string",
"enum": [
"sent",
"cancelled",
"error",
"empty"
],
"description": "`sent`: enviou algo; `cancelled`: descartada (a conversa pausou, um fluxo começou ou bateu o limite de respostas por hora); `error`: o provedor falhou; `empty`: nada a enviar."
},
"texts": {
"type": "integer",
"description": "Mensagens de texto enviadas."
},
"audio": {
"type": "boolean",
"description": "Respondeu em áudio."
},
"menus": {
"type": "integer",
"description": "Menus enviados."
},
"files": {
"type": "integer",
"description": "Arquivos (mensagens cadastradas) enviados."
},
"handoff": {
"type": "string",
"description": "`chamar_humano`: o resumo para quem atender."
},
"lead": {
"type": "array",
"items": {
"type": "string"
},
"description": "`atualizar_lead`: o que foi gravado no CRM (`lead_email = ana@exemplo.com; column = Agendado`)."
},
"detail": {
"type": "string",
"description": "Por que foi descartada, ou o erro."
}
}
}
}
},
"sender_pn": {
"description": "JID PN resolvido do remetente (quando disponível)",
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"sender_lid": {
"description": "LID original do remetente (quando disponível)",
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"sender_image_preview_url": {
"type": "string",
"format": "uri",
"description": "URL temporária de preview do remetente, quando conhecida. A hidratação desta versão preenche mensagens recebidas em grupos; o campo pode ser omitido. Não provoca consulta de foto ao WhatsApp na listagem."
}
}
}