> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zapfy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Eventos

> O envelope canônico e o payload de cada evento. A mesma forma, seja qual for a conexão com o WhatsApp.

Todo evento chega no **mesmo envelope**. Os campos do topo não mudam; só o `data`
varia por tipo de evento. O payload é **normalizado pela Zapfy** — não muda quando a
conexão com o WhatsApp muda.

## Envelope

```json theme={null}
{
  "event": "MESSAGE_RECEIVED",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:34:56.789Z",
  "data": { }
}
```

<ResponseField name="event" type="string">
  Tipo do evento, em `UPPER_SNAKE`. Um dos valores abaixo.
</ResponseField>

<ResponseField name="instanceId" type="string">
  ID da instância na Zapfy que originou o evento.
</ResponseField>

<ResponseField name="id" type="string">
  ID único do evento. Use como **chave de idempotência** (a entrega é at-least-once).
</ResponseField>

<ResponseField name="timestamp" type="string">
  Momento da emissão, ISO 8601 (UTC).
</ResponseField>

<ResponseField name="data" type="object">
  Payload específico do evento — descrito abaixo. Os exemplos a seguir mostram o evento
  completo (envelope + `data`).
</ResponseField>

## Tipos de evento

| Evento              | Quando dispara                             |
| ------------------- | ------------------------------------------ |
| `MESSAGE_RECEIVED`  | Você recebeu uma mensagem.                 |
| `MESSAGE_SENT`      | Você enviou uma mensagem.                  |
| `MESSAGE_STATUS`    | Uma mensagem foi entregue, lida ou falhou. |
| `CONNECTION_UPDATE` | Seu número conectou ou desconectou.        |
| `QRCODE_UPDATED`    | Um novo QR Code foi gerado para conectar.  |

## MESSAGE\_RECEIVED / MESSAGE\_SENT

Mensagem em **conversa de contato** (1:1):

```json theme={null}
{
  "event": "MESSAGE_RECEIVED",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:34:56.789Z",
  "data": {
    "messageId": "3EB0C767D...",
    "fromMe": false,
    "chat": {
      "jid": "5511999998888@s.whatsapp.net",
      "phone": "5511999998888",
      "isGroup": false,
      "name": null
    },
    "sender": {
      "jid": "5511999998888@s.whatsapp.net",
      "phone": "5511999998888",
      "name": "João Silva"
    },
    "type": "TEXT",
    "text": "Olá, tudo bem?",
    "media": null
  }
}
```

Mensagem em **grupo** — `chat` é o grupo (`phone: null`) e `sender` é o participante que enviou:

```json theme={null}
{
  "event": "MESSAGE_RECEIVED",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:34:56.789Z",
  "data": {
    "messageId": "3EB0C767D...",
    "fromMe": false,
    "chat": {
      "jid": "120363012345678901@g.us",
      "phone": null,
      "isGroup": true,
      "name": "Família"
    },
    "sender": {
      "jid": "5511999998888@s.whatsapp.net",
      "phone": "5511999998888",
      "name": "João Silva"
    },
    "type": "TEXT",
    "text": "Olá grupo!",
    "media": null
  }
}
```

Os campos abaixo descrevem o objeto `data`:

<ResponseField name="messageId" type="string">
  ID da mensagem no WhatsApp. Reaproveite em `delete`/`edit`.
</ResponseField>

<ResponseField name="fromMe" type="boolean">
  `true` se foi você quem enviou (`MESSAGE_SENT`); `false` se recebeu.
</ResponseField>

<ResponseField name="chat" type="object">
  A conversa — o contato ou grupo onde a mensagem está. É aqui que você responde.

  <Expandable title="chat">
    <ResponseField name="jid" type="string">
      JID da conversa (contato `…@s.whatsapp.net` ou grupo `…@g.us`). Use como destinatário pra responder.
    </ResponseField>

    <ResponseField name="phone" type="string | null">
      Telefone em E.164 (só dígitos) quando a conversa é um contato; `null` em grupo.
    </ResponseField>

    <ResponseField name="isGroup" type="boolean">
      `true` quando a conversa é um grupo.
    </ResponseField>

    <ResponseField name="name" type="string | null">
      Nome do grupo; `null` em conversa de contato.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="sender" type="object">
  Quem enviou esta mensagem. Em conversa de contato é o próprio contato; em grupo, o participante.

  <Expandable title="sender">
    <ResponseField name="jid" type="string">
      JID de quem enviou. Identificador estável mesmo quando o número não está disponível.
    </ResponseField>

    <ResponseField name="phone" type="string | null">
      Telefone do remetente em E.164; `null` quando o WhatsApp anonimiza o remetente (`@lid`).
    </ResponseField>

    <ResponseField name="name" type="string | null">
      Nome de exibição (pushName) do remetente.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="type" type="string">
  `TEXT` · `IMAGE` · `AUDIO` · `VIDEO` · `DOCUMENT` · `STICKER` · `LOCATION` ·
  `CONTACT` · `INTERACTIVE`.
</ResponseField>

<ResponseField name="text" type="string">
  Conteúdo de texto. Em mídias, traz a legenda.
</ResponseField>

<ResponseField name="media" type="object | null">
  Presente em mídias: `{ mimeType, url, filename, caption }`.
</ResponseField>

## MESSAGE\_STATUS

Status de uma mensagem **que você enviou** — `data` traz `chat` (mesma forma), sem `sender`:

```json theme={null}
{
  "event": "MESSAGE_STATUS",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:35:01Z",
  "data": {
    "messageId": "3EB0C767D...",
    "chat": {
      "jid": "5511999998888@s.whatsapp.net",
      "phone": "5511999998888",
      "isGroup": false,
      "name": null
    },
    "status": "DELIVERED",
    "error": null
  }
}
```

<ResponseField name="status" type="string">
  `PENDING` · `SENT` · `DELIVERED` · `READ` · `FAILED`.
</ResponseField>

<ResponseField name="error" type="object | null">
  Presente em `FAILED`: `{ code, message }`.
</ResponseField>

## CONNECTION\_UPDATE

```json theme={null}
{
  "event": "CONNECTION_UPDATE",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:34:56.789Z",
  "data": {
    "status": "CONNECTED",
    "phone": "5511777776666",
    "reason": null
  }
}
```

<ResponseField name="status" type="string">
  `CONNECTING` · `CONNECTED` · `DISCONNECTED`.
</ResponseField>

<ResponseField name="phone" type="string | null">
  Número da conta conectada, em E.164. `null` enquanto não há sessão (ex.: `CONNECTING` ou `DISCONNECTED`).
</ResponseField>

<ResponseField name="reason" type="string | null">
  Motivo da queda quando `DISCONNECTED` (ex.: `LOGGED_OUT`, `BANNED`).
</ResponseField>

## QRCODE\_UPDATED

```json theme={null}
{
  "event": "QRCODE_UPDATED",
  "instanceId": "01J9Z...",
  "id": "evt_01J9Z...",
  "timestamp": "2026-06-09T12:35:55Z",
  "data": {
    "qr": "data:image/png;base64,iVBOR...",
    "expiresAt": "2026-06-09T12:36:55Z"
  }
}
```

<ResponseField name="qr" type="string">
  QR Code em data URL (PNG base64) para parear o número.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  Expiração do QR, ISO 8601 (UTC).
</ResponseField>
