Skip to main content
After this guide, end users who message your WhatsApp Business number talk to your agent, and the agent can message them first with Channels.send or an approved WhatsApp message template. You need a Meta Business account with a WhatsApp Business Account (WABA) and a phone number in it. The dashboard creates or connects those through Meta’s Embedded Signup; the CLI takes credentials you already hold. Verified against lua-cli 3.33.0. Before you begin
  • A Meta Business account and a WhatsApp Business Account with a phone number, following Meta’s Cloud API getting-started guide. Meta’s free test number is enough for development.
  • For the CLI path: the phone number ID, the WABA ID, and an access token from WhatsApp → API Setup in your Meta app. For production, generate a permanent token through a system user.
  • An agent with a promoted production version; see Release an agent.
1

Link the number

Pick one path. Both register the number with the Cloud API and subscribe the WhatsApp Business Account to the app that issued the token.
In the admin dashboard open Agents, select the agent, select + in the Channels section of its Overview tab, and choose WhatsApp in Connect a channel. Tick I accept the Terms of Service and Privacy Policy and select Connect. Meta’s Embedded Signup opens: sign in with Facebook, then select or create the Business account, the WhatsApp Business Account, and the phone number. When it closes, the channel is connected and the webhook is already configured.
2

Provider console: point your app's webhook at Lua

Skip this step on the admin dashboard path. On the CLI path, Meta delivers messages to the app that issued the token, so that app’s webhook must point at Lua. In the Meta app dashboard open WhatsApp → Configuration, set the callback URL to https://wa.heylua.ai/whatsapp/webhook, enter the verify token, and subscribe the messages webhook field.The verify token is Lua’s, not one you choose, and the CLI doesn’t print it.
If the CLI prints the webhook URL with /webhook twice, use the single /webhook form.
3

Verify

From a phone, send hello to the business number. The agent replies in the same chat. lua channels list then shows a WHATSAPP entry with the number, and the list’s detail view shows Meta’s status and quality rating for it.

Channel behavior

user.send() also reaches an end user whose most recent conversation with the agent is on WhatsApp; Meta applies the same 24-hour rule to it. To receive receipts in code, subscribe a webhook to the events you want.

Users who hide their phone number

A WhatsApp user who sets a WhatsApp username can hide their phone number. For that user Lua only receives a WhatsApp-issued user id, and _luaProfile.mobileNumbers is empty unless they share the number. Channels.whatsapp.requestPhoneNumber sends a message with a share-phone-number button; if the user taps it and confirms, Lua saves the number on their profile. If another Lua user already has that number, for example someone who wrote from the same phone before setting a username, the WhatsApp account moves to that user, and its messages run as them from then on. The same happens when WhatsApp later sends the number by itself. Every message from such a user still carries their WhatsApp user id. Agent code reads it as Lua.request.sender and in user._luaProfile.identities, can find the person again with User.get({ identity }), and can message them with Channels.send({ channel: 'whatsapp', to: { identity } }), so you can key your own records on it when they never share a number. This preprocessor lets registered numbers through, asks a user with no number to share it, and blocks everyone else. The call needs an open 24-hour window, which the user’s own message provides.
src/preprocessors/PhoneGate.ts
A block with no response is silent, so the user only sees the button message. Catch a failed request: a preprocessor that throws lets the message through on chat channels. The tap itself arrives as the user’s next message, with the number already in mobileNumbers, so it passes the gate if the number is registered. Every message from a user with no number sends a new request; to ask less often, store when you asked in user data.

Disconnect a number

In the admin dashboard, open the agent, select Disconnect on the WhatsApp channel, and type the agent’s name to confirm. The agent stops answering the number straight away. A plain disconnect keeps the number registered with Meta’s Cloud API. Use it to move the number to another agent or to another WhatsApp provider. While the number is registered with the Cloud API, it can’t be used in the WhatsApp or WhatsApp Business app. To use the number on a phone again, tick Release this number so it can be used in the WhatsApp app again and select Release and disconnect. Lua asks Meta to deregister the number from the Cloud API, then disconnects it. Register the number in the WhatsApp or WhatsApp Business app with the code Meta sends by SMS or call. If the app or WhatsApp Manager asks for a two-step verification PIN, use the one the dashboard shows after the release.
  • If Meta refuses the release, the channel stays connected and the dashboard shows Meta’s reason.
  • Meta allows 10 release attempts per number in 72 hours.
  • A number that also runs in the WhatsApp Business app can’t be released from Lua. Disconnect it in the app under Settings → Account → Business Platform.
  • Deleting your Lua organization releases its WhatsApp numbers.

Limits

  • Free-form sends: 24 hours after the end user’s last inbound message. Message templates have no window but need Meta’s approval.
  • Closed-window queueing to a +1 (US or Canada) number: Meta blocks the marketing-category opt-in prompt, so the send still returns queued: true with a warning and the prompt may never arrive. Send an approved WhatsApp message template to those recipients instead.
  • Reactions: the target message must be at most 30 days old.
  • A number connects to one agent at a time. Linking it again, to this or another agent, is refused with Channel already exists.
  • Meta’s messaging tiers and quality rating govern volume. The rating appears in the channel’s detail view in lua channels and in the admin dashboard.

Troubleshooting

The number is already linked to an agent. Run lua channels list to see whether it is this one; to move it to another agent, disconnect it in the admin dashboard first.
The phone number ID isn’t in the WhatsApp Business Account you gave. Copy both IDs from WhatsApp → API Setup of the same Meta app.
Meta rejected the stored token (a revoked system user, a password change, a disabled WABA). Reconnect from the admin dashboard; on the CLI path, generate a new token and link again.
The number is still registered with the Cloud API. If it’s connected to an agent, disconnect it with the release box ticked. If it was disconnected without a release, connect it to an agent again from the admin dashboard, then disconnect it with the release box ticked. If nobody can reach the WhatsApp Business Account that holds the number, ask Meta support to release it.
The app that issued the token isn’t delivering to Lua. Check the callback URL, the verify token, and that the messages field is subscribed and the WhatsApp Business Account is subscribed to that app.

Next steps

Send proactive messages

Reminders and notices, the 24-hour window, and WhatsApp message templates.

Channels reference

send, whatsapp.sendTemplate, whatsapp.sendReaction, and delivery status.

Response formatting

What each component becomes on WhatsApp.

About channels

The inbound and outbound channel vocabularies.