WhatIsUp.dev
Comenzar
Esta página está disponible solo en inglés por ahora.

Event payloads

Every webhook body has the same envelope:

{
  "event": "message.received",
  "event_id": "evt_01J...",
  "api_version": "2026-04",
  "instance_id": "inst_01J...",
  "occurred_at": "2026-05-01T12:34:56.000Z",
  "data": { /* event-specific shape, see below */ }
}

The envelope fields:

FieldNotes
eventThe event name. See list below.
event_idULID, stable across retries. Use as your dedupe key.
api_versionDate-stamped version of the event schema. We won't break shape within a version.
instance_idThe instance that produced the event. Always present.
occurred_atWall-clock time at the gateway when the event was emitted.
dataEvent-specific payload, schemas below.

Event types

The full list of events comes straight from @whatisup/contracts:

  • qr.updated — A new QR PNG is available for an instance. The dashboard uses this; webhook subscribers usually filter it out.
  • instance.connected — The instance finished pairing. Includes phone_number.
  • instance.disconnected — The session ended. Includes reason (network, logout, session_invalidated, kicked_other_device).
  • message.received — Inbound message from a contact. Includes from, body (text or media reference), and received_at.
  • message.sent — Your outbound message reached WhatsApp. Includes message_id.
  • message.delivered — The recipient's device acked the message.
  • message.failed — Terminal send failure. Includes error.code and error.message.

Headers your endpoint will see

POST /your/endpoint HTTP/1.1
Host: api.acme.dev
Content-Type: application/json
User-Agent: whatisup-webhooks/0.0.1
X-WhatIsUp-Signature: t=1700000000,v1=...
X-WhatIsUp-Event: message.received
X-WhatIsUp-Event-Id: evt_01J...
X-WhatIsUp-Correlation-Id: req_01J...

X-WhatIsUp-Event-Id and X-WhatIsUp-Event are conveniences — they mirror what's in the body, but let you route or short-circuit before you parse the JSON.

X-WhatIsUp-Correlation-Id traces the event back to whatever triggered it. For an outbound message.sent it's the request ID of the POST /v1/messages call. For a message.received it's a generated ID stable across retries. Useful in logs.

Compatibility

We versioned the schemas via api_version. Within 2026-04, we'll only add optional fields — never rename, never remove. New incompatible shapes get a new version string; you opt in by upgrading your endpoint at your pace. (We don't have multiple versions live yet — just one.)

The wire payloads here are the same shapes that come down /v1/events. The SSE stream is just an unsigned, untoaster real-time view of the same bus.