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:
- On the same Configuration page, look for Webhook Fields.
- Click Manage.
- 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.)