Implement a WhatsApp Status Webhook

To see why messages are failing despite the 200 OK, you need to set up a listener (an endpoint) on your server that Meta can send “Status” updates to. Follow these steps to implement a WhatsApp Status Webhook:

1 – Create an Endpoint on Your Server

Your server must have a public URL (e.g., https://yourdomain.com) that can handle two types of requests:

  • GET Request: Used by Meta once to verify your server.
  • POST Request: Used by Meta every time a message status changes (sent, delivered, read, or failed).

Example (Node.js/Express): javascript

app.get('/webhook', (req, res) => {
  // Verification logic for Meta
  const mode = req.query['hub.mode'];
  const token = req.query['hub.verify_token'];
  const challenge = req.query['hub.challenge'];

  if (mode && token === 'YOUR_CUSTOM_TOKEN') {
    res.status(200).send(challenge);
  } else {
    res.status(403).end();
  }
});

app.post('/webhook', (req, res) => {
  // This is where you catch the "failed" status and error codes
  const data = req.body;
  console.log('Status Update:', JSON.stringify(data, null, 2));
  res.sendStatus(200); 
});

2 – Configure in Meta Developer Portal

3 – Go to the Meta App Dashboard.

In the left sidebar, click WhatsApp > Configuration.

  • Click Edit under the “Webhook” section.
  • Callback URL: Enter your public endpoint (e.g., https://yourdomain.com).
  • Verify Token: Enter the string you used in your code (e.g., YOUR_CUSTOM_TOKEN).
  • Click Verify and Save.
Subscribe to “Messages”

Once verified, you must tell Meta which events to send you:

  1. On the same Configuration page, look for Webhook Fields.
  2. Click Manage.
  3. Find messages in the list and click Subscribe. This subscription covers both incoming messages and outgoing status updates (sent, delivered, failed).

4 – Catch the Error Codes

When a message fails, Meta will send a POST request to your server. Look specifically for the statuses object in the JSON body. What a failure looks like in your logs: json

"statuses": [{
  "id": "wamid.HBgLMTY1M...",
  "status": "failed",
  "errors": [{
    "code": 131049,
    "title": "Message failed to send due to a marketing sub-category rate limit"
  }]
}]

Use code with caution. Do you have a server environment ready (like Node.js, Python, or PHP), or would you like a tool recommendation to test this locally first? (Testing locally usually requires a tool like ngrok to create a public URL for Meta to reach.)

Leave a Comment

Your email address will not be published. Required fields are marked *