Webhooks
Webhooks overview
Receive signed, environment-specific HTTP events as message and delivery state changes occur.
What this guide covers
- Create separate endpoint configurations for Test Mode and Live Mode.
- Subscribe only to event types your application handles.
- Verify every signature before parsing or processing the event.
Configure an endpoint
Webhook endpoint lifecycle is managed from the Agent Project dashboard, not through public /v1 endpoint-creation routes. Open API → Webhooks, select Live Mode or Test Mode, and create the destination in that environment.
Yanola creates deliveries only for enabled endpoints whose event and optional Sender filters match the event. Disabled endpoints keep their configuration but receive no new deliveries.
| Setting | Contract |
|---|---|
Environment | Fixed to live or test. Events and deliveries never cross environments. |
URL | Public HTTPS in both Live Mode and Test Mode. To receive events on your machine, expose your local receiver through an HTTPS tunnel such as cloudflared or ngrok. |
Payload mode | yanola, meta, or yanola_with_raw. |
Sender filter | All current and future Senders, or an explicit set of up to 100 connected Senders. |
Event types | At least one supported public event type. |
Enabled | Controls whether matching events create new deliveries. |
Endpoints, in Live and Test Mode, cannot target localhost or private, link-local, metadata, or reserved networks. Yanola resolves and pins the destination before delivery and does not follow redirects.
Store the copy-once signing secret
Yanola shows the endpoint signing secret only when the endpoint is created or its secret is rotated. Store the whsec_ value in a server-side secret manager as YANOLA_WEBHOOK_SECRET.
Rotating a secret creates a bounded overlap in which Yanola signs with the active and retiring secrets. The yanola-signature header contains one v1 digest per accepted secret so you can deploy the new secret without dropping deliveries.
- Create the endpoint and copy the secret before closing the dialog.
- Store separate secrets for Live Mode and Test Mode endpoints.
- Never expose the secret in browser code, source control, logs, or support screenshots.
- When rotating, deploy the new secret promptly and remove the retired secret after the dashboard grace period ends.
Delivery request contract
Yanola sends an HTTP POST with an application/json body. The payload bytes are signed before delivery; verify them before JSON parsing or any side effect.
| Header | Meaning |
|---|---|
Content-Type | application/json |
User-Agent | Yanola-Webhooks/1.0 |
yanola-signature | t=<unix_seconds>,v1=<hex_hmac_sha256>[,v1=...] |
yanola-timestamp | The signing timestamp in Unix seconds. |
yanola-event-id | Stable evt_ identity for deduplicating business processing. |
yanola-delivery-id | Stable del_ identity for this automatic or replay delivery. |
yanola-payload-format | yanola, meta, or yanola_with_raw. |
yanola-replayed | Present with value true only on a manual replay delivery. |
Stable webhook compatibility
The signed headers, three payload-mode identities, normalized Event envelope, any-2xx acknowledgement, and at-least-once delivery semantics are part of the GA contract. Yanola does not remove or reinterpret them within v1.
New optional normalized fields and newly supported event types are additive. A new event type reaches an endpoint only after it is included in that endpoint's subscription. Ignore unknown fields, handle raw as nullable in yanola_with_raw mode, and treat provider-compatible fields in meta mode as extensible.
The meta body preserves the documented WhatsApp webhook structure for migration. It is still a Yanola-signed delivery and is not a byte-for-byte Meta request, Meta authentication contract, or promise that every provider-only field is retained.
Acknowledge durable acceptance
Yanola considers any 2xx response successful. Every other status, connection failure, or 10-second timeout is a failed attempt and can be retried.
- Read the exact raw request body.
- Verify yanola-signature and its timestamp before parsing JSON.
- Validate the payload shape selected by yanola-payload-format.
- Atomically deduplicate and persist the event using yanola-event-id or the normalized event id.
- Return 2xx only after durable acceptance.
- Process slow business work asynchronously after the response.
Returning 2xx and then losing in-memory work prevents Yanola from retrying. A queue or database write should be complete before acknowledgement.
Environment and subscription isolation
Live events are dispatched only to matching Live endpoints and Test events only to matching Test endpoints. Use separate URLs or route configuration when you want an obvious operational boundary.
Webhook endpoint counts, payload retention, and throughput can be controlled by the Yanola Subscription. Inbound webhook processing and Test Mode delivery do not consume message-send Yanola Balance.
Inspect delivery state
Use the dashboard Delivery history or an API key with webhooks:read to inspect safe delivery summaries. Public delivery reads expose status, attempts, timing, response status, a bounded redacted response preview, payload format, and replay state—not endpoint URLs, secrets, request bodies, or unredacted responses.
import { WhatsAppClient } from "@yanola/whatsapp"
const apiKey = process.env.YANOLA_API_KEY
if (!apiKey) {
throw new Error("Missing YANOLA_API_KEY")
}
const yanola = new WhatsAppClient({ apiKey })
const failures = await yanola.webhookDeliveries.list({
status: "failed",
createdAfter: "2026-07-29T00:00:00.000Z",
limit: 100,
})
for (const delivery of failures.data) {
console.log(
delivery.id,
delivery.eventId,
delivery.attemptCount,
delivery.responseStatus
)
}Production checklist
- Use a public HTTPS endpoint and keep DNS targets public.
- Store the copy-once signing secret in a server-side secret manager.
- Verify signatures over raw bytes with the SDK helper.
- Deduplicate event processing and retain safe correlation IDs.
- Return 2xx within 10 seconds after durable acceptance.
- Monitor failed deliveries and auto-disabled endpoints.
- Exercise the same handler with a Test Mode endpoint before enabling Live Mode.