Webhook Migration Guide

Webhook Migration Guide: supported contracts, practical examples and recovery.

Use this checklist when updating an existing webhook integration. Webhook access is available on every plan, subject to applicable volume limits. A particular event also depends on the relevant product/channel and a working delivery path; the registered-name list alone is not a delivery guarantee.

Keep creation and management contracts separate

StepAPI and field rules
Discover namesV3 event types. Select events with a published reference and verify they are supported for your account/channel.
Inspect saved subscriptionsV3 list and GET by returned subscription id. Preserve the saved URL, channel number, selected events and current status.
Create only if neededV2 creation: tenant-prefixed route; body is an array using phoneNumber, eventTypes and numeric status. Values are 0 Disabled, 1 Enabled, 2 Defective. phoneNumber identifies your sending WhatsApp channel, not the customer.
Update an existing IDV3 PUT: request uses url, eventTypes and string status such as Enabled. A non-empty URL is required even for a status/events-only change. A non-empty eventTypes list replaces the saved event set; omitting it or sending an empty list does not clear that set.
Parse V3 responsesResponses use fields including phone_number, event_types and string status. Do not copy response casing into the PUT request.

Migration does not require creating a duplicate subscription. List first; if creation had an uncertain result, search existing subscriptions before trying again. Preserve the old configuration until the chosen transition is verified; avoid simultaneously enabled duplicate subscriptions for the same logical delivery.

For example, after reading the saved subscription and confirming the chosen events, a V3 update can be:

{
  "url": "https://example.com/webhooks/wati",
  "eventTypes": ["message", "sentMessageDELIVERED_v2"],
  "status": "Enabled"
}

Replace the URL and events with the actual intended values. Use the saved ID in PUT /api/ext/v3/webhooks/{id}; no tenant ID belongs in the V3 path.

Update event handling deliberately

Legacy and V2 notification payloads are separate from the REST API version used to manage a subscription. Do not rename an event by mechanically appending _v2.

NotificationLegacy eventTypeV2 eventType
Session message sentsessionMessageSentsessionMessageSent_v2
Template message senttemplateMessageSenttemplateMessageSent_v2
DeliveredsentMessageDELIVEREDsentMessageDELIVERED_v2
ReadsentMessageREADsentMessageREAD_v2
RepliedsentMessageREPLIEDsentMessageREPLIED_v2

Choose the supported variant your parser expects for each logical notification. If you intentionally consume both during transition, normalize and deduplicate them. Keep the documented session failure and template failure handling; failure is distinct from a send's HTTP acceptance.

V2 can add localMessageId correlation; do not require it on legacy payloads or assume every V2 payload supplies a non-empty value. A message/broadcast-link id, provider whatsappMessageId, caller localMessageId, contact ID, conversation ID and ticket ID are different identifiers. There is no universal per-delivery UUID. Treat source-dependent timestamps as context, not a guaranteed wall-clock time of the delivery/read/reply.

Verify and recover

  1. Deploy a receiver that validates the expected payload, safely queues it, then acknowledges with a 2xx. A sample callback verifies connectivity only.
  2. Use an authorized actual event to verify the chosen channel, subscription, exact eventType, identifier mapping and downstream effect.
  3. Deduplicate before applying side effects using account/channel, normalized event family/status and the applicable message identifiers. Where identifiers are absent, use a deliberate bounded payload-based fallback; do not collapse distinct status transitions into one event.
  4. Expect repeat and out-of-order deliveries. Persist processing outcomes and reconcile ambiguous/missing message outcomes through the applicable message/campaign APIs. A missing callback does not prove nothing was sent.
  5. Read the subscription status when callbacks stop. Correct the receiver/network problem before re-enabling a disabled/defective subscription; use the proper V3 PUT casing and retained URL.

Retry intervals/counts, signature support and failure handling depend on the service/event contract. Do not assume a universal HMAC header, replay API, fixed retry window or exactly-once delivery. See webhook setup and the individual payload references before changing production processing.