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

# Catálogo de eventos

> Esquemas, enums y ejemplos de los 6 tipos de eventos entregados vía webhook y WebSocket

El webhook y el WebSocket comparten el **mismo envoltorio** y el **mismo catálogo** de eventos. La única diferencia es el canal de entrega, `data` es idéntico.

Esta página documenta los 6 tipos: **`message.exchange`**, **`message.status`**, **`call.update`**, **`group.flow`**, **`instance.state`** y **`label.update`**.

## Envoltorio

```json theme={null}
{
  "event": "<event-name>",
  "data": { /* event-specific payload */ },
  "instanceData": {
    "baseUrl": "https://api.example.com",
    "instance": "<name>",
    "token":    "<instance-token>"
  }
}
```

El filtrado se hace por el nombre del `event` en el campo `events` de la configuración. Vacío = todos los tipos.

## Filtrado y enrutamiento

```json theme={null}
{ "events": ["message.exchange", "call.update", "instance.state"] }
```

Cuando `byEvents=true` (solo webhook), el nombre del evento se **agrega a la URL**:

* Configuración: `url: "https://app/wh"`, `byEvents: true`
* Entrega: `POST https://app/wh/message.exchange`

Útil para enrutamiento basado en endpoints sin inspeccionar el payload.

***

## `message.exchange`

Mensajes enviados y recibidos (texto, media, sticker, documento, audio, encuesta, contacto, ubicación, etc.), ediciones y revocaciones.

### Payload

```json theme={null}
{
  "id": "wamid.msg.123",
  "message": {
    "id": "wamid.msg.123",
    "direction": "incoming | outgoing",
    "timestamp": "2026-04-28T10:30:00Z",
    "chat": {
      "jid": "5511999999999",
      "lid": "100@s.whatsapp.net",
      "name": "João Silva",
      "type": "private | group | newsletter",
      "isCommunity": true
    },
    "sender": {
      "jid": "5511999999999",
      "lid": "100@s.whatsapp.net",
      "name": "João Silva"
    },
    "content": { "text": "Hello" },
    "media": {
      "type": "image | video | audio | document | sticker | ptt | ptv",
      "url": "https://media-...whatsapp.net/...",
      "s3Url": "https://bucket.s3.amazonaws.com/...",
      "base64": "iVBORw0KGgo...",
      "mimetype": "image/jpeg",
      "size": 45678,
      "caption": "Event photo",
      "fileName": "doc.pdf"
    },
    "edit": {
      "original_id": "wamid.original",
      "originalContent": "Old text",
      "text": "New text"
    },
    "forward": { "count": 2 },
    "reply": {
      "message_id": "wamid.replied",
      "sender": { "jid": "...", "name": "..." },
      "text": "...",
      "media": { /* simplified media object */ }
    },
    "poll": {
      "title": "Which flavor?",
      "options": [{ "name": "Chocolate", "count": 0 }]
    },
    "location": {
      "latitude": -23.5505,
      "longitude": -46.6333,
      "address": "Av. Paulista, 1374"
    },
    "contact": {
      "display_name": "Maria",
      "phone_number": "5511987654321",
      "vcard": "BEGIN:VCARD..."
    },
    "list_response": {
      "title": "...",
      "body": "...",
      "list_type": "single_select",
      "single_select_reply": { "option_name": "p1" }
    },
    "button_response": {
      "title": "Buy",
      "body": "...",
      "selected_button_id": "buy_camiseta"
    },
    "interactive": { /* form / native flow / other surfaces */ }
  }
}
```

### Campos condicionales

Solo se completan los campos relevantes para el tipo de mensaje. Las ediciones tienen `edit` poblado; las revocaciones llegan con `type: "message_revoke"` en `data.message.type`.

<Note>
  `chat.isCommunity` aparece **solo cuando es `true`**, indicando que el chat es el canal de anuncios (parent / announcement channel) de una comunidad de WhatsApp. Los subgrupos vinculados a una comunidad mantienen `type: "group"` y **no** incluyen el campo `isCommunity`. En grupos regulares y DMs el campo también se omite.
</Note>

<Tip>
  `media.base64` solo aparece cuando `mediaBase64=true` en la configuración (webhook o WebSocket). De lo contrario, usa `media.url` (whatsapp.net, expira) o `media.s3Url` (si S3 está configurado en la instancia).
</Tip>

### Ejemplo (imagen recibida)

```json theme={null}
{
  "event": "message.exchange",
  "data": {
    "id": "wamid.123",
    "message": {
      "id": "wamid.123",
      "direction": "incoming",
      "timestamp": "2026-04-28T10:30:00Z",
      "chat":   { "jid": "5511999999999", "name": "João", "type": "private" },
      "sender": { "jid": "5511999999999", "name": "João" },
      "media": {
        "type":     "image",
        "url":      "https://media-abc.whatsapp.net/...",
        "mimetype": "image/jpeg",
        "size":     45678,
        "caption":  "Photo"
      }
    }
  },
  "instanceData": { "baseUrl": "https://api...", "instance": "minha", "token": "..." }
}
```

