Skip to content
Wbiztool

Messaging API

Send to Multiple Numbers API

Send the same WhatsApp message to several phone numbers and groups in one request. Use it for small broadcasts such as newsletters, offers and announcements.

POSThttps://wbiztool.com/api/v1/send_msg/multi/

Body: JSON or form fields

Wbiztool creates one message per recipient and returns a msg_id for each, so you can check their status individually.

Quick example#

curl -X POST https://wbiztool.com/api/v1/send_msg/multi/ \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 12345,
    "api_key": "YOUR_API_KEY",
    "whatsapp_client": 678,
    "msg_type": 0,
    "country_code": "91",
    "phone": "9876543210,9812345670,Sales Team Mumbai",
    "msg": "Our Diwali sale starts tomorrow. Get 20% off on all orders!"
  }'

Replace 12345, YOUR_API_KEY and 678 with your own values. See Authentication for where to find them.

Request parameters#

Authentication

client_idintegerrequired

Your API Client ID from Settings → API keys.

api_keystringrequired

Your API key from the same page.

whatsapp_clientintegerrequired

ID of the WhatsApp number to send from, from WhatsApp settings. Unlike Send message, this endpoint never picks a number for you.

Recipients and message

phonestringrequired

Phone numbers and group names in one comma-separated string, for example 9876543210,9812345670,Sales Team Mumbai. Don't send a JSON array. See How recipients are read.

country_codestringoptional

Country calling code without +, for example 91. It's added in front of each phone number unless the number already starts with it. In JSON, send it as a string ("91"), not a number. If you send a number, every phone number in the list is treated as a group name (is_group: true), and those messages fail.

msg_typeintegeroptional

0 text (default), 1 image, 2 file or document.

msgstringRequired when msg_type is 0

Message text. For images and files it's the caption and can be empty. WhatsApp formatting works: *bold*, _italic_, ~strikethrough~. message is accepted as an alias.

Images and files

img_urlstringRequired when msg_type is 1

Public http or https URL of the image.

file_urlstringRequired when msg_type is 2

Public http or https URL the file can be downloaded from directly.

file_namestringoptional

File name recipients see, such as price-list.pdf. It's sent in lower case, characters such as & : ? * $ ; are replaced with _, and it's cut to 150 characters. If you leave it out, the name comes from the URL.

Delivery options

webhookstringoptional

URL that receives a POST for each message when it's sent or fails. The payload is the same as for Send message.

Image from a URLcURL
curl -X POST https://wbiztool.com/api/v1/send_msg/multi/ \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 12345,
    "api_key": "YOUR_API_KEY",
    "whatsapp_client": 678,
    "msg_type": 1,
    "country_code": "91",
    "phone": "9876543210,9812345670",
    "img_url": "https://example.com/offers/diwali-sale.jpg",
    "msg": "Our Diwali sale starts tomorrow."
  }'

How recipients are read#

Wbiztool splits phone on commas, trims spaces around each item and then decides what each item is:

  • Only digits (a leading + or leading zeros are fine): treated as a phone number. country_code is added unless the number already starts with it, then the number must be 6 to 15 digits long.
  • Anything else: treated as a WhatsApp group name, found the same way as in Send to group.
  • A group whose name is only digits (for example 2024) is treated as a phone number, and group names containing commas can't be sent from this endpoint. Use Send to group for those.

Other things to know:

  • Numbers that are too short or too long after adding the country code are skipped silently. They don't appear in the response and don't get a msg_id.
  • Duplicates aren't removed. A number listed twice gets two messages.
  • If a local number happens to start with the same digits as country_code (for example 9123456780 with country_code 91), the code isn't added. Send such numbers with the country code already included (919123456780).
  • Image and file URLs aren't checked when you call the API. They're downloaded when each message is sent, so a broken link makes the messages fail later rather than the request. The same send-time rules as Send message apply: images over 16 MB and videos over 64 MB fail, WAV and OGG audio isn't supported, and files (msg_type 2) without a supported extension get .pdf added. See Sending images and files.

Credits#

The whole batch is checked against your remaining credits before anything is created. Every non-empty item in phone counts, including items that are later skipped. If the count is higher than your remaining credits, no messages are created and you get:

{
  "message": "Not enough credits: 120 messages requested, 85 credits remaining",
  "status": 0
}

Messages that are queued but not yet sent also count against your remaining credits. Split large lists into smaller requests or top up your plan. For big campaigns, upload a spreadsheet from the Campaigns page instead.

Response#

A successful request returns HTTP 200:

{
  "msg_ids": [9817263, 9817264, 9817265],
  "messages": [
    { "msg_id": 9817263, "contact": "919876543210", "is_group": false },
    { "msg_id": 9817264, "contact": "919812345670", "is_group": false },
    { "msg_id": 9817265, "contact": "Sales Team Mumbai", "is_group": true }
  ],
  "message": "Successfully created 3 messages",
  "status": 1
}
FieldTypeDescription
statusinteger1 if at least one message was queued, 0 otherwise.
messagestringSuccessfully created N messages on success, otherwise the error.
msg_idsarray of integersIDs of the queued messages, in the order of phone. Only present on success.
messagesarrayOne object per queued message. Only present on success.
messages[].msg_idintegerID of the message.
messages[].contactstringThe phone number with the country code applied, or the group name.
messages[].is_groupbooleantrue if the item was treated as a group name.

Compare messages with the list you sent to find skipped numbers, and check that is_group is false for every item you meant as a phone number.

Errors#

Most errors return HTTP 200 with status set to 0, so always check status in the body. Except for the HTTP 400 and 403 errors, responses (successful ones included) are JSON sent with Content-Type: text/html, so parse the body yourself instead of relying on automatic JSON detection (for example in no-code tools):

{ "message": "Invalid whatsapp client", "status": 0 }
MessageHow to fix it
Auth ErrorSend both client_id and api_key.
Invalid Client IdSend client_id as a number. Returned with HTTP 403.
Auth Error: invalid api keyCheck the key exists, hasn't been deleted and belongs to this client_id. Returned with HTTP 400.
Msg cant be nullText messages (msg_type 0) need msg.
Image Url Can't be nullFor msg_type 1, send img_url.
File Url Can't be nullFor msg_type 2, send file_url.
Not enough credits: … messages requested, … credits remainingSend fewer recipients or add credits. See Credits.
Invalid whatsapp clientThat whatsapp_client ID isn't in your workspace.
No valid contacts foundEvery item in phone was empty or skipped. Check the numbers are 6 to 15 digits with the country code.
Demo Account can not access apisUse a regular account.
Invalid JSON format: …The JSON body isn't valid, or you sent form fields without client_id.

Tips#

  • Send phone as a string: join your list with commas. A JSON array returns {}.
  • Don't use the Python client's send_bulk_messages for now: it sends the list as phones, which this endpoint ignores. Call the endpoint directly as in the examples above.
  • Track each message: save every msg_id from messages, or pass a webhook to be notified as each one is sent or fails.
  • Keep your number connected: every message is sent from your WhatsApp number, so it must stay connected in WhatsApp settings until the whole batch has gone out.
  • Different text per person: this endpoint sends the same msg to everyone. Call Send message once per recipient to personalise each message.