WhatsApp Business API
Connect your business WhatsApp number to the CRM through Meta's official Cloud API — credentials, webhook verification, health checks and a test message.
WhatsApp Business API
Zodiac Tech CRM talks to WhatsApp through Meta's official WhatsApp Cloud API — there is no unofficial bridge, no phone farm, and no shadow banning risk. Each Business (tenant) connects its own WhatsApp Business Account (WABA) and phone number. Once connected, messages from leads land in the WhatsApp inbox and automations can send approved templates from your own number.

Who this is for
- Admin (workspace owner) or Super Admin who manages the business's Meta assets.
- Anyone re-connecting after a token was rotated.
Difficulty: Medium · Time: about 15 minutes · Prerequisites:
- A Meta Business account with the WhatsApp Business Platform (Cloud API) enabled.
- A phone number that is not currently used on the regular WhatsApp or WhatsApp Business app (a number can only live in one place).
- Access to the Meta Developer App used for your workspace (or help from your provider's Super Admin).
- Your CRM reachable over HTTPS in production — Meta calls the webhook over the public internet.
One Meta app can serve every client The platform usually runs on a single Meta Developer App configured by the operator at Meta Developer settings. Your workspace only supplies its own WABA ID, Phone Number ID and token — clients never need to create their own Meta app.
Step 1 — Collect the credentials in Meta
- Open
developers.facebook.com→ your Meta app → WhatsApp → API Setup. - Note these values:
- WhatsApp Business Account ID (WABA ID) — identifies your business account.
- Phone Number ID — identifies the sending number (not the phone number itself).
- Access token — for production, create a System User token so it does not expire in 24 hours.
- Decide a Verify token — any random string you invent. You will paste the same value in both Meta and the CRM.
Step 2 — Fill the connection form
In the CRM go to Settings → Connections → WhatsApp (/admin/settings/whatsapp).
| Field | Required | What it is |
|---|---|---|
| WABA ID | Yes | WhatsApp Business Account ID from Meta |
| Phone Number ID | Yes | The sending number's ID from Meta |
| Display phone number | No | Shown on the connection card for recognition |
| Access token | Yes | Meta System User / permanent token |
| App secret | Recommended | Used to verify inbound webhook signatures |
| Verify token | Yes | Shared secret you invent and paste in Meta's webhook setup |
Secrets are write-only The Access token, App secret and Verify token are stored encrypted and displayed masked (••••••••••••). Saving the form with a masked field untouched keeps the stored secret — nothing is wiped. You can never read the value back out of the CRM.
Step 3 — Save and let the health check run
Click Save. The CRM immediately performs a health check by calling Meta with your Phone Number ID and reading the number's display_phone_number, verified_name and quality_rating.
- Connected — credentials work; the card shows the verified name, display number and WABA.
- Error — the card shows Meta's error in
last_error; fix the credential and save again.
Step 4 — Register the webhook in Meta
Copy the Webhook URL shown on the page. Its shape is:
https://your-crm-domain/api/messaging/whatsapp/webhook/{tenantId}/{token}
- In Meta: WhatsApp → Configuration → Webhook → Edit, paste the URL.
- Paste the same Verify token you saved in Step 2.
- Verify and save — Meta fires a challenge request that the CRM answers automatically.
- Subscribe to the
messagesfield so inbound messages and delivery statuses reach the CRM.
Inbound deliveries are signature-checked against your App secret (X-Hub-Signature-256). If the secret is set but the signature does not match, the request is rejected — so an incorrect App secret means "everything looks connected but nothing arrives".
Step 5 — Sync your templates
Click Sync Templates. The CRM pulls the templates that exist on the WABA and stores Meta's status for each (approved, pending, rejected…). Sending in automations requires an approved template — see Message templates.
Step 6 — Send a Test Message
Click Test Message and send one to your own phone. A green result means the full path works: credentials → Meta → handset. If it fails, the error is surfaced verbatim on the page.
Managing the connection
The same card offers:
| Action | What it does |
|---|---|
| Reconnect | Re-opens the form so you can paste fresh credentials (token rotation) |
| Disconnect | Removes the connection after a confirmation modal — messages stop until reconnected |
| Sync Templates | Re-pulls template statuses from Meta |
Expected result
The connection card shows Connected with the verified business name, display phone number and WABA ID; a test message arrives on a real handset; an inbound reply from that handset appears in the WhatsApp inbox.
The 24-hour window (read this before blaming the CRM)
Meta only accepts free-form messages within 24 hours of the contact's last message to you. Outside that window you can only send an approved template. Attempts to send free text outside the window are rejected by Meta with error 131047 ("re-engagement message"). This is a Meta platform rule, not a CRM limitation — the inbox and automations respect it.
Common mistakes
- Using the phone number's display value where the Phone Number ID belongs. They are different — the ID is numeric and lives in API Setup.
- A short-lived (24h) token. Works today, breaks tomorrow. Use a System User token.
- Skipping the App secret. The webhook still verifies in Meta but the CRM rejects every inbound delivery with 403 (signature cannot be checked).
- The number is still installed on the WhatsApp app. Deregister it in the WhatsApp app first.
- Forgetting to subscribe to the
messagesfield — the webhook verifies but no events arrive.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Health check shows Error | Wrong Phone Number ID or expired token | Re-copy both from Meta API Setup, save again |
| Test message fails with auth/code errors | Token revoked or lacks whatsapp_business_messaging permission |
Issue a new System User token |
| Inbound messages never appear | Webhook not subscribed, or App secret mismatch → 403 | Check Meta's webhook delivery log; correct the App secret |
Send outside 24h window fails with 131047 |
Meta re-engagement rule | Use an approved template |
Template send fails with language mismatch (132001) |
Template language does not match the one registered on Meta | Sync templates and pick the exact language variant |
| Everything "worked" yesterday, all sends fail today | Short-lived token expired | Rotate to a System User token |
Technical details
- Tables:
whatsapp_connections(one row per tenant),whatsapp_templates,conversations,lead_messages(channelwhatsapp). - Services:
App\Services\WhatsApp\MetaCloudWhatsAppProvider,MetaGraphClient,WhatsAppConnectionService,WhatsAppMessageService,WhatsAppMediaService,WhatsAppTemplateService,WhatsAppVariableResolver. - Secrets are encrypted with the app key; legacy values under
tenants.settings.messagingare read via a decrypt-fallback so older installs keep working. - Outbound sending runs through queued
LeadMessagerows and theSendLeadMessagejob with a monotonic status ladder:queued → sending → sent → delivered → read(orfailed). - Super Admins get read-only diagnostics per business at Super Admin → Businesses → open business (status, verified name, WABA ID, last webhook, automation/template counts, messages today, failures).
Related guides
Was this page helpful?
Thanks — noted. ✦