***

## `message.status`

Acuses de entrega: delivered, read, played, etc.

### Payload

```json theme={null}
{
  "status": "delivered | read | played | sender | read_self | played_self | retry | inactive | server_error",
  "messageIds": ["wamid.123", "wamid.124"],
  "timestamp":  "2026-04-28T10:45:00Z",
  "chat": {
    "jid": "5511999999999",
    "type": "private | group | broadcast",
    "isCommunity": true
  },
  "recipient":     "5511999999999",
  "messageSender": null,
  "isFromMe":      false
}
```

### Enum `status`

| Valor          | Significado                                                      |
| -------------- | ---------------------------------------------------------------- |
| `delivered`    | El mensaje llegó al dispositivo del destinatario.                |
| `read`         | El destinatario lo leyó (con confirmaciones de lectura activas). |
| `played`       | Audio/nota de voz reproducida.                                   |
| `sender`       | Eco interno (la propia fuente reportando entrega).               |
| `read_self`    | El **propio usuario** lo marcó como leído en otro dispositivo.   |
| `played_self`  | El propio usuario lo reprodujo en otro dispositivo.              |
| `retry`        | El servidor solicitó re-entrega (transitorio).                   |
| `inactive`     | El destinatario lleva demasiado tiempo offline.                  |
| `server_error` | Error genérico del servidor de WhatsApp.                         |

<Note>
  * `messageSender` en **grupos**: JID del autor original del mensaje (relevante cuando alguien lee un mensaje de otro participante).
  * `chat.isCommunity` sigue la misma regla que `message.exchange`: presente y `true` solo cuando el chat es el canal de anuncios de una comunidad.
</Note>

***

## `call.update`

Eventos de llamadas: offer, accepted, rejected, terminated, latency.

### Payload

```json theme={null}
{
  "type": "offer | accepted | rejected | terminated | notification | latency",
  "direction": "incoming | outgoing",
  "callId": "call-abc123",
  "from": "5511999999999",
  "to":   "5511888888888",
  "timestamp": "2026-04-28T10:35:00Z",
  "groupJid": null,
  "callMedia": "audio | video | null",
  "remotePlatform": "Android | iPhone | null",
  "remoteVersion": "2.23.15.74",
  "noticeType": "group | null",
  "reason": null,
  "duration": 123,
  "latency":  45.6,
  "latencyStatus": "Excellent | Good | Average | Poor"
}
```

### Enum `type`

| Valor          | Cuándo se dispara                                                          |
| -------------- | -------------------------------------------------------------------------- |
| `offer`        | Llamada recibida/enviada (timbre inicial).                                 |
| `accepted`     | El lado remoto contestó.                                                   |
| `rejected`     | El lado remoto rechazó.                                                    |
| `terminated`   | Llamada finalizada, se completa `duration` en segundos.                    |
| `notification` | Notificación contextual de llamada (p. ej., llamada perdida en grupo).     |
| `latency`      | Métrica de latencia durante la llamada (`latency` en ms, `latencyStatus`). |

<Tip>
  Para auto-rechazar llamadas, configura `autoRejectCalls=true` en el [bloque de configuración de la instancia](/es/api/instance/settings-update), aún recibirás los eventos `offer` + `rejected` en el webhook.
</Tip>

***

## `group.flow`

Cambios de grupo: miembros, metadatos, configuraciones.

### Payload, cambio de participante

```json theme={null}
{
  "type": "joined | left | promoted | demoted",
  "groupJid": "120363406289005073@g.us",
  "groupName": "Dev Team",
  "timestamp": "2026-04-28T11:00:00Z",
  "participants": [
    { "jid": "5511999999999", "action": "joined" }
  ]
}
```

### Subtipos de metadatos

| `type`                        | Significado                                         |
| ----------------------------- | --------------------------------------------------- |
| `name`                        | Nombre del grupo cambiado                           |
| `topic`                       | Descripción cambiada                                |
| `locked` / `unlocked`         | Los miembros pueden/no pueden editar la información |
| `announce` / `not_announce`   | Los miembros pueden/no pueden enviar mensajes       |
| `ephemeral` / `not_ephemeral` | Mensajes efímeros activados/desactivados            |
| `invite`                      | Enlace de invitación generado                       |
| `link` / `unlink`             | Subgrupo vinculado/desvinculado de la comunidad     |
| `delete`                      | Grupo eliminado                                     |
| `membership_approval`         | Modo de aprobación para nuevos miembros cambiado    |
| `suspended` / `unsuspended`   | Grupo suspendido/reactivado por WhatsApp            |

***

## `instance.state`

Cambios en el estado de la propia instancia (conexión, QR, ban, emparejamiento).

### Payload

