Meta setup
App, WhatsApp product, test number, system user token and webhook.
Sendo only talks to the official WhatsApp Cloud API. You need a Meta Business account (business.facebook.com) and a developer account (developers.facebook.com). Meta renames menu items from time to time; the names below match the dashboard at the time of writing.
1. Create the Meta app#
- developers.facebook.com › My Apps › Create app.
- Choose the Business type (or the “Connect with customers through WhatsApp” use case) and link it to your Meta Business account.
2. Add the WhatsApp product#
In the app dashboard, Add product › WhatsApp › Set up. Meta creates a WhatsApp Business Account (WABA) for the business and opens WhatsApp › API Setup.
3. Test number and recipients#
- API Setup shows a free test number with its Phone number ID and the WhatsApp Business Account ID. Copy both.
- Under To, add up to five recipient numbers and verify them with the code Meta sends. The test number can only message verified recipients.
- For production, add your own number under WhatsApp › API Setup › Add phone number (it must not be registered in the WhatsApp app) and complete the display name review.
4. System user token#
The temporary token on API Setup expires after 24 hours. Use a system user token, which doesn’t expire:
- business.facebook.com › Settings › Users › System users › Add (role Admin).
- Assign assets: your app, and the WhatsApp account with full control.
- Generate token: pick the app, expiration Never, and the permissions
whatsapp_business_messagingandwhatsapp_business_management. - Put it in an env var such as
SENDO_TOKEN_MAIN(locally and in your deployment). Never commit it and never store it in the database.
5. App secret#
App dashboard › App settings › Basic › App secret › Show. This is SENDO_META_APP_SECRET: Sendo verifies the X-Hub-Signature-256 HMAC of every webhook POST with it and answers 401 on a mismatch. The App ID on the same page is the optional SENDO_META_APP_ID that doctor uses to confirm the app is subscribed to your WABA.
6. Tunnel for local development#
Meta must reach your webhook over public HTTPS. Start the dev server, then one of:
ngrok http 3000
# or
cloudflared tunnel --url http://localhost:3000Use the printed https://… host as the callback URL. Free ngrok and quick cloudflared tunnels change host on every start, so update the callback URL (and rerun doctor --url) when they do.
7. Webhook and the messages field#
- Pick a random verify token and set it as
SENDO_VERIFY_TOKEN, e.g.openssl rand -hex 24. Restart the dev server. - App dashboard › WhatsApp › Configuration › Webhook › Edit: Callback URL
https://<host>/api/sendo/webhook, Verify token =SENDO_VERIFY_TOKEN, Verify and save. Meta sends a GET challenge; Sendo answers it only when the token matches (403 otherwise). - Under Webhook fields, Subscribe to
messages. It carries inbound messages and the sent / delivered / read / failed statuses. For numbers shared with the WhatsApp Business app, also subscribe tosmb_message_echoes,historyandsmb_app_state_sync(Coexistence). - If
doctorreports the app isn’t subscribed to the WABA, subscribe it with the token:
curl -X POST "https://graph.facebook.com/v26.0/<WABA_ID>/subscribed_apps" \
-H "Authorization: Bearer $SENDO_TOKEN_MAIN"Where each value goes#
| Meta value | sendo |
|---|---|
| Phone number ID | sendo_accounts.phone_number_id (--phone-number-id); webhooks are routed by it |
| WhatsApp Business Account ID | sendo_accounts.waba_id (--waba-id, auto-detected when possible) |
| System user token | env var named by sendo_accounts.token_ref (--token-env) |
| App secret | SENDO_META_APP_SECRET |
| Verify token (yours) | SENDO_VERIFY_TOKEN |
| App ID (optional) | SENDO_META_APP_ID |
Back to Quickstart step 6.