Scope Wiser API: Sending WhatsApp Messages
The endpoints that send: plain text, interactive reply buttons, images, video, audio and documents, uploading media to reuse, triggering a bot flow, and checking whether a message was delivered.
Everything here assumes you have read Scope Wiser API: Overview and Authentication — the base URL, the apiToken parameter and the status response shape.
The rule that governs all of it
Within 24 hours of a customer's last message you may send free-form text, buttons and media. Outside that window WhatsApp delivers only an approved template. This is Meta's rule, not ours, and the API cannot work around it. The WhatsApp 24-Hour Rule and Templates explains it properly.
So: use the endpoints below for people who have messaged you recently, and a template send for everyone else.
Send a text message
GET or POST → /whatsapp/send
Parameter | Notes |
|---|---|
| Required |
| Required — your WhatsApp number's ID |
| Required — country code first, digits only |
| Required — URL-encode it for GET |
curl -X POST \
'https://connect.scopewiser.com/api/v1/whatsapp/send' \
-d 'apiToken=API-KEY' \
-d 'phone_number_id=PHONE-NUMBER-ID' \
-d 'message=Your order is on its way' \
-d 'phone_number=PHONE-NUMBER'A success returns the WhatsApp message id, which you need later to check delivery:
{"status":"1","wa_message_id":"wamid.HBgNODgw...","message":"Message sent successfully."}Send reply buttons
POST → /whatsapp/send/interactive-buttons
Buttons are session messages, so the 24-hour window applies. Send one to three buttons, each title up to 20 characters.
Parameter | Notes |
|---|---|
| Required — the body shown above the buttons |
| Required — a JSON array. Each item is a string, or an object with |
| Optional. Ignored if you send a media header |
| Optional |
| Optional header media |
|
|
| Only used when |
curl -X POST "https://connect.scopewiser.com/api/v1/whatsapp/send/interactive-buttons" \
-H "Accept: application/json" \
-d "apiToken=API-KEY" \
-d "phone_number_id=PHONE-NUMBER-ID" \
-d "phone_number=PHONE-NUMBER" \
-d "message=Would you like to continue?" \
-d 'buttons=[{"id":"buy_now","title":"Buy Now"},{"id":"details","title":"View Details"}]' \
-d "button_footer_text=Tap an option"Give each button a meaningful id. It is what identifies the tap in your webhook, and {"id":"buy_now"} is far easier to handle than matching on the visible title.
Send a file
GET or POST → /whatsapp/send/file
One endpoint covers image, video, audio and document. Supply either media_url or media_id.
Parameter | Notes |
|---|---|
| A public HTTPS URL. WhatsApp downloads it |
| From the upload endpoint below |
|
|
| Required when |
| Optional caption for image, video or document. Not for audio |
Upload media once, send it many times
POST (multipart/form-data) → /whatsapp/upload/media
Sending the same file by URL repeatedly makes WhatsApp fetch it every time. Upload it once and reuse the id instead.
curl -X POST "https://connect.scopewiser.com/api/v1/whatsapp/upload/media" \
-H "Authorization: Bearer API-KEY" \
-H "Accept: application/json" \
-F "phone_number_id=PHONE-NUMBER-ID" \
-F "media_file=@/path/to/local/file.jpg"The file field must be named media_file. The response gives you what the send endpoint wants:
{"status":"1","media_id":"1739230482390482","media_type":"document","media_name":"invoice.pdf",
"message":"Upload successful..."}A media_id is tied to the phone_number_id you uploaded against. Upload separately for each number.
The console has a Try upload panel on the page, so you can get a real media_id without writing any code first.
Send a template
Template sends are generated per template rather than through one generic endpoint. On the developer console, under Send Text Message, the Generate API End-point : Send Template Message section lets you pick a WHATSAPP ACCOUNT and a SELECT MESSAGE TEMPLATE, and it builds the call for you with that template's variables in place.
Get the template approved first — Creating & Getting WhatsApp Templates Approved. To list what is available programmatically, call /whatsapp/get/template/list with phone_number_id.
Trigger a bot flow
GET or POST → /whatsapp/trigger-bot
Rather than composing a message, you can start a flow you already built.
Call
/whatsapp/get/bot-flow-listwithphone_number_idto list flows. Each returns anameand aunique_id.Call
/whatsapp/trigger-botwithbot_flow_unique_idandphone_number.
{"status":"1","message":"Bot has been trigger successfully."}This is usually the better integration. Your system decides when; the flow — already tested, with its buttons, labels and follow-ups — decides what.
Check whether it arrived
GET or POST → /whatsapp/get/message-status, with the wa_message_id from the send response.
{"status":"1","message":{"message_status":"delivered","delivery_status_updated_at":"2024-07-28 13:21:03",
"read_time":null,"failed_time":null,"failed_reason":""}}A send returning status: "1" means WhatsApp accepted it, not that it reached the handset. If delivery matters, poll this endpoint or read the same information from your webhook.
Read a conversation
GET or POST → /whatsapp/get/conversation, with phone_number_id, phone_number, limit (up to 50) and optional offset.
Each message carries sender (bot, or an agent), the raw message_content as JSON, conversation_time, wa_message_id, message_status and failed_reason. Keep paging while nextOffset comes back.
