WhatsAble

How do outgoing webhooks work in Whatsable?

Send each incoming or outgoing WhatsApp message to Make, Zapier, n8n or your own server as it happens. Set up an endpoint in Settings → Webhooks, pause it while your team replies, combine quick messages, and optionally sign each request.

An outgoing webhook sends a WhatsApp message to an address you choose, as soon as it arrives or goes out. Use it to start a Make scenario, a Zap or an n8n workflow, or to feed your own server.

Outgoing webhooks are part of the Pro and Agency plans and the free plan, which include integrations. Bulk Message does not include them. Owners and Admins set them up. See plans.

The app says this screen is preliminary: "Delivery history and endpoint testing are not here yet." You cannot see past deliveries or send a test request from the screen today.

Add an endpoint

Go to Settings → Webhooks. The page is called Outgoing webhooks.

Start

Select Add endpoint.

Choose where it goes

Under Send to, pick Make, Zapier or n8n (incoming and outgoing messages, recommended) or Your own server (incoming messages only, one request per message). You cannot change this after you add the webhook.

Paste the address

In Webhook URL, paste the webhook address from your Make scenario, Zap or n8n workflow, or your server's address. It must be a public HTTPS address.

Pick the number

Under Number, choose All numbers or one business number. The endpoint receives only that number's messages.

Pick what to send

Under What to send, tick Incoming messages (what your customers send you), Outgoing messages (what is sent from your WhatsApp number), or both.

Sign requests, if you want to

Sign requests starts off. Leave it off and Whatsable sends the JSON with no signature. Turn it on to receive X-Notifyer-Signature-256 and X-Notifyer-Timestamp on every request. You cannot change this after you add the webhook. To switch, delete the endpoint and add it again.

Save

Select Add webhook. If you turned on Sign requests, copy the signing secret now: it is not shown again. That row shows Signed.

Each row in the list shows the endpoint, its events, its number and its status. A webhook that signs its requests shows Signed. From a row's menu you can Edit, Disable or Enable, and Delete it. Editing does not change whether requests are signed. When they are signed, the signing secret stays the same.

Older endpoints can show Native payload as their format. You cannot pick it for a new endpoint.

Pause when your team replies

When your automation also answers customers, you do not want it to answer a chat that a person is handling. Turn on Pause when your team replies (it needs Incoming messages).

  • After a team member replies, the endpoint stops getting that chat's incoming messages for 24 hours. Outgoing messages still arrive. You can change the length under Pause for, in minutes, hours or days, up to 30 days.
  • The timer restarts every time your team replies.
  • Replies from bots, broadcasts and the API don't pause it. A reply typed in the WhatsApp Business app on your phone does.
  • Endpoints with a pause show Pauses for replies in the list.

In the inbox, the contact panel has an Automations section. Under Send this chat to your automations, choose Automatic (follow the pause), Always send (even while your team is replying), or Never send (no incoming message from this chat goes to your automations). These choices apply to incoming messages only; outgoing messages still arrive.

Combine quick messages

Customers often send several short messages in a row. With Combine quick messages on, Whatsable waits until the chat is quiet and sends them as one request. The wait is 30 seconds by default and can be 1 second to 30 minutes. This option is only for the Make, Zapier or n8n format and for incoming messages.

What Whatsable sends

Each delivery is an HTTPS POST with a JSON body. This is an incoming message on the Make, Zapier or n8n format:

