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/messagesAuthorization: Bearer APP_KEYContent-Type: application/jsonBody comum
| Campo | Obrigatorio | Notas |
|---|---|---|
chip_id | opcional | qual 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) |
to | sim | telefone destino — 5511999998888 (so digitos) ou JID completo |
type | sim | text | image | audio | document | location | reaction |
content | sim | varia por type — ver abaixo |
idempotency_key | recomendado | string ate 120 chars; unique (app_id, idempotency_key) previne duplicacao |
quoted_message_id | opcional | ULID 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) aceitamurlpublica OUmedia_idde 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 }}| Campo | Notas |
|---|---|
name | pergunta da enquete (1-255 chars) |
options | array de 2-12 opcoes (1-100 chars cada) |
selectable_count | 1 = 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
| Param | Tipo | Notas |
|---|---|---|
chip_id | opcional | restringe a 1 chip especifico (precisa estar no whitelist) |
chat_jid | opcional | filtra por conversa (1:1 ou grupo) |
direction | opcional | in ou out |
type | opcional | text | image | audio | etc |
status | opcional | queued | sent | delivered | read | failed |
since, until | opcional | ISO datetime — janela de criacao |
before | opcional | cursor — proximo next_before da resposta anterior |
limit | opcional | 1-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_ide omitido, hub busca em todos os chips do whitelist e re-ordenacreated_at desc. Cada chip e queryado serializadamente (baixo volume — para apps com muitos chips, prefira passarchip_idexplicito).
Status possiveis
| Status | Significado |
|---|---|
queued | enfileirada, aguardando rate limiter |
sent | hub mandou pro WhatsApp (server ack 1) |
delivered | aparelho do destinatario recebeu (server ack 2) |
read | destinatario leu (so se leitura ativa nas configs WhatsApp) |
failed | erro irreversivel — campo error tem detalhe |
Erros comuns
409 chip-not-connected— chip vinculado nao estaconnected403 chip-access-forbidden— app semcan_send=trueno vinculo409 idempotency-conflict— mesmaidempotency_keyja foi usada com payload diferente422 unsupported-message-type—typenao reconhecido422 transcription-disabled— tentou rota de transcricao manual com provider desligado
Ver Erros pra lista completa.