Skip to main content

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"
API key only — no cookies

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

MethodPathDescription
POST/messagesSend a template or free-form message
GET/messages/:idGet a sent message's delivery status by WhatsApp message ID
GET/message_templatesList all message templates on your account
GET/message_templates/:idGet 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

  1. Insufficient wallet balance still returns HTTP 200. When your wallet cannot cover the send, the message is not sent, but the response is 200 OK with { "reason": "INSUFFICIENT_BALANCE" } instead of the usual Meta payload. Do not treat HTTP 200 alone as proof of a send — check for data.messages[0].id. See Send Message.
  2. language must exactly match the template's language code. Sending en for a template created as en_US (or vice versa) fails with 400 Template not found. Copy the language value returned by List Templates.
  3. Template lists are cached. GET /message_templates serves a cached copy; pass ?refresh=true after creating or editing a template.
  4. Dynamic-URL buttons require a button component. A dynamic-URL template sent with empty components fails — the URL variable must be supplied via a button component with sub_type: "url". See the working example.
  5. Recipient phone format matters. Send the number in international format — either +<countrycode><number> or bare digits with the country code (e.g. 917545991999, Meta's wa_id format, 11–15 digits). Bare 10-digit national numbers are validated against your organisation's country and rejected if they don't match.