Skip to content

Mensagens

Endpoints da app consumidora pra enviar mensagens via chip vinculado e consultar status.

POST /v1/messages

Enfileira envio. Retorna 202 Accepted com message_id. Mensagem efetiva acontece async (rate limit + jitter por chip).

POST /v1/messages
Authorization: Bearer APP_KEY
Content-Type: application/json

Body comum

CampoObrigatorioNotas
chip_idopcionalqual chip envia. Quando ausente, hub auto-resolve via app_chip_access: se app tem 1 chip com canSend=true usa ele; se 0 ou 2+ → 400 chip-id-required (extra inclui candidate_chip_ids)
tosimtelefone destino — 5511999998888 (so digitos) ou JID completo
typesimtext | image | audio | document | location | reaction
contentsimvaria por type — ver abaixo
idempotency_keyrecomendadostring ate 120 chars; unique (app_id, idempotency_key) previne duplicacao
quoted_message_idopcionalULID de mensagem anterior pra reply

Texto

{
"chip_id": "01HZTQ...",
"to": "5511999998888",
"type": "text",
"content": { "text": "ola, sua compra foi confirmada" },
"idempotency_key": "order-1234-confirmed"
}

Imagem

Tipos de midia (image, audio, document, sticker) aceitam url publica OU media_id de upload previo (POST /v1/media). Forneca um dos dois.

{
"chip_id": "...",
"to": "...",
"type": "image",
"content": {
"url": "https://cdn.com/produto.jpg",
"caption": "produto X — R$99"
}
}

Hub baixa do url, valida tamanho (MEDIA_MAX_BYTES, default 16MB), reupload pro WhatsApp.

Aceita tambem data:image/jpeg;base64,... em url (inline).

Audio

{
"type": "audio",
"content": {
"url": "https://cdn.com/audio.ogg",
"ptt": true // true = bolha de voz; false = anexo
}
}

⚠️ Pra tocar como bolha de voz no WhatsApp, mimetype precisa ser audio/ogg; codecs=opus. Conversao do seu lado.

Documento

{
"type": "document",
"content": {
"url": "https://cdn.com/contrato.pdf",
"filename": "contrato-2026.pdf",
"title": "Contrato"
}
}

Localizacao

{
"type": "location",
"content": {
"lat": -23.5505,
"lng": -46.6333,
"name": "Loja SP",
"address": "Av Paulista 1000"
}
}

Reaction

{
"type": "reaction",
"content": {
"emoji": "❤️",
"to_wa_message_id": "BAE5..." // wa_message_id da mensagem alvo
}
}

emoji="" remove reaction existente.

Sticker

{
"type": "sticker",
"content": {
"url": "https://cdn.com/figurinha.webp"
}
}

WhatsApp espera WebP 512x512. Animado (WebP animated) e suportado se o arquivo estiver no formato. Hub baixa, persiste em MinIO e envia.

Contact (vCard)

{
"type": "contact",
"content": {
"display_name": "Joao da Silva",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:Joao da Silva\nTEL;type=CELL;type=VOICE;waid=5511999998888:+55 11 99999-8888\nEND:VCARD"
}
}

vcard precisa ser vCard 3.0 valido. Telefone com waid permite o destinatario adicionar direto no WhatsApp. Multiplos contatos numa so mensagem ainda nao suportado (passe 1 vCard por POST).

Poll (enquete)

{
"type": "poll",
"content": {
"name": "Qual o melhor horario pra reuniao?",
"options": ["09h", "14h", "16h"],
"selectable_count": 1
}
}
CampoNotas
namepergunta da enquete (1-255 chars)
optionsarray de 2-12 opcoes (1-100 chars cada)
selectable_count1 = single choice (radio); 2+ = multipla escolha. Default 1

Votos chegam pelo webhook poll.vote — 1 evento por voto.

Response (todos os types)

202 Accepted:

{
"id": "01HZTQMSG...",
"status": "queued"
}

A mensagem entra na fila do chip. Voce acompanha via webhook message.status (queued → sent → delivered → read). Ou consulta diretamente:

GET /v1/messages/:id

{
"id": "01HZTQMSG...",
"chip_id": "...",
"app_id": "...",
"wa_message_id": "BAE5...",
"to_jid": "5511...@s.whatsapp.net",
"from_jid": "5511...:30@s.whatsapp.net",
"direction": "out",
"type": "text",
"content": { "text": "..." },
"status": "delivered",
"error": null,
"created_at": "...",
"sent_at": "...",
"delivered_at": "...",
"read_at": "..."
}

GET /v1/messages (historico paginado)

Lista mensagens dos chips em que a app tem app_chip_access.canReceive=true. Util pra backup, treinamento de IA, reprocesso ou exportacao.

Query params

ParamTipoNotas
chip_idopcionalrestringe a 1 chip especifico (precisa estar no whitelist)
chat_jidopcionalfiltra por conversa (1:1 ou grupo)
directionopcionalin ou out
typeopcionaltext | image | audio | etc
statusopcionalqueued | sent | delivered | read | failed
since, untilopcionalISO datetime — janela de criacao
beforeopcionalcursor — proximo next_before da resposta anterior
limitopcional1-200, default 50

Resposta 200

{
"data": [
{
"id": "01HZTQ...",
"chip_id": "01HZTQCHIP...",
"app_id": "01HZTQAPP...",
"direction": "in",
"from_jid": "5511988887777@s.whatsapp.net",
"to_jid": "5511999998888:30@s.whatsapp.net",
"sender_jid": "5511988887777@s.whatsapp.net",
"sender_name": "Maria",
"chat_jid": "5511988887777@s.whatsapp.net",
"is_group": false,
"chat_name": null,
"is_favorite": false,
"type": "text",
"content": { "text": "ola" },
"status": "delivered",
"wa_message_id": "BAE5...",
"error": null,
"created_at": "2026-05-03T10:00:00.000Z"
}
],
"next_before": "2026-05-03T09:55:00.000Z"
}

next_before: null indica fim. Pra paginar: ?before=<next_before>.

Multi-chip: quando chip_id e omitido, hub busca em todos os chips do whitelist e re-ordena created_at desc. Cada chip e queryado serializadamente (baixo volume — para apps com muitos chips, prefira passar chip_id explicito).

Status possiveis

StatusSignificado
queuedenfileirada, aguardando rate limiter
senthub mandou pro WhatsApp (server ack 1)
deliveredaparelho do destinatario recebeu (server ack 2)
readdestinatario leu (so se leitura ativa nas configs WhatsApp)
failederro irreversivel — campo error tem detalhe

Erros comuns

  • 409 chip-not-connected — chip vinculado nao esta connected
  • 403 chip-access-forbidden — app sem can_send=true no vinculo
  • 409 idempotency-conflict — mesma idempotency_key ja foi usada com payload diferente
  • 422 unsupported-message-typetype nao reconhecido
  • 422 transcription-disabled — tentou rota de transcricao manual com provider desligado

Ver Erros pra lista completa.