Skip to main content
The account webhook is the recommended way to receive Enterprise events. You configure it once on your account and it starts receiving events from all your instances, with no per-instance setup. The per-instance webhook still works (backward compatible with what already exists), but for trial and billing events the account webhook is preferred: a single endpoint, a single signing secret, and it follows the instances you create and delete with no extra work.

Configure the account webhook

There are two ways to configure it.

In the panel

In the panel, at /settings, you set the URL that receives the events, pick which events you want, view and rotate the signing secret, and send a test event to confirm your endpoint is receiving and verifying the signature.

Via the API

Every route accepts the account TokenAccount, or the global token passing ?account=<account-name>. GET /api/account/webhook Returns the current configuration. The secret is never returned in cleartext on a read, only masked.
200 OK
PATCH /api/account/webhook Saves the URL, the event list, and turns it on or off. On the first configuration, when the account still has no secret, the response includes the secret in cleartext once. Store that value, it is not shown again. To get a new one, rotate the secret.
string
Endpoint that receives the deliveries. Use HTTPS. An unsafe or disallowed URL is rejected with 400.
array
The event names you want to receive. If you omit the field, the account uses the four events by default. An empty list ([]) means “receive none”.
boolean
Turns delivery on or off. With false, the configuration is preserved but nothing is delivered.
string
Account name. Required only when you use the global token. With the TokenAccount, the account comes from the token itself.
200 OK (first configuration)
The secret only appears in this first response (and when you rotate it). After that, a read returns just the secretMasked. If you lose the value, rotate to generate a new one.
POST /api/account/webhook/rotate-secret Generates a new secret and returns it once. The previous secret stops being used on subsequent deliveries.
200 OK
POST /api/account/webhook/test Sends an enterprise.webhook.test event to the configured URL, so you can validate reception and the signature. Responds 400 if there is no URL configured. The test event is delivered even when the configuration is disabled.
test event delivered

The four events

Envelope

Every delivery has the same JSON body:
string
Event name in the form enterprise.<kind>, one of the four above (or enterprise.webhook.test).
string
Your account name.
string
A human-readable English summary of what happened. Handy for logs and for showing to your team.
object
The event fields. The content varies per event kind, see below.
string
Time of the delivery, in RFC3339 (UTC).

enterprise.instance.billable

enterprise.cycle.renewed

data fields

The data object carries only the fields relevant to each event.

Trial events (trial.started, trial.ending)

string
Instance name.
string
WhatsApp number connected to the instance. Populated when a number is already associated.
string
Date and time when the trial ends, in RFC3339.

Switch to billing (instance.billable)

string
Instance name.
string
WhatsApp number connected to the instance. Populated when a number is already associated.
string
Date and time from which the instance is billed, in RFC3339.

Monthly renewal (cycle.renewed)

integer
Amount actually charged on the renewal, in cents.
integer
The base for the period (the floor), in cents.
integer
How much usage went over the base, in cents. It is 0 when usage fits within the base.
string
Start of the charged period, in RFC3339.
string
End of the charged period, in RFC3339.

Validate the signature

Every delivery carries the header X-Ryze-Signature: sha256=<hex>, an HMAC-SHA256 of the raw request body using your account signing secret. Compute the same HMAC on your server and compare, to be sure the delivery came from RyzeAPI and was not tampered with.
Compare in constant time (timingSafeEqual / compare_digest), never with a string ==. And use the body exactly as received (the raw bytes), not the reserialized JSON, otherwise the signature will not match.
When you rotate the secret, accept both the new and the previous secret for a short window. That way, deliveries already in flight during the switch keep validating.

Per-instance webhook (still supported)

Before the account webhook, Enterprise events were delivered to the instance’s own webhook. That still holds: if an instance’s webhook (or WebSocket) events list includes the enterprise.* names, that instance’s events also arrive there, in the same envelope as the API’s other events. See Configure webhook. For billing and lifecycle, prefer the account webhook: a single endpoint receives everything, with no per-instance setup, and the deliveries are signed.

Next

Billing control

Force billing on an instance.

FAQ

Common questions about trial, billing and events.