Hi everyone,
I'm integrating Meta WhatsApp Cloud API → Salesforce Apex REST using a Salesforce Site.
The Apex REST endpoint works correctly when tested through Postman, and the same Meta webhook works successfully when pointed to a Render
endpoint.
However, when Meta sends the real WhatsApp webhook to the Salesforce Site endpoint, the Apex @HttpPost method does not appear to execute. The endpoint is publicly accessible and the Meta messages webhook is subscribed.
Are there any Salesforce-specific limitations, security settings, Guest User considerations, or other requirements for receiving external webhooks such as Meta WhatsApp directly through a Salesforce Site/Apex REST endpoint?
Any guidance or known considerations would be appreciated.
#Salesforce #Integration
Hi Rangadas - the pattern you describe (works from Postman and Render, but Meta's real webhook to the Site never reaches @HttpPost) almost always comes down to one thing: Salesforce is returning a redirect (a 302), and Meta - unlike Postman or a Render test - does not follow redirects, so the POST body is dropped and your Apex never runs.
Why the Site redirects, and what to check:
1. Guest user Apex class access (the most common cause). For a public Site, the Site's guest user profile must have the Apex class explicitly enabled (Site > Public Access Settings > Enabled Apex Class Access > add your class). If it's missing, Salesforce redirects the unauthenticated request toward login (a 302), which Meta silently drops - looking exactly like 'the method didn't execute'. Postman/Render either followed that redirect or you were authenticated, which is why it seemed to work there.
2. Prove it's a redirect. Hit the exact Site endpoint with curl -i (or Postman with 'follow redirects' turned off): curl -i -X POST
https://<yoursite>/services/apexrest/<yourmapping>. If you see a 302 with a Location back to a login page, that's your smoking gun.
3. Exact URL + trailing slash. Make sure Meta calls the full Site path
https://<site>/services/apexrest/<urlMapping>with no trailing-slash mismatch - Site URL rewriting can 301/302 on canonical differences.
4. Re-verify the GET handshake against the Site itself. Meta's initial verification is a GET with hub.mode / hub.challenge / hub.verify_token that must echo hub.challenge back. If your class only has @HttpPost, or you only verified while pointed at Render, add an @HttpGet that returns the challenge and re-subscribe against the Site URL.
5. Respond fast, process async. Meta expects a quick 200; do the heavy work in a Queueable or @future so you don't hit the timeout and trigger retries.
My money's on #1 - grant the guest user the class and re-test with the redirect-revealing curl. Also confirm the Site is Active and 'Require Secure Connections (HTTPS)' is on.
Hope that cracks it!