A mensagem
Toda mensagem da Orkesio tem o mesmo formato, venha de onde vier: a resposta do envio, cada item da busca e o message
dentro do data dos eventos de mensagem. Quem entende este objeto entende toda a API de mensagens.
Exemplo comentado
Uma foto recebida num grupo, respondendo a uma mensagem da inbox:
{
"id": "3EB0A1B2C3D4E5F60718",
"chat_id": "120363028782550019@g.us",
"author": {
"id": "5511999999999@s.whatsapp.net",
"phone": "5511999999999",
"lid": "123456789012345@lid",
"name": "Maria"
},
"direction": "in",
"sent_at": "2026-10-17T12:00:00.000Z",
"type": "image",
"text": "Segue a foto",
"mime_type": "image/jpeg",
"size": 111193,
"width": 738,
"height": 1599,
"display_text": "Segue a foto",
"reply_to": "3EB05DCE1D4036FCE241C6",
"quoted": {
"direction": "out",
"type": "text",
"preview": "Seu pedido saiu para entrega."
},
"device": "android"
}
Lendo de cima para baixo:
id: o id da mensagem no WhatsApp (guarde junto com a inbox).chat_id: em que conversa. Aqui, um grupo. Os dados da conversa (nome, atendimento, lead) não vão na mensagem: vêm emGET /chats/{chat_id}e, nos eventos, ao lado da mensagem (data.chat).author: quem escreveu. Num grupo é o participante; numa conversa direta, o contato (ou a própria inbox, nas enviadas).direction:in(do contato) ouout(da inbox).typee os campos do tipo: o tipo diz quais campos vêm soltos na mensagem.texté sempre o texto principal (aqui, a legenda), edisplay_texttraz tudo o que aparece na tela num texto só (veja Os campos do tipo).reply_toequoted:reply_toé o id da mensagem respondida;quotedtraz o resumo dela (preview) para mostrar sem buscar a outra mensagem.
Os campos
Identidade e lugar
| Campo | O que é |
|---|---|
id | Id da mensagem no canal: o id do WhatsApp ou, na API oficial, o wamid. Único dentro da inbox. |
chat_id | O id da conversa (o id de GET /chats/{chat_id}). Num grupo, o grupo; quem escreveu vem em author. O nome, o tipo (direct, group, newsletter, broadcast, status, channel, post) e o lead ficam na conversa, que o webhook e o /events mandam em data.chat. |
author | Quem escreveu: id (sempre), phone, lid, name, username e picture_url (quando o canal informa). |
direction | in: escrita pelo contato. out: escrita pela inbox. |
sent_at | Quando foi enviada (ISO 8601, UTC). |
Origem (só em out)
| Campo | O que é |
|---|---|
sent_by | Quem mandou: api (rota de envio), automation (IA, fluxo ou resposta rápida), campaign (disparo em massa, com campaign_id), phone (o celular), web (WhatsApp Web ou outro aparelho) ou user (pessoa logada no painel, em breve: virá com o campo user dizendo quem). |
automation | Qual automação enviou (agent_id, flow_id), quando sent_by é automation. |
campaign_id | A campanha que enviou, quando sent_by é campaign. |
track_source, track_id | Seu rastreamento: o que você mandou no envio, devolvido igual. |
Estado
| Campo | O que é |
|---|---|
status | Só em mensagens da inbox. Veja a tabela abaixo. |
error | Só com status: failed: error (o código, como expired), message e, quando o erro é de um campo, field. |
scheduled_at | Quando sai, num envio agendado (status: scheduled). |
edited | Já foi editada; o conteúdo é o da última edição. |
deleted | Foi apagada para todos. A mensagem continua com o conteúdo que já tinha. |
pinned, pinned_until | Fixada na conversa, e até quando (quando o prazo é conhecido). |
status | Quer dizer |
|---|---|
scheduled | Agendada, ainda não saiu. |
queued | Na fila da inbox, ainda não saiu. |
pending | Saiu para o canal, sem confirmação de entrega ainda. |
sent | O servidor do canal recebeu. |
delivered | Chegou no aparelho do contato. |
read | O contato leu. |
played | O contato ouviu (áudio de voz) ou assistiu (vídeo redondo). |
failed | Não saiu. O motivo está em error. |
O status só avança (queued → pending → sent → delivered → read). Cada mudança chega no evento
message.status.
Contexto
| Campo | O que é |
|---|---|
reply_to | A mensagem respondida: o id dela. |
quoted | O resumo da mensagem respondida, só na leitura: author (em grupo), direction, type e preview. Vem quando a api conhece a citada. Resposta a um story do Instagram não tem reply_to: o story vem em quoted.story. |
mentions | Quem foi mencionado (ids). |
forwarded, forwarded_from | Encaminhada, e de onde, quando o canal informa (encaminhada de uma newsletter do WhatsApp). |
device | Aparelho de quem enviou (android, ios, web, desktop), quando dá para saber. Só no WhatsApp Web. |
referral | Da Meta: a pessoa chegou por um anúncio ou publicação (click-to-WhatsApp). Traz o anúncio e o ctwa_clid. Costuma vir só na primeira mensagem. |
Os campos do tipo
O type diz o que é a mensagem, e os campos daquele tipo vêm soltos na mensagem, ao lado de id, author... Não há um
objeto content. Três regras valem para todos:
texté sempre o texto principal, o que a pessoa lê: o texto, a legenda da mídia, o corpo dos botões, a pergunta da enquete... Para pegar "o que a mensagem diz", em qualquer tipo, é um campo só.- Os outros textos têm o mesmo nome em todo tipo:
footer(rodapé),button_text(o botão que abre a lista),address,description,title. O cabeçalho em texto dos botões e da lista vem na primeira linha detext, como se manda; a mídia dele vem solta, emmime_typeefilename. display_textjunta tudo o que aparece na tela num texto só, com a formatação do WhatsApp (*negrito*,_itálico_): cabeçalho, texto, rodapé e opções. Bom para n8n, IA e CRM. Só vem na busca e nos eventos; no envio, a api monta a mensagem pelos campos.
O mesmo formato vale no envio (POST /messages): para reenviar uma mensagem recebida, use o
mesmo type e os mesmos campos do tipo, sem os campos que só existem na leitura (display_text, size, sha256, width,
height...).
Várias mídias
Uma mensagem tem uma mídia principal, em url depois de baixada. Quando há mais de uma mídia, vale uma
destas duas formas:
- Várias fotos e vídeos enviados juntos viram um álbum. Chega uma mensagem
albumcom a contagem (images,videos) e o texto que veio junto, e uma mensagem por mídia, cada uma comalbum_idapontando para o álbum. Vale para o álbum do WhatsApp e, quando chegarem, para as mensagens com várias fotos do Instagram e do Messenger. Assim cada foto tem o seuid, o seu evento e o seu download. - Mídia dentro de uma mensagem (o cabeçalho dos botões, os cartões do carrossel): baixe com
POST /messages/mediae diga qual emitem:"item": "header"ou"item": "cards.2"(o terceiro cartão, contando do zero). Semitem, a mídia principal.
Depois de baixado, o link fica na resposta da rota e na própria mensagem, no lugar da mídia, e volta na busca:
| Mídia | Onde fica o link |
|---|---|
| A principal | url |
| O cartão N | cards[N].url |
O link da mídia do cabeçalho ("item": "header") volta só na resposta da rota.
Os tipos
type | text | Outros campos |
|---|---|---|
text | o texto | link_preview quando o link tem prévia |
image, video, document, sticker | a legenda | url, mime_type, size, filename, width, height; a miniatura só no evento em tempo real |
album | o texto que veio junto | images, videos: a contagem; cada mídia chega à parte, com album_id |
audio, voice | — | o mesmo da mídia, mais duration_seconds e transcription (a transcrição, quando feita: nunca vai em text, que é só o que o autor escreveu). voice é o áudio gravado na hora |
video_note | — | o mesmo da mídia (o vídeo redondo) |
location | — | latitude, longitude, name (o nome do lugar), address, url |
live_location | a legenda | latitude, longitude, accuracy, sequence |
contacts | — | contacts: a lista (name, phones) |
poll | a pergunta | choices (os nomes das opções), selectable_count; o resultado na busca vem em results |
poll_vote | — | poll (a enquete votada) e choices (os nomes votados) |
buttons, list | o corpo, com o cabeçalho na primeira linha | footer, choices; a mídia do cabeçalho, solta (mime_type, filename); na lista, button_text |
carousel | o texto de abertura | cards, cada um com a mídia solta (type, url, mime_type...), text e choices |
location_request | o pedido | — |
interactive_reply | o título da opção escolhida | option_id (o id da opção), description |
event | o nome do evento | description, start_at, location |
payment | a nota | amount, currency, items, pix, payment_status... |
reaction | — | emoji e a mensagem reagida (target). Chega em message.reaction |
call | — | a ligação (tipo, duração, resultado) |
group_participant, system | — | registros do grupo e do sistema; ficam na busca, não chegam em message.received |
unavailable | — | a mensagem não pôde ser lida (ex.: não decifrada) |
unknown | — | tipo que a Orkesio ainda não traduz. Nunca é erro: trate como "mensagem não suportada" |
Onde o nome do campo do tipo colidia com um da mensagem, ele ganhou um nome próprio: product_id (produto), shared_id
(compartilhamento), story_id (menção em story) e payment_status (pagamento).
A lista completa, com todos os campos de cada tipo, está no schema OrkesioMessage da referência. A lista de tipos
pode crescer: trate tipo desconhecido como unknown.
O que muda conforme o lugar
O objeto é o mesmo nos três lugares, com duas diferenças:
| Resposta do envio | Busca | Evento em tempo real | |
|---|---|---|---|
| Miniatura da mídia | não | não | sim |
| Campos do tipo | os do pedido (na fila, a mensagem ainda não foi montada) | completo | completo |