WhatsApp Business API
Send WhatsApp messages and manage message templates on your Superfone business number, programmatically. This is the API behind Superfone's WhatsApp service ("Dragonfly").
Base URL
https://prod-api.superfone.co.in/superfone/api/dragonfly/whatsapp
Authentication
Every request requires the x-api-key header.
To find your API key: open the Superfone web dashboard → Teams (left nav) →
Settings. The API key shown there is your x-api-key
(format: 59665bbf-858e-4232-a868-xxxxxxxxxxxx).
curl -H "x-api-key: your_api_key_here" \
"https://prod-api.superfone.co.in/superfone/api/dragonfly/whatsapp/message_templates"
Authentication is by x-api-key alone. Do not send session cookies — they are never
required for these endpoints. Treat your API key like a password: keep it in an
environment variable, never commit or share it, and rotate it if it is ever exposed.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /messages | Send a template or free-form message |
GET | /messages/:id | Get a sent message's delivery status by WhatsApp message ID |
GET | /message_templates | List all message templates on your account |
GET | /message_templates/:id | Get one template by its Meta template ID |
The 24-hour customer-service window
WhatsApp only allows free-form messages (text, media, etc.) inside the 24-hour window
that opens when the customer last messaged you. Outside that window you must use an
approved template. A free-form send outside the window is accepted by the API but fails
asynchronously with Meta error 131047 ("Re-engagement message") — visible via
Get Message by ID.
Good to know
- Insufficient wallet balance still returns HTTP
200. When your wallet cannot cover the send, the message is not sent, but the response is200 OKwith{ "reason": "INSUFFICIENT_BALANCE" }instead of the usual Meta payload. Do not treat HTTP 200 alone as proof of a send — check fordata.messages[0].id. See Send Message. languagemust exactly match the template's language code. Sendingenfor a template created asen_US(or vice versa) fails with400 Template not found. Copy thelanguagevalue returned by List Templates.- Template lists are cached.
GET /message_templatesserves a cached copy; pass?refresh=trueafter creating or editing a template. - Dynamic-URL buttons require a
buttoncomponent. A dynamic-URL template sent with emptycomponentsfails — the URL variable must be supplied via abuttoncomponent withsub_type: "url". See the working example. - Recipient phone format matters. Send the number in international format — either
+<countrycode><number>or bare digits with the country code (e.g.917545991999, Meta'swa_idformat, 11–15 digits). Bare 10-digit national numbers are validated against your organisation's country and rejected if they don't match.