Integrations

Connecting WhatsApp Web to Your CRM with Webhooks

Webhooks turn WhatsApp conversations into events your CRM can act on, and let your CRM trigger WhatsApp messages back. Here is how inbound and outbound webhooks differ and how to wire both up safely.

Key takeaways

  • Outbound webhooks push WhatsApp events to your systems; inbound webhooks let your systems trigger WhatsApp sends.
  • Design the payload around a stable contact identifier — the phone number in E.164 format is the only reliable join key.
  • Always verify the request signature on inbound webhooks; a webhook URL is a credential, not a secret.
  • Make consumers idempotent — retries and duplicate deliveries are normal, not exceptional.
  • Log every delivery with its response code, because silent webhook failures are the hardest integration bug to notice.
What it contains
  1. Key takeaways
  2. Outbound Webhooks: WhatsApp → Your Systems
  3. Payload Design
  4. Delivery and Retries
  5. Inbound Webhooks: Your Systems → WhatsApp
  6. Securing the Endpoint
  7. Wiring It Into a CRM
  8. Where WAPlus Fits
  9. Testing Before You Trust It
  10. Frequently asked questions

A CRM that does not know about your WhatsApp conversations is a CRM with a hole in it. Webhooks close that hole in both directions: outbound webhooks tell your systems what happened in WhatsApp, and inbound webhooks let your systems make something happen in WhatsApp.

This article covers both directions, the payload design that makes them useful, and the failure modes that make integrations quietly stop working.

Outbound Webhooks: WhatsApp → Your Systems

An outbound webhook fires an HTTP POST to a URL you control whenever a configured event occurs.

Events worth wiring up:

  • A message arrives from a new, unknown number — create a lead
  • An auto-reply rule matches a specific keyword — tag the contact
  • A broadcast campaign finishes — write the results back
  • A contact replies to a campaign — mark them engaged
  • A message matches a pattern such as an order number — look it up and route it

The receiving end is whatever you already run: a CRM’s incoming-webhook endpoint, a Zapier catch hook, a Make scenario, an n8n workflow, or a small function of your own.

Payload Design

A good payload is boring, flat, and stable. Something like:

{
  "event": "message.received",
  "event_id": "evt_01J9X2K4M7",
  "timestamp": "2026-08-02T14:31:07Z",
  "contact": {
    "phone": "+8801712345678",
    "name": "Maria Santos",
    "is_saved_contact": true
  },
  "message": {
    "body": "Do you still have the blue one in stock?",
    "chat_type": "individual"
  },
  "matched_rule": "stock-enquiry"
}

Four design rules make the difference between a payload that ages well and one that breaks every consumer when you change it:

Use E.164 phone numbers. +8801712345678, always with the +, never with spaces or dashes. It is the only field that reliably joins a WhatsApp contact to a CRM record. Display names change and are not unique.

Include an event ID. Retries and duplicate deliveries happen. A stable ID lets consumers deduplicate instead of creating the same lead three times.

Use ISO-8601 UTC timestamps. Local time in a webhook is a bug waiting for a daylight-saving transition.

Keep it flat and additive. Add fields, never rename or remove them. Consumers written against your payload will not be updated when you change it.

Delivery and Retries

Networks fail. Your consumer will be down at some point. Plan for it:

  • Treat any 2xx as success and everything else as failure.
  • Retry with exponential backoff — a few seconds, then tens of seconds, then minutes — and cap the attempts.
  • Never retry forever; a permanently misconfigured URL should surface as an error, not as an infinite queue.
  • Log every attempt with its status code and response body.

That log is the thing that saves you. The most common webhook bug is not an error — it is silence, and you cannot debug silence without a delivery log.

Inbound Webhooks: Your Systems → WhatsApp

An inbound webhook goes the other way. You get a URL; posting to it triggers a WhatsApp message from your account.

Uses that pay for themselves immediately:

  • Order shipped in your e-commerce platform → WhatsApp notification with tracking
  • Appointment booked in your scheduler → confirmation, then a reminder the day before
  • Payment received → receipt
  • Support ticket resolved → follow-up asking if it worked
  • Form submitted on your site → instant acknowledgement

A minimal trigger request:

{
  "to": "+8801712345678",
  "template": "order-shipped",
  "variables": {
    "name": "Maria",
    "order_id": "4821",
    "tracking_url": "https://example.com/t/4821"
  }
}

Referencing a template by name with variables, rather than passing raw message text, is the better pattern. The wording lives in one place, marketing can change it without touching the integration, and the integration cannot accidentally send a malformed message.

Securing the Endpoint

An inbound webhook URL can cause messages to be sent from your number. Treat it accordingly.

Verify a signature. The caller computes an HMAC-SHA256 of the raw request body using a shared secret and sends it in a header. You recompute and compare using a constant-time comparison. Reject anything that does not match.

Reject stale timestamps. Include a timestamp in the signed payload and reject requests older than a few minutes, so a captured request cannot be replayed later.

Require HTTPS. No exceptions.

Rate limit. A bug in a calling system should not become a thousand WhatsApp messages.

Rotate the secret if it is ever exposed, and keep it out of source control.

A long random URL is helpful but it is not authentication. URLs leak — through logs, browser history, screenshots, and support tickets.

Wiring It Into a CRM

The general pattern, regardless of which CRM:

  1. Create the contact-matching rule first. Decide exactly how an incoming phone number maps to a CRM record, including what happens when there is no match and when there are two.
  2. Normalize numbers on both sides. Store E.164 everywhere. Most CRM data has numbers in three formats; fix that before wiring anything up.
  3. Start with one event. message.received from an unknown number is the highest-value first integration.
  4. Make the consumer idempotent. Key on the event ID. Running the same webhook twice must produce the same result as running it once.
  5. Add the reverse direction second, once the inbound data is flowing and correct.
  6. Alert on failure. A webhook that has not delivered successfully in 24 hours should page someone.

Where WAPlus Fits

WAPlus supports both directions. Outbound webhooks fire on configured events — matched auto-reply rules and campaign activity — and relay the payload to your endpoint. Inbound webhooks give you a generated URL that external systems can POST to in order to trigger sends through your session.

One architectural detail worth knowing: outbound payloads are relayed through WAPlus’s servers rather than called directly from the browser, and inbound events are polled by the extension. That relay is what makes delivery work from a browser context, and it means the relayed payload contains exactly the fields you configure — so do not put anything in a webhook payload that you would not want leaving your machine. Configure the minimum set of fields your integration actually needs. This is documented in the privacy policy.

Testing Before You Trust It

  • Point the outbound webhook at a request-inspection service first and read the actual payload — not the documented one.
  • Send a deliberately malformed inbound request and confirm it is rejected, not silently accepted.
  • Test with a name containing emoji and non-Latin characters. Encoding bugs appear immediately.
  • Disconnect the consumer and confirm the retry and alerting behaviour is what you expect.
  • Trigger the same event twice and confirm exactly one CRM record results.

Integrations fail quietly. The half hour spent on these five tests is what makes the difference between an integration you trust and one you discover was broken three weeks ago.

Related reading: WhatsApp Auto-Reply Rules explains the rule matching that most outbound webhook events fire from.

Frequently asked questions

What is a webhook in the context of WhatsApp?

A webhook is an HTTP request fired automatically when something happens. An outbound WhatsApp webhook posts event data to your URL when a message arrives or a rule matches. An inbound webhook exposes a URL that your systems can post to in order to trigger a WhatsApp message.

Can I connect WhatsApp to Zapier or Make without the official API?

Yes. Both platforms accept generic incoming webhooks, so any tool that can POST JSON on an event can drive a Zap or Scenario. The same works in reverse: Zapier and Make can POST to an inbound webhook URL to trigger a send.

How do I secure a webhook endpoint?

Verify a shared-secret HMAC signature on every request, reject requests with old or reused timestamps, require HTTPS, and treat the URL itself as guessable. A long random URL path is obscurity, not security.

What should a WhatsApp webhook payload contain?

At minimum: an event type, an event ID for deduplication, an ISO-8601 timestamp, the contact phone number in E.164 format, and the message body. Add chat type and matched rule name if your automation branches on them.