---
title: "Webhooks"
description: "Cada API de mensageria avisa o seu sistema quando algo acontece: mensagem recebida, entrega confirmada, sessão que caiu, QR Code lido. Você registra uma URL, nós enviamos um POST — e o laço de consulta some do seu código."
lang: pt-BR
canonical: https://doc.apibrasil.io/webhooks
markdown: https://doc.apibrasil.io/webhooks.md
source: apibrasil-documentation
---

# Webhooks

> Cada API de mensageria avisa o seu sistema quando algo acontece: mensagem recebida, entrega confirmada, sessão que caiu, QR Code lido. Você registra uma URL, nós enviamos um POST — e o laço de consulta some do seu código.

## Canais

Cada canal tem os próprios eventos, o próprio envelope e as próprias armadilhas — o corpo do SMS é um array, o do WhatsApp Wpp é um objeto com assinatura HMAC, e o do Baileys não diz sequer qual evento ele é. Abra o que você usa.

| Canal | Eventos | URLs de destino | Resumo | Página |
| --- | --- | --- | --- | --- |
| SMS | 4 | 1 | Avisos do percurso de cada mensagem — e, quando alguém responde, o texto da resposta. | [Webhook de SMS](https://doc.apibrasil.io/webhooks/api-sms.md) |
| WhatsApp Wpp | 19 | 4 | Mensagens que chegam e que saem, confirmação de leitura, chamadas, e o ciclo de vida da sessão. | [Webhook de WhatsApp Wpp](https://doc.apibrasil.io/webhooks/api-whatsapp-wpp.md) |
| WhatsApp Baileys | 6 | 1 | Mensagens, confirmações de leitura, contatos e o ciclo da conexão — num envelope que não diz qual evento é. | [Webhook de WhatsApp Baileys](https://doc.apibrasil.io/webhooks/api-whatsapp-baileys.md) |
| WhatsApp WhatsMeow | 18 | 1 | Mensagens, recibos de leitura, chamadas, grupos e conexão — com o nome do evento vindo junto, e um filtro para escolher o que chega. | [Webhook de WhatsApp WhatsMeow](https://doc.apibrasil.io/webhooks/api-whatsapp-whatsmeow.md) |

## Envio assíncrono

> As APIs de mensageria aceitam o sufixo /queue na rota. Com ele o gateway não espera o envio acontecer: grava o pedido, devolve um id na hora e publica numa fila. Serve para disparo em lote, onde segurar a conexão aberta por envio é o que derruba o seu processo.

### A volta inteira

1. Você chama a MESMA rota do envio síncrono, com /queue no fim.
2. A resposta volta na hora com um id — não com o resultado do envio.
3. Você acompanha o id em /jobs, e o resultado do envio chega pelos eventos do dispositivo.

### Os motores que aceitam fila

A rota assíncrona é a síncrona com /queue no fim, e as três primeiras entram na mesma pilha de autenticação e cobrança da síncrona — Bearer, DeviceToken e o débito acontecem no enfileiramento, não na entrega.

| Motor | Rota | Fila | Canal de webhook |
| --- | --- | --- | --- |
| WhatsApp Wpp — O motor WPPConnect. É o único cujo canal de webhook tem quatro URLs separadas. | `POST /whatsapp/{action}/queue` | sim | [api-whatsapp-wpp](https://doc.apibrasil.io/webhooks/api-whatsapp-wpp.md) |
| WhatsApp Baileys — O motor Evolution. O {controller} da rota é o mesmo do envio síncrono — message, chat, group. | `POST /evolution/{controller}/{action}/queue` | sim | [api-whatsapp-baileys](https://doc.apibrasil.io/webhooks/api-whatsapp-baileys.md) |
| WhatsApp WhatsMeow — O motor whatsmeow. A rota aceita barra no {action}, então caminhos compostos passam inteiros. | `POST /whatsmeow/{action}/queue` | sim | [api-whatsapp-whatsmeow](https://doc.apibrasil.io/webhooks/api-whatsapp-whatsmeow.md) |
| WhatsApp Oficial (WABA e CoEx) — A rota EXISTE e recusa em tempo de execução, com queue_not_available e a instrução de usar a rota síncrona. É pior que não existir: passa no teste de fumaça de quem integra e falha no primeiro envio de verdade. | `POST /waba/{action}/queue · POST /coex/{action}/queue` | não: a rota existe e recusa | — |

### O que a fila devolve

Um identificador e uma confirmação de que o pedido entrou. Não há resultado de envio nesta resposta, e não há como haver: o envio ainda não aconteceu.

```json
{
  "id": "9f1c8e2a-4b7d-4e61-9a3c-2f5d8e0b1c74",
  "message": "Dados enviados para a fila com sucesso"
}
```

### Acompanhar pelo id

Duas rotas, e nenhuma delas pede DeviceToken — elas ficam num grupo de middleware diferente do envio, com Bearer apenas. É o que permite um painel de acompanhamento não saber de dispositivo nenhum.

- **Endereço base:** `https://gateway.apibrasil.io/api/v2`

- `GET /jobs` — **Listar os seus jobs**: Devolve a paginação padrão do Laravel com job_id, status, created_at e updated_at, restrita à sua conta.
- `POST /jobs` — **Consultar por id**: O corpo é um array de uuid em id. Cada um precisa existir em job_statuses: um id inexistente reprova a requisição inteira com 422 “Job não encontrado”, e não devolve os outros.

**Corpo da consulta**

```json
{
  "id": [
    "9f1c8e2a-4b7d-4e61-9a3c-2f5d8e0b1c74"
  ]
}
```

**Resposta da consulta**

```json
[
  {
    "id": "9f1c8e2a-4b7d-4e61-9a3c-2f5d8e0b1c74",
    "status": "queued",
    "created_at": "28/08/2026 14:28:50",
    "processed_at": "",
    "diff_in_minutes": ""
  }
]
```

### O que vem em cada job

| Nome | Tipo | Significado |
| --- | --- | --- |
| `id` | string (uuid) | O uuid que a chamada de enfileiramento devolveu. |
| `status` | string | O estado do job. No enfileiramento ele nasce como queued — ver as lacunas abaixo. |
| `created_at` | string | Quando o pedido entrou na fila, em DD/MM/AAAA HH:mm:ss. |
| `processed_at` | string | Quando foi processado, no mesmo formato. STRING VAZIA enquanto não foi — não é nulo. |
| `diff_in_minutes` | number \| string | Minutos entre a entrada e o processamento. String vazia enquanto o job não foi processado. |

### O que costuma pegar

- **A resposta não é o resultado do envio** — O que volta é um id de fila. Tratar essa resposta como “mensagem enviada” faz o seu sistema dar por entregue algo que ainda nem saiu. O resultado do envio aparece nos eventos do dispositivo — SEND_MESSAGE e MESSAGE_STATUS no Wpp —, que é o que a página do canal documenta.
- **Vazio não é nulo** — processed_at e diff_in_minutes voltam como STRING VAZIA quando o job não foi processado, e não como null. Quem testa === null nunca acha; quem testa a ausência do valor acha.
- **Um id ruim reprova a consulta inteira** — POST /jobs valida cada item de id contra job_statuses. Um uuid que não exista devolve 422 e derruba a requisição toda — os outros ids do mesmo array não são consultados. Em lote, consulte em blocos pequenos.
- **A cobrança acontece no enfileiramento** — As rotas com /queue passam pela MESMA pilha de middleware das síncronas, incluindo a de cobrança e cota. O débito é feito quando o pedido entra na fila, não quando a mensagem sai.

### O que esta página não afirma

O gateway grava o job como queued e publica na fila. Quem consome essa fila não está em nenhum repositório disponível, e por isso o que está abaixo não foi verificado — está escrito como pergunta em aberto em vez de ser preenchido com um nome plausível.

- **Quais valores status assume além de queued** — O gateway insere queued e nunca mais escreve nessa linha. Nenhum código disponível atualiza job_statuses, então os demais estados — se existem — vêm do consumidor da fila.
- **Quando processed_at é preenchido** — O campo é lido pela rota de consulta e não é escrito em nenhum lugar que dê para ler. Enquanto isso não for confirmado, trate a ausência dele como “ainda não sei”, e não como “ainda não processou”.

## Ver também

- Índice da documentação: https://doc.apibrasil.io/llms.txt
- Versão HTML desta página: https://doc.apibrasil.io/webhooks
