# Buscar mensagens

[`GET /messages`](/endpoint/get/messages) lê as mensagens guardadas da inbox, da mais nova para a mais antiga.
Cada item é a [mensagem](/docs/mensagem), no mesmo formato do envio e dos eventos.

```
GET /messages?chat_id=5511999999999&limit=20
```

```json
{
  "messages": [
    {
      "id": "3EB0A1...",
      "type": "text",
      "text": "oi",
      "...": "..."
    }
  ],
  "next_cursor": "MTc5MjIzODQwMDAwMHwzRUIwQTE"
}
```

## Paginação

- `limit`: de 1 a 200 itens por página (padrão 50).
- `next_cursor`: vem enquanto houver mais. Para a próxima página, repita a mesma busca com `cursor=<next_cursor>`.
  Sem `next_cursor`, acabou.
- **Não pula nem repete:** o cursor marca a posição exata (o horário e o id da última mensagem lida). Mensagem que
  chega enquanto você pagina não empurra as outras: ela aparece numa busca nova, do começo.
- **Página com menos itens não quer dizer fim.** Com um filtro raro (por exemplo `type=sticker` numa inbox com
  muitas mensagens), a api para de procurar depois de um certo volume e devolve o que achou, até vazio, com
  `next_cursor`. Continue enquanto vier `next_cursor`.

## Filtros

Todos são opcionais e se combinam, **menos o `message_id`**: com `message_id`, a busca devolve aquela mensagem e
ignora os outros filtros.

| Filtro | O que faz |
|---|---|
| `chat_id` | Só desta conversa. Aceita o número (com ou sem `+`, com ou sem o nono dígito), o id do WhatsApp, o LID ou o id do grupo. A api inclui as outras formas da mesma conversa (o LID de um número e o número de um LID), porque o WhatsApp guarda mensagens das duas. |
| `message_id` | Uma mensagem só, pelo `id` dela. Volta numa lista com um item (ou vazia). |
| `direction` | `in` (do contato) ou `out` (da inbox). |
| `type` | Tipos, separados por vírgula (`image,video`). Tipo desconhecido responde `400`. |
| `category` | Classes, separadas por vírgula (veja abaixo). |
| `track_source`, `track_id` | As mensagens que você enviou com esse rastreamento. |
| `after`, `before` | Enviadas depois ou antes de uma data (ISO 8601). Os limites não entram: `after` é "depois de", não "a partir de". |

### Classes (`category`)

Vem em cada mensagem (campo `category`), dado pela api: leia o campo em vez de deduzir do `type` ou do `status`.
Só `conversation` não apagada aceita resposta, reação, edição e fixar.

| `category` | O que entra |
|---|---|
| `conversation` | As mensagens da conversa (texto, mídia, botões...): o que aparece como balão, apagada inclusive. |
| `reaction` | Reações. |
| `call` | Ligações. |
| `event` | O que não é balão: edição, voto de enquete, fixar, registros do grupo e do sistema (alguém entrou, mudou o nome do grupo...). |
| `unsent` | Envios que ainda não chegaram ao canal: agendado, na fila, enviando, com falha ou cancelado. |

Para mostrar uma conversa como no WhatsApp: `category=conversation,call,event`.

## Sem `chat_id`

A busca percorre a inbox toda, o que serve para sincronizar ("o que chegou desde ontem?":
`after=2026-10-16T00:00:00.000Z`). As publicações de Status (`status@broadcast`) ficam de fora; para elas, filtre
por `chat_id=status@broadcast`.

## O que a busca vê

- Mensagens recebidas e enviadas, inclusive as que ainda estão sendo gravadas (a busca junta o que está em memória com
  o que já foi gravado, sem repetir).
- O status mais recente de cada mensagem.
- O nome de quem escreveu (`author.name`), da agenda. A mensagem traz só o `chat_id`; o nome da conversa vem em [`GET /chats`](/endpoint/get/chats).
- **Não traz miniatura** (nem da mídia, nem do link, da localização ou do convite; ela vem só no evento em tempo real) nem o arquivo: o `url` vem quando o arquivo já foi
  baixado.