{
  "last_messages": "[{\"type\":\"bot\",\"content\":\"we are open until 6\",\"timestamp\":\"2026-08-11T10:00:00.000Z\",\"content_type\":\"text\"},{\"type\":\"user\",\"content\":\"are you open?\",\"timestamp\":\"2026-08-11T09:58:00.000Z\",\"content_type\":\"text\"},{\"type\":\"user\",\"content\":\"hello?\",\"timestamp\":\"2026-08-11T09:50:00.000Z\",\"content_type\":\"text\"}]",
  "conversation_paragraph": "Bot (10:00:00 AM): we are open until 6 ; User (9:58:00 AM): are you open? ; User (9:50:00 AM): hello?",
  "phone_number": "5491122223333",
  "recipient_name": "Ada",
  "user_id": "tenant_42",
  "last_message_of_user": "are you open?",
  "last_message_of_bot": "we are open until 6",
  "message_type": "text",
  "user_last_message_time": 1786442280,
  "bot_last_message_time": 1786442400,
  "attachment_url": "",
  "note": "vip",
  "note_automation": "auto-summary",
  "labels": "gold, spanish",
  "is_scheduled": false
}

The other shapes differ in a few fields:

  • Outgoing message. phone_number is a JSON number, not a string. It adds "incoming_message": false, send_by ("WhatsApp App", "AI", or "Notifyer" for a reply from your team) and was_message_by_human. It has no is_scheduled.
  • Your own server. Incoming messages carry "incoming_message": true.
  • Combined messages. is_scheduled is true, scheduled_messages lists the batch, phone_number is a number and labels is an array.
  • All numbers. An endpoint for all numbers also gets business_phone_number_id and business_phone_number, so you know which of your numbers the message used.
  • Ads and buttons. A message from a Click-to-WhatsApp ad adds referral, and a button tap adds button_reply. See Click-to-WhatsApp fields and button replies.
  • attachment_url is empty for now. Whatsable does not send a public link to a media file.

The full field list is in message webhooks.

Verify the signature

Turn on Sign requests when you add the webhook. Those requests carry two headers. A webhook added with Sign requests left off does not send them.

  • X-Notifyer-Timestamp: the time of the request, in Unix seconds.
  • X-Notifyer-Signature-256: sha256= followed by the HMAC-SHA256, in hex, of the timestamp, a dot, and the raw request body, keyed with your signing secret.

To check a request, compute the same value from the raw body and compare. Refuse a request whose timestamp is too old, so a captured request cannot be replayed.

import crypto from 'node:crypto';

// rawBody: the request body exactly as received, before any JSON parsing.
function isFromWhatsable(rawBody, headers, secret) {
  const timestamp = headers['x-notifyer-timestamp'];
  const signature = headers['x-notifyer-signature-256'];
  if (!timestamp || !signature) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');
  const a = Buffer.from(signature);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Answer, retries and failures

  • Answer with any 2xx status, quickly. Whatsable reads only the status.
  • If your endpoint does not answer, or answers with another error, Whatsable tries again, waiting longer each time, up to five attempts in all. Because of retries, the same message can reach you twice. Make your handler safe to run twice.
  • A 404 or 410 means the address is gone, so Whatsable does not retry it. When an endpoint keeps answering that way, Whatsable turns it off. The list shows Disabled: endpoint not found. Fix the address, then select Enable.
  • When a webhook keeps failing, or is turned off, owners and Admins get a notice in the bell. See notifications.

How webhooks work with other features

  • Make, Zapier and n8n. Start your scenario, Zap or workflow with a webhook trigger, then paste its address here. For each tool's own Whatsable app, see Make, Zapier and n8n.
  • The AI agent. Turn on Pause when your team replies so your automation and your team don't both answer. Replies from the AI agent never pause it.
  • Labels and notes. Each payload carries the contact's labels and notes, so your automation can branch on them.
  • API v1. To send messages back, use an API key with the API v1.

FAQ

Can I change an endpoint from "Your own server" to "Make, Zapier or n8n"?

No. The format is fixed once you add the webhook. Add a new endpoint with the other format, then delete the old one.

Why does my endpoint receive nothing for a chat?

Check three things: the chat's Automations setting in the inbox, whether a teammate replied within the pause, and whether the endpoint is set to that chat's number.

Can I see the delivery history?

Not yet. The screen does not show past deliveries.