Skip to main content

What are webhooks?

Webhooks are HTTP notifications that Omni Z-API sends to your server when events happen — such as a message received, delivery status, or a template update. Instead of your system periodically polling the API, Omni Z-API pushes events to you as they happen.
Any valid secret key of an active workspace can manage webhooks, both channel and template ones. No specific role is required on your account. If the workspace is not active, webhook calls return 422 with {"error": "Webhook management requires an active workspace"}.

Webhook types

Omni Z-API has three webhook types. What differs between them is the accepted events and how they are associated — each section covers its own specifics. The rest of this page applies to all three types.

Channel webhooks

Receive the events of a specific channel (messages, delivery, connection).

Template webhooks

Receive WhatsApp template events, independent of any instance.

Default webhook

Receives the events of every channel in the workspace that has no webhook of its own.

Payload formats

Omni Z-API supports three payload formats:
payloadFormat applies to channel webhooks only. On template webhooks the format is always DEFAULT and the field is discarded.

Webhook URL

When you create a webhook, and when you change the URL of an existing one, Omni Z-API checks the url before saving it. The rules apply to both webhook types. The host is refused when it:
  • is an IP that is not public: private network, loopback, link-local (including the cloud metadata address 169.254.169.254), CGNAT, multicast, or a reserved range, in IPv4 or IPv6;
  • is a name that resolves to one of those addresses. A single non-public address among the ones the name returns is enough;
  • is localhost, ends in .localhost or .internal, or is a name without a dot, such as https://server/webhook;
  • is an IPv4 address written outside the usual four decimal numbers, such as http://2130706433/;
  • does not exist in DNS or has no address.
If DNS does not answer in time, the response is 503 with {"error": "Could not verify the webhook URL now, try again"}. Nothing is saved: try again.
http is still accepted, but prefer https: with http, the event body and the authentication headers travel unencrypted.
On update, the url is only checked when it changes. A PATCH without url, or with the URL already stored, is not refused because of it: an old webhook whose URL would be refused today can still be disabled, have other fields changed, or be deleted.

Webhook authentication

You can configure how Omni Z-API authenticates when calling your URL:

HMAC signing

To ensure requests received are genuinely from Omni Z-API and have not been tampered with, enable HMAC signing by setting signing: true when creating the webhook. When enabled:
  • A 64-character hexadecimal secret is generated and returned only once on create/update.
  • Each request sent to your webhook carries the x-webhook-signature header, in the form t={unix_timestamp},v1={hmac_sha256_hex}.
  • You verify the signature on your server using the stored secret.
The signature is not the HMAC of the body alone. It is computed over a canonical string of five fields, of which the body is the last. See HMAC signing for the exact string, a complete example, and ready-to-use verification code.
The secret is shown only in the create response or in an update with signing: true. Store it securely — it cannot be retrieved afterwards.