Connecting channels
Voxa connects to WhatsApp via Meta’s WhatsApp Business Cloud API. This guide walks through everything: Meta prerequisites, generating a long-lived access token, pasting credentials into Voxa, verifying the webhook, and testing.
Prerequisites
Section titled “Prerequisites”You need all of the following in Meta Business Manager before starting:
- A Business Manager account (verified business ID).
- A WhatsApp Business Account (WABA) inside the Business Manager.
- A phone number registered against the WABA. It must be a number you own and control — Meta will send an SMS or voice verification code.
- A Meta App of type Business with the WhatsApp product added.
- A System User with Admin access to the WABA.
If any of those are missing, complete them in business.facebook.com before continuing. Meta’s own docs cover each step in detail; we don’t try to duplicate them here.
Credentials you’ll collect
Section titled “Credentials you’ll collect”Voxa stores five values, all encrypted at rest:
| Field | Where to find it |
|---|---|
app_id | Meta app dashboard → Settings → Basic. |
app_secret | Meta app dashboard → Settings → Basic → Show secret. |
phone_number_id | Meta app → WhatsApp → API Setup → Phone numbers table. |
waba_id | Meta app → WhatsApp → API Setup → WhatsApp Business Account ID. |
access_token | System User access token (see below). |
Generating a long-lived access token
Section titled “Generating a long-lived access token”The temporary token on the API Setup page expires in 24 hours — don’t use it in production. Instead:
-
Business Manager → Business Settings → Users → System Users. Create a System User (or reuse an existing one).
-
Grant it asset access to the WhatsApp Business Account as Admin. Without this, the token won’t have permission to send messages.
-
Click “Generate new token” on the system user. Choose your Meta App, then select the permissions
whatsapp_business_managementandwhatsapp_business_messaging. Leave Never expire checked. -
Copy the token immediately. Meta will only show it once.
Registering the webhook
Section titled “Registering the webhook”Voxa needs Meta to POST inbound messages and status updates to a webhook URL that Voxa exposes.
-
Meta app dashboard → WhatsApp → Configuration → Webhook.
-
Callback URL — paste the URL shown on Voxa’s
Settings → Meta credentialsscreen. It has this shape:https://voxa.software/webhooks/whatsapp/<opaque-token>The opaque token is specific to your tenant and non-enumerable.
-
Verify Token — paste the verify token from Voxa’s settings page. Meta uses this to prove to Voxa that the callback belongs to your Meta app; Voxa stores it plaintext in
meta_credentials. -
Verify and Save. Meta issues a GET with the challenge; Voxa’s webhook handshakes it in under 50 ms.
-
Subscribe to webhook fields. Tick at minimum:
messages(inbound text, media, button clicks, status callbacks)- Optional:
message_template_status_updateif you plan to manage templates through Meta.
Pasting credentials into Voxa
Section titled “Pasting credentials into Voxa”- In Voxa → Settings → Meta credentials.
- Paste each of the five values.
- Click Save. Voxa encrypts the five secret fields (app_secret,
access_token) with AES-256-GCM keyed off
CREDENTIAL_ENCRYPTION_KEYbefore inserting the row. - Click Test connection. Voxa calls Meta’s
/v21.0/<phone_number_id>endpoint and reports the WABA display name and phone number. A green check appears if the round-trip succeeds;last_test_atandlast_test_statusare recorded for audit.
Signature verification
Section titled “Signature verification”Every inbound webhook POST carries an X-Hub-Signature-256 header.
Voxa computes an HMAC-SHA256 of the raw body keyed off your stored
app_secret and compares it with the header using timingSafeEqual.
If a mismatch occurs:
- The request is rejected with 403.
- A
signature_valid: falseentry lands inwebhook_events. - An owner-level in-app notification fires alerting you to a probable misconfiguration (wrong app_secret or wrong Meta app).
This is by design: a working webhook with an invalid signature means something is trying to impersonate Meta against your tenant, and you should notice.
Smoke test
Section titled “Smoke test”-
Open a Voxa quickstart flow on a real WhatsApp account that is not the one attached to your tenant.
-
Reply to the welcome message with any text.
-
Open Conversations in the Voxa dashboard. You should see the inbound message within a few seconds.
-
Check Audit log — you’ll see a
webhook.inbound.receivedevent. -
Check Settings → Meta credentials → Recent webhook events. Every inbound POST in the last 24 hours shows up with the signature status.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause |
|---|---|
| Webhook verify fails | Verify token mismatch between Voxa and Meta. |
| Inbound messages never arrive | Webhook fields not subscribed in Meta. |
signature_valid: false in recent events | Wrong app_secret pasted, or the Meta app was swapped. |
| Test connection fails with 401 | Access token revoked or permissions missing. Regenerate. |
| Test connection fails with 190 | Token expired — you used a temporary 24-hour token. Generate a system-user token. |
- Messaging integration — outbound sending, templates, and the 24-hour window.
- Production checklist.