```json theme={null}
{
  "instance": "minha",
  "state": "connected | disconnected | logged_out | stream_replaced | temp_banned | client_outdated | connect_failure | stream_error | cat_refresh_error | qr_ready | pair_success | pair_error | qr_scanned_no_multidevice | keepalive_timeout | keepalive_restored | manual_reconnect",
  "timestamp": "2026-04-28T10:50:00Z",
  "reason": "...",
  "reasonCode": 123,
  "message": "...",
  "expireAt": "2026-04-28T11:50:00Z",
  "expireInSeconds": 3600,
  "onConnect": true,
  "codes": ["1@abc...,xyz==,base64string"],
  "jid": "5511999999999@s.whatsapp.net",
  "platform": "iPhone | Android | Desktop",
  "errorMsg": "..."
}
```

### Enum `state`

| Estado                      | Significado                                                               | Campos extra completados                |
| --------------------------- | ------------------------------------------------------------------------- | --------------------------------------- |
| `connected`                 | Sesión activa, lista para enviar/recibir.                                 | ,                                       |
| `disconnected`              | Desconectado (transitorio, usualmente reconecta solo).                    | ,                                       |
| `logged_out`                | Sesión invalidada (requiere nuevo `connect`).                             | `reason`                                |
| `stream_replaced`           | Otra sesión tomó el control (conflicto multi-dispositivo).                | ,                                       |
| `temp_banned`               | Ban temporal aplicado por WhatsApp.                                       | `expireAt`, `expireInSeconds`, `reason` |
| `client_outdated`           | La versión de WhatsApp Web en uso está desactualizada, contactar soporte. | `message`                               |
| `connect_failure`           | Falla durante la conexión.                                                | `reason`, `reasonCode`                  |
| `stream_error`              | Error de stream de WhatsApp.                                              | `errorMsg`                              |
| `cat_refresh_error`         | Falla al refrescar credenciales (`cat`).                                  | `errorMsg`                              |
| `qr_ready`                  | Nuevo QR disponible para emparejamiento.                                  | `codes[]`, `onConnect`                  |
| `pair_success`              | Emparejamiento completado.                                                | `jid`, `platform`                       |
| `pair_error`                | Error durante el emparejamiento.                                          | `errorMsg`                              |
| `qr_scanned_no_multidevice` | QR escaneado pero el dispositivo destino no soporta multi-dispositivo.    | ,                                       |
| `keepalive_timeout`         | Conexión inestable, keepalive no respondido.                              | ,                                       |
| `keepalive_restored`        | Conexión estabilizada después de `keepalive_timeout`.                     | ,                                       |
| `manual_reconnect`          | Reconexión disparada manualmente vía REST.                                | ,                                       |

<Tip>
  Para que tu cliente sepa cuándo refrescar el QR en la UI, escucha `instance.state` con `state=qr_ready` y renderiza `data.codes[0]`.
</Tip>

***

## `label.update`

Ediciones/asociaciones de etiquetas (etiquetas de WhatsApp Business).

### Payload

```json theme={null}
{
  "type":   "edit | chat | message",
  "labelId": "1",
  "timestamp": "2026-04-28T10:00:00Z",
  "action": "updated | deleted | add | remove",

  // type=edit:
  "name": "Important",
  "color": 0,
  "labelType": "CUSTOM",
  "isActive": true,
  "isImmutable": false,
  "orderIndex": 1,
  "deleted": false,

  // type=chat:
  "chatJid": "5511999999999@s.whatsapp.net",
  "labeled": true,

  // type=message:
  "messageId": "wamid.abc"
}
```

### Combinaciones `type` × `action`

| `type`    | `action` válida      | Campos extra                                                                     |
| --------- | -------------------- | -------------------------------------------------------------------------------- |
| `edit`    | `updated`, `deleted` | `name`, `color`, `labelType`, `isActive`, `isImmutable`, `orderIndex`, `deleted` |
| `chat`    | `add`, `remove`      | `chatJid`, `labeled`                                                             |
| `message` | `add`, `remove`      | `chatJid`, `messageId`                                                           |

***

## Eventos no emitidos (internos)

Capturados por el handler de `whatsmeow` pero **no** propagados vía webhook/WS:

* `*events.Picture`, cambio de foto de perfil (solo registrado en log).
* `*events.FBMessage`, Facebook Business (solo registrado en log).
* `*events.HistorySync`, sincronización de historial (procesado y almacenado en BD).

Si necesitas consumir alguno de estos cambios, haz polling de los endpoints REST correspondientes (perfil, historial).

## Referencias

<CardGroup cols={2}>
  <Card title="Configurar webhook" icon="webhook" href="/es/api/events/webhook-configure">
    Filtra eventos vía `events[]` en la configuración.
  </Card>

  <Card title="Configurar WebSocket" icon="plug" href="/es/api/events/websocket-configure">
    Misma sintaxis de filtro que el webhook.
  </Card>

  <Card title="Conectar vía WebSocket" icon="bolt" href="/es/api/websocket">
    Recibe eventos en tiempo real.
  </Card>

  <Card title="Resumen de eventos" icon="bell" href="/es/api/events/overview">
    Comparación webhook vs WebSocket.
  </Card>
</CardGroup>
