API de mensagens
API de envio para vários números
Envie a mesma mensagem de WhatsApp para vários números de telefone e grupos em uma única requisição. Use-a para pequenos disparos, como newsletters, ofertas e comunicados.
https://wbiztool.com/api/v1/send_msg/multi/Corpo: JSON ou campos de formulário
O WbizTool cria uma mensagem por destinatário e retorna um msg_id para cada uma, para que você possa verificar o status de cada mensagem individualmente.
Exemplo rápido#
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!"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/send_msg/multi/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 0,
"country_code": "91",
"phone": ",".join(["9876543210", "9812345670", "Sales Team Mumbai"]),
"msg": "Our Diwali sale starts tomorrow. Get 20% off on all orders!",
},
timeout=60,
)
result = response.json() # read the body even when the HTTP code is 400
if result.get("status") == 1:
for item in result["messages"]:
print(item["contact"], "->", item["msg_id"])
else:
print("Failed:", result.get("message", "no message in response"))// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/send_msg/multi/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
msg_type: 0,
country_code: "91",
phone: ["9876543210", "9812345670", "Sales Team Mumbai"].join(","),
msg: "Our Diwali sale starts tomorrow. Get 20% off on all orders!",
}),
});
const result = await response.json(); // read the body even when the HTTP code is 400
if (result.status === 1) {
for (const item of result.messages) {
console.log(item.contact, "->", item.msg_id);
}
} else {
console.error("Failed:", result.message ?? "no message in response");
}<?php
$payload = [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'msg_type' => 0,
'country_code' => '91',
'phone' => implode(',', ['9876543210', '9812345670', 'Sales Team Mumbai']),
'msg' => 'Our Diwali sale starts tomorrow. Get 20% off on all orders!',
];
$ch = curl_init('https://wbiztool.com/api/v1/send_msg/multi/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
foreach ($result['messages'] as $item) {
echo $item['contact'] . ' -> ' . $item['msg_id'] . PHP_EOL;
}
} else {
echo 'Failed: ' . ($result['message'] ?? 'no message in response');
}Substitua 12345, YOUR_API_KEY e 678 pelos seus próprios valores. Veja em Autenticação onde encontrá-los.
Parâmetros da requisição#
Autenticação
client_idintegerobrigatórioSeu ID do Cliente da API, em Configurações → Chaves API.
api_keystringobrigatórioSua chave de API, na mesma página.
whatsapp_clientintegerobrigatórioID do número de WhatsApp ou da conta do Telegram a partir do qual enviar, nas configurações do WhatsApp. Ao contrário de Enviar mensagem, este endpoint nunca escolhe um número por você.
Destinatários e mensagem
phonestringobrigatórioNúmeros de telefone e nomes de grupos em uma única string separada por vírgulas, por exemplo
9876543210,9812345670,Sales Team Mumbai. Não envie um array JSON. Veja Como os destinatários são lidos.country_codestringopcionalCódigo de discagem do país sem
+, por exemplo91. Ele é adicionado antes de cada número de telefone, a menos que o número já comece com ele ou esteja escrito com+ou00. Em JSON, tanto uma string ("91") quanto um número (91) funcionam.msg_typeintegeropcional0texto (padrão),1imagem,2arquivo ou documento.msgstringObrigatório quando msg_type é 0Texto da mensagem. Para imagens e arquivos, é a legenda e pode ficar vazio. A formatação do WhatsApp funciona:
*bold*,_italic_,~strikethrough~.messageé aceito como alias.
Imagens e arquivos
img_urlstringObrigatório quando msg_type é 1URL pública
httpouhttpsda imagem.file_urlstringObrigatório quando msg_type é 2URL pública
httpouhttpsa partir da qual o arquivo pode ser baixado diretamente.file_namestringopcionalNome do arquivo que os destinatários veem, como
price-list.pdf. Ele é enviado em letras minúsculas, caracteres como& : ? * $ ;são substituídos por_, e ele é cortado em 150 caracteres. Se você não enviar, o nome vem da URL.
Opções de entrega
webhookstringopcionalURL que recebe um
POSTpara cada mensagem quando ela é enviada, falha, é cancelada ou expira. O payload é o mesmo de Enviar mensagem.
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."
}'Como os destinatários são lidos#
O WbizTool divide phone nas vírgulas, remove os espaços ao redor de cada item e então decide o que cada item é:
- Números de telefone podem ser escritos como você os tem:
+91 98765 43210,98765-43210,(987) 654-3210,0091 98765 43210e+44 (0)20 7946 0018funcionam, assim como valores de planilha como919876543210.0e9.19876543210E+11. country_codeé adicionado a menos que o número já comece com ele ou esteja escrito com+ou00:+44 20 7946 0018comcountry_code91continua442079460018. Assim, uma lista pode misturar países: escreva os números dos outros países com+.- Um número local escrito com o
0inicial também funciona:09876543210comcountry_code91vai para919876543210, e0612345678com39(Itália, onde o0faz parte do número) vai para390612345678. - Com o código do país incluído, um número precisa ter de 7 a 15 dígitos.
- Texto com letras ou outros símbolos, como
Sales Team MumbaiouFamily 2024, é tratado como nome de grupo de WhatsApp, encontrado da mesma forma que em Enviar para um grupo. - Um nome de grupo sem letras, como
2024-2025, é lido como número de telefone, a menos que tenha menos de 10 dígitos e o seu espaço de trabalho já tenha enviado uma mensagem para um grupo com exatamente esse nome (ele aparece em Grupos nos Contatos). Um nome curto, com menos de 7 dígitos e um hífen, ponto ou parênteses, como2024-25ou(2024), é sempre um nome de grupo. Nomes de grupo que contêm vírgulas não podem ser usados neste endpoint. Para esses casos, use Enviar para um grupo. - De uma conta do Telegram, um
@username, um linkt.me/usernameoutg:<id>é uma pessoa, não um nome de grupo, e um número de telefone vai para essa pessoa no Telegram. De um número de WhatsApp, nomes de usuário, linkst.meetg:<id>são ignorados.
Outros pontos importantes:
- Números curtos ou longos demais depois de adicionar o código do país, valores de planilha arredondados e itens que são só zeros (
0,00) são ignorados sem aviso. Eles não aparecem na resposta e não recebem ummsg_id. - Duplicados não são removidos. Um número listado duas vezes recebe duas mensagens.
- Se um número local começar com os mesmos dígitos de
country_code(por exemplo9123456780comcountry_code91), o código não é adicionado. Envie esses números já com o código do país incluído (919123456780). - As URLs de imagens e arquivos não são verificadas quando você chama a API. Elas são baixadas no envio de cada mensagem, então um link quebrado faz as mensagens falharem depois, e não a requisição. Valem as mesmas regras de envio de Enviar mensagem: imagens acima de 16 MB e vídeos acima de 64 MB falham, áudio WAV e OGG não pode ser enviado como imagem (
msg_type1), e arquivos (msg_type2) sem extensão ou com uma que não é aceita recebem.pdfno final. Veja Enviar imagens e arquivos.
Limites de mensagens#
O lote inteiro é verificado antes de qualquer mensagem ser criada, então uma lista nunca é enviada pela metade. Todo item não vazio em phone conta, inclusive os que forem ignorados depois, e mensagens na fila que ainda não foram enviadas também contam.
- Todos os planos: o lote precisa caber no limite diário de uso justo do número que envia – 1.000 mensagens em quaisquer 24 horas. Caso contrário, nenhuma mensagem é criada e você recebe:
{
"message": "Daily limit reached: a number can send 1,000 messages in 24 hours (fair use). Send the rest tomorrow. 1200 messages requested, 640 more can go out from this number in the next 24 hours.",
"code": "daily_limit_reached",
"status": 0
}
- Plano gratuito: o lote também precisa caber nas mensagens grátis que restam ao espaço de trabalho (50 em quaisquer 30 dias). Caso contrário, você recebe:
{
"message": "Not enough credits: 120 messages requested, 35 credits remaining",
"status": 0
}
Divida listas grandes entre vários números ou dias. Para campanhas grandes, envie uma planilha pela página Campanhas.
Resposta#
Uma requisição bem-sucedida retorna 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
}
| Campo | Tipo | Descrição |
|---|---|---|
status | integer | 1 se pelo menos uma mensagem entrou na fila, 0 caso contrário. |
message | string | Successfully created N messages em caso de sucesso; caso contrário, o erro. |
msg_ids | array de inteiros | IDs das mensagens na fila, na ordem de phone. Presente apenas em caso de sucesso. |
messages | array | Um objeto por mensagem na fila. Presente apenas em caso de sucesso. |
messages[].msg_id | integer | ID da mensagem. |
messages[].contact | string | O número de telefone com o código do país aplicado, ou o nome do grupo. |
messages[].is_group | boolean | true se o item foi tratado como nome de grupo. |
Compare messages com a lista que você enviou para encontrar números ignorados, e confira se is_group é false em todos os itens que você queria enviar como número de telefone.
Erros#
A maioria dos erros retorna HTTP 200 com status igual a 0, então sempre verifique status no corpo. Com exceção dos erros HTTP 400 e 403, as respostas (inclusive as de sucesso) são JSON enviado com Content-Type: text/html, então interprete o corpo você mesmo em vez de depender da detecção automática de JSON (por exemplo, em ferramentas no-code):
{ "message": "Invalid whatsapp client", "status": 0 }
| Mensagem | Como corrigir |
|---|---|
Auth Error | Envie client_id e api_key. |
Invalid Client Id | Envie client_id como número. Retornado com HTTP 403. |
Auth Error: invalid api key | Verifique se a chave existe, não foi excluída e pertence a este client_id. Retornado com HTTP 400. |
Msg cant be null | Mensagens de texto (msg_type 0) precisam de msg. |
Image Url Can't be null | Para msg_type 1, envie img_url. |
File Url Can't be null | Para msg_type 2, envie file_url. |
Not enough credits: … messages requested, … credits remaining | As mensagens do plano gratuito não cobrem a lista. Envie menos destinatários ou escolha um plano. Veja Limites de mensagens. |
Daily limit reached: … messages requested, … more can go out from this number in the next 24 hours. | Divida a lista entre dias ou números. Veja Limites de mensagens. |
Invalid whatsapp client | Esse ID de whatsapp_client não está no seu espaço de trabalho. |
No valid contacts found | Todos os itens em phone estavam vazios ou foram ignorados. Verifique se os números têm de 7 a 15 dígitos com o código do país. |
Demo Account can not access apis | Use uma conta normal. |
Invalid JSON format: … | O corpo JSON não é válido, ou você enviou campos de formulário sem client_id. |
Dicas#
- Envie
phonecomo string: junte sua lista com vírgulas. Um array JSON retorna{}. - Não use o
send_bulk_messagesdo cliente Python por enquanto: ele envia a lista comophones, que este endpoint ignora. Chame o endpoint diretamente, como nos exemplos acima. - Acompanhe cada mensagem: guarde cada
msg_iddemessages, ou informe umwebhookpara ser notificado quando cada uma for enviada, falhar, for cancelada ou expirar. - Mantenha seu número conectado: todas as mensagens são enviadas do seu número de WhatsApp, então ele precisa continuar conectado nas configurações do WhatsApp até que o lote inteiro tenha sido enviado.
- Texto diferente para cada pessoa: este endpoint envia o mesmo
msgpara todos. Chame Enviar mensagem uma vez por destinatário para personalizar cada mensagem.
