WhatsApp Business
Preview
Send WhatsApp messages and approved templates from your business number (Cloud API).
- Status: Preview
- Shelf: Messaging
- How you connect: API key
- Regions: global and Kazakhstan
- The service’s own API reference: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages
Apps send WhatsApp messages from your business number through Meta's WhatsApp Cloud API:
plain text inside the 24 hours after a customer writes, and approved templates to start a
conversation. It is reached through the HTTP API connector with a preset: the gate calls only
graph.facebook.com (API v23.0) with POST. The token is sealed to the gate and apps never
see it.
Connect it#
- In Meta Business Settings: add your WhatsApp Business account, then Users → System users → create one and assign it the account.
- Generate a token for the system user with only the
whatsapp_business_messagingpermission, set to never expire. - In WhatsApp Manager → API setup note the phone number ID. It is not secret; apps are given it as a setting, and it goes in the request path.
- Create and submit a message template (WhatsApp Manager → Message templates). A template must be approved before an app can send it, and only a template can start a conversation.
- Qaldy → Connectors → WhatsApp Business → Connect WhatsApp Business → paste the token → Seal and connect.
Test connection only checks that the sealed key opens: the preset allows POST only, and
sending a message to test would message a customer.
What the gate allows#
| Host | graph.facebook.com, base path /v23.0 (pinned, every resolved address public) |
| Method | POST only |
| Paths | everything under /v23.0, which in practice is /<phone number id>/messages |
| Key | Authorization: Bearer <token>, added by the gate |
The fence is the host and the method; the token's own permission (whatsapp_business_messaging
only) is what stops an app doing more, which is why the steps above ask for just that one.
Use it from an app#
{ "id": "http", "actions": ["request"], "scope": "conn_k3v9…" }import { whatsapp } from '@qaldy/sdk'
const wa = whatsapp(ctx.connectors.http('conn_k3v9…'))
// Inside 24 hours after the customer wrote:
await wa.sendText({ phoneNumberId, to: '77010000000', body: 'Your order is ready.' })
// Any time, with an approved template ({{1}}, {{2}} filled in order):
await wa.sendTemplate({
phoneNumberId,
to: '77010000000',
template: 'order_ready',
language: 'en',
bodyParameters: ['#4411'],
})to is the customer's number with its country code, digits only. The helper checks the input
before anything is sent and returns Meta's messageId.
When it breaks#
| You see | Why | Do |
|---|---|---|
401 / OAuthException 190 | The token was revoked or mistyped | Replace the token |
131047 "Re-engagement message" | Free text outside the 24-hour window | Send a template |
132001 "Template does not exist" | Wrong name or language, or not approved yet | Check the template in WhatsApp Manager |
131030 "Recipient not in allowed list" | The number is still in Meta's test mode | Finish business verification or add the recipient |
130429 | Meta's messaging rate limit | Send fewer messages a second |
Gaps#
- Never run against a live number (hence Preview); template approval and sender quality are Meta's and happen outside Qaldy.
- Sending only. Receiving messages needs Meta's webhook (a
POSTto Qaldy, signed withX-Hub-Signature-256) and a verification handshake that is not built; the catalog lists "A customer writes" as planned. - No media, buttons or list messages yet.