Connects a Twilio WhatsApp-enabled number to an agent flow. Every incoming message on that number, from any sender, is routed to the same flow.
1. Prerequisites
- Account SID (starts with
AC) - Auth Token
- Twilio WhatsApp number, in E.164 format (e.g.
+15558675310)
All three come from the Twilio Console: the Account SID and Auth Token are on the account dashboard, the WhatsApp number is whichever number you've enabled for WhatsApp in Twilio's Messaging settings. Once the integration exists in NeuraFlow (step 2 below), set the number's webhook in Twilio's messaging configuration to:
{BASE_URL}/api/v1/webhooks/whatsapp
Optionally also set a status callback URL, if you want delivery status
(queued / sent / delivered / read / failed / undelivered) logged:
{BASE_URL}/api/v1/webhooks/whatsapp/status
2. Configuration
Three console routes:
| Route | Purpose |
|---|---|
/channels/whatsapp | List the organization's WhatsApp integrations |
/channels/whatsapp/create | Create an integration |
/channels/whatsapp/{id}/edit | Reconfigure or disable it |
Create
/channels/whatsapp/create repeats the webhook URL from
section 1 in an on-screen alert, then a single card:
| Field | Required | Placeholder |
|---|---|---|
| Twilio WhatsApp Number | Yes | +15558675310 |
| Account SID | Yes | ACXXXXXXXX... |
| Auth Token | Yes | none |
| Friendly Name | No | e.g. Support WhatsApp |
| Agent Flow | Yes | Select an agent flow |
If the org has no agent flows, an inline warning replaces normal validation
and links to Create an Agent Flow (/agent-builder/create); the Save
Integration button is disabled until at least one flow exists.
Clicking Save Integration validates client-side in order ("Phone number
is required.", "Account SID is required.", "Auth Token is required.", "Agent
Flow is required."), then calls
POST /channels/whatsapp/integrations with all five fields plus the current
organization_id. On success it toasts "WhatsApp integration created
successfully!" and navigates to the edit page for the new integration. On
failure it toasts "Failed to create integration" with the server's detail
message as the description (this is where the 409 "A WhatsApp integration
with this Twilio phone number already exists." shows up).
Edit
/channels/whatsapp/{id}/edit has two cards, no tabs.
Status card: Integration Enabled toggle only, no separate save, the value is included the next time you click Save Changes below. Disabled integrations still match incoming webhooks but drop the message without processing it.
Configuration card, same fields as create:
| Field | Required | Notes |
|---|---|---|
| Twilio WhatsApp Number | Yes | Editable, no uniqueness re-check happens client-side |
| Account SID | Yes | |
| Auth Token | No | Always loads blank (the API never returns the stored token). Leave blank to keep the existing one, non-blank replaces it |
| Friendly Name | No | Shown in the entity switcher dropdown and page title in place of the phone number when set |
| Agent Flow | Yes |
Save Changes validates "Phone number is required.", "Account SID is
required.", "Agent Flow is required." (Auth Token is not required here,
unlike create), then calls PUT /channels/whatsapp/integrations/{id} with
all fields, omitting auth_token from the request entirely if it's still
blank so the stored value is untouched. On success it toasts "WhatsApp
integration saved successfully." and clears the Auth Token field again. On
failure it toasts "Failed to save integration." with the server's detail
as the description.
3. Other
Incoming messages are matched to an integration by the Twilio To number, so
one webhook URL serves every WhatsApp integration across every organization.
Empty or media-only messages (no Body text) are acknowledged and dropped.
Twilio request signature verification is implemented
(X-Twilio-Signature, validated with the integration's auth_token) but not
enforced: on a failed check the webhook logs a warning and processes the
message anyway. The code marks this with a TODO: Enforce signature validation in production.