DA Connect API
Send WhatsApp messages from your own software. Available on the Starter and Growth plans. Create a key in Developers → API keys.
Basics
- Base URL:
https://chpxvjqfwoxtndilmpox.supabase.co/functions/v1/api - Auth header:
Authorization: Bearer dac_live_… - JSON in, JSON out. Errors look like
{"error":{"message":"…","code":"…"}}with an HTTP 4xx/5xx status. - Phone numbers: digits with country code, e.g.
919876543210. A 10-digit number is treated as Indian. - Limit: 600 requests per minute per key. Meta's own throughput and daily limits also apply.
Send a template — POST /v1/messages
Templates can be sent any time. Message charges are billed by Meta to your WhatsApp account.
curl -X POST https://chpxvjqfwoxtndilmpox.supabase.co/functions/v1/api/v1/messages \
-H "Authorization: Bearer $DAC_KEY" -H "Content-Type: application/json" \
-d '{
"to": "919876543210",
"type": "template",
"template": {
"name": "order_update",
"language": "en",
"params": {
"header": "Order #1043",
"body": ["Ravi", "#1043", "today 6 pm"],
"buttons": { "0": "1043" }
}
},
"contact": { "name": "Ravi Kumar" }
}'
params.body fills {{1}}, {{2}}… in order. For a media header use "header": {"link":"https://…/invoice.pdf","filename":"Invoice.pdf"}. buttons maps a button's position to the URL ending or offer code. If you have several numbers, add "from": "<phone number ID or number>".
Response:
{ "id": "6f1c…", "wamid": "wamid.HBgM…", "status": "sent", "to": "919876543210" }
Send a free-form message
Only inside the 24-hour window after the customer's last message (otherwise you get 409 WINDOW_CLOSED).
{ "to": "919876543210", "type": "text", "text": "Your order is out for delivery 🚚" }
{ "to": "919876543210", "type": "document", "link": "https://…/bill.pdf", "filename": "Bill.pdf", "caption": "Your bill" }
Types: text, image, video, audio, document (media by public https link).
Message status — GET /v1/messages/{id}
{ "id": "6f1c…", "status": "read", "error": null, "pricing_category": "utility",
"sent_at": "…", "delivered_at": "…", "read_at": "…" }
Status goes sent → delivered → read, or failed with a reason in error.
Create or update a contact — POST /v1/contacts
{ "phone": "919876543210", "name": "Ravi Kumar", "email": "ravi@example.com",
"attributes": { "city": "Port Blair", "customer_id": "C-221" }, "tags": ["Website lead"] }
Tags are created if they don't exist. Send "opted_out": true to unsubscribe someone.
List templates — GET /v1/templates
Approved templates with their components, so you know which parameters to send.
List numbers — GET /v1/numbers
Your connected WhatsApp numbers with quality rating and daily limit.
Webhooks (Growth plan)
Add a URL in Developers → Webhooks. We send a POST with JSON for each event:
{ "event": "message.received", "workspace_id": "…", "created_at": "…",
"data": { "id": "…", "wamid": "…", "from": "919876543210", "name": "Ravi", "type": "text",
"text": "Is my order ready?", "message": { …raw WhatsApp message… } } }
Events: message.received, message.status (data: id, wamid, status, campaign_id, recipient, errors, pricing), contact.opted_out.
Check the signature: X-DA-Signature: sha256=<hex> is HMAC-SHA256 of the raw body using your webhook secret. Answer with any 2xx within 10 seconds; otherwise we retry after 1, 5, 30, 120 and 720 minutes.
// Node.js
const crypto = require('crypto');
const ok = req.headers['x-da-signature'] ===
'sha256=' + crypto.createHmac('sha256', SECRET).update(rawBody).digest('hex');
Common errors
401missing, invalid or revoked key403plan doesn't include the API404template not found or not approved on that number409 WINDOW_CLOSEDfree-form message outside 24 h;409contact opted out (marketing)422Meta rejected the message (the message explains why)429rate limit