---
title: Events and recovery | API Docs
description: Combine live notifications with durable account and chat logs.
---

The API separates notification from durable content:

1. `GET /v1/streams/events` delivers live account events over SSE.
2. `GET /v1/event_log` pages the same account sequence for bounded recovery.
3. `GET /v1/chats/{chat}/events` returns the detailed, gapless journal for one chat.

An account event identifies a chat and a `seq_from`–`seq_to` range. Fetch that range from the chat journal to read the content. Do not treat every event as a reply trigger: one customer message may also produce a window-opened event, and an outbound message may later produce delivered and read events. A `message.failed` event points at the message; the message row you fetch is what carries the [published failure reason](/channel/whatsapp/guides/messaging/sending-messages#why-a-message-failed/index.md), when there is one.

## Cursor rules

- Persist the SSE `id` and send it back as `Last-Event-ID` after reconnecting.
- The event-log cursor is opaque; pass `next_cursor` back unchanged.
- A chat cursor is the last gapless numeric `seq` you processed.
- Keep all three cursor domains separate.
- A cursor older than retained account history returns HTTP `410` with `error.code` [2032](/channel/whatsapp/error/codes/2xxx/2032/index.md); reconnect without a cursor to continue from the current position.
- Ignore unknown event kinds so newly added kinds remain backward compatible.

Webhooks carry the same stable event identity as the stream. Deduplicate the two sinks by event ID if you consume both.

With [zero-day retention](/channel/whatsapp/guides/platform/data-retention#zero-day-retention/index.md), the stream and the event log carry empty `parts` and `zero_retention: true`.

## Messages with attachments

A `message.received` event for a message carrying an image, video, audio, document or sticker can be recorded once every attachment has been captured or has failed, or ten minutes after the message arrived, whichever comes first. It takes its position in the stream and the event log when it is recorded, so its attachments can be ready to [download](/channel/whatsapp/guides/messaging/sending-messages#download-incoming-attachments/index.md) when it arrives. This is being enabled gradually.

Such an event can arrive after events for later messages of the same chat, on webhooks, the event stream and the event log alike. Its `data.seq_from` can be lower than one you already received, and its `chat.window.opened` event can arrive first.

- Never discard an event because its `seq_from` is lower than one already received.
- Deduplicate by the event `id`.
- Order a chat by `data.seq_from`.
- For live processing, buffer briefly or reconcile with `GET /v1/chats/{chat}/events`.

Events for messages without attachments, and every other event kind, keep their order.
