Home/ Developers/Quickstart
Send your first WhatsApp message
One API key, five calls: create a key, create a contact, start a conversation, send a message, and receive the reply on a webhook. Every request below is real — copy, replace the placeholders, and run it.
To send a WhatsApp message through the BotPulsar API: create a scoped API key,
POST a contact, POST a conversation for that contact on your
WhatsApp channel, then POST a message into that conversation.
Every request needs an Authorization: ApiKey header and an
X-Tenant-ID header naming your workspace.
-
1. Create an API key
In the BotPulsar dashboard, go to Operations → Developer → Create API key (owner, admin, or manager role required). Name it, and grant only the scopes this integration needs — for this walkthrough:
contacts:read contacts:write conversations:read conversations:write messages:read messages:writeThe secret is shown once, in the form
smk_<prefix>_<secret>. Store it — BotPulsar keeps only a salted digest and cannot show it to you again. See Authentication for what each scope unlocks. -
2. Find your workspace and channel IDs
Every request needs your workspace's UUID in
X-Tenant-ID. It's theidof your workspace in theworkspacesarray returned byPOST /api/v1/auth/login/(orcurrent_workspace.idin that same response) — the same value the BotPulsar app itself sends on every request once you're signed in.You'll also need the
idof the WhatsApp channel to send from, from Dashboard → Channels. -
3. Create or find a contact
Idempotent by phone number: calling this twice with the same
phone_e164returns the existing contact (200) instead of a duplicate.Requestcurl -X POST https://api.botpulsar.com/api/v1/contacts/ \ -H "Authorization: ApiKey smk_your_prefix_your_secret" \ -H "X-Tenant-ID: YOUR_WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "phone_e164": "+919812345678", "display_name": "Ada Lovelace" }'
201 Created{ "id": "3f9c7e2a-1b4d-4e8a-9c3f-2a1b4d4e8a9c", "phone_e164": "+919812345678", "display_name": "Ada Lovelace", "tags": [], "...": "..." } -
4. Start a conversation
Also idempotent: the same
contact+channel_accountpair returns the existing open conversation rather than opening a second one.Requestcurl -X POST https://api.botpulsar.com/api/v1/conversations/ \ -H "Authorization: ApiKey smk_your_prefix_your_secret" \ -H "X-Tenant-ID: YOUR_WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "contact_id": "3f9c7e2a-1b4d-4e8a-9c3f-2a1b4d4e8a9c", "channel_account_id": "YOUR_CHANNEL_ID" }'
Keep the
idfrom the response — it's the conversation you send into next. -
5. Send the message
Requestcurl -X POST https://api.botpulsar.com/api/v1/conversations/YOUR_CONVERSATION_ID/messages/ \ -H "Authorization: ApiKey smk_your_prefix_your_secret" \ -H "X-Tenant-ID: YOUR_WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "content_type": "text", "text": "Hi Ada, your order has shipped!" }'
First message to a contact, or their last reply was over 24 hours ago? WhatsApp requires an approved template instead of free-form text — BotPulsar returns
409 whatsapp_template_requiredif you try free-form text outside that window. Send a template instead:Request — template messagecurl -X POST https://api.botpulsar.com/api/v1/conversations/YOUR_CONVERSATION_ID/messages/ \ -H "Authorization: ApiKey smk_your_prefix_your_secret" \ -H "X-Tenant-ID: YOUR_WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "content_type": "template", "template_id": "YOUR_APPROVED_TEMPLATE_ID", "template_parameters": {"1": "Ada", "2": "12045"} }'
Look up an approved template's
idand parameters first withGET /api/v1/whatsapp/templates/(needs thetemplates:readscope). -
6. Know when it's delivered, and catch the reply
Sending returns immediately with the message queued — delivery status and inbound replies arrive as webhook events, not as a response you poll for. Subscribe to
message.delivery_status.changedandmessage.receivedto get both. See Webhooks for subscribing and verifying the signature.