Saltar al contenido
WbizTool

API de mensajería

API de envío de mensajes

Envía un texto, una imagen o un documento de WhatsApp a un número de teléfono desde tu número de WhatsApp conectado. Úsala para confirmaciones de pedidos, recordatorios de pago, alertas y respuestas de soporte.

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

Cuerpo: JSON, campos de formulario o multipart/form-data al subir un archivo

El mensaje se pone en cola y se envía desde tu número de WhatsApp en pocos instantes. La respuesta te da un msg_id que puedes usar para consultar su estado.

Ejemplo rápido#

curl -X POST https://wbiztool.com/api/v1/send_msg/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "whatsapp_client": 678,
    "msg_type": 0,
    "country_code": "91",
    "phone": "9876543210",
    "msg": "Hi Aman, your order #4821 has shipped and will arrive on Thursday."
  }'

Sustituye YOUR_API_KEY y 678 por tu propia clave y el ID de tu número. Consulta Autenticación para saber dónde encontrarlos. La clave va en la cabecera Authorization: Bearer (recomendado); client_id y api_key en el cuerpo, como JSON o campos de formulario, también funcionan: los ejemplos más abajo los usan.

Parámetros de la solicitud#

Autenticación

AuthorizationheaderRecomendado

Bearer YOUR_API_KEY: tu clave API de Configuración → Claves API. Con la cabecera, client_id y api_key pueden omitirse del cuerpo; si se envían ambas, se usa una clave válida de la cabecera. Consulta Enviar la clave en una cabecera.

client_idintegerSin la cabecera Authorization

Tu ID de cliente de la API, de Configuración → Claves API. Opcional con la cabecera; si lo envías, debe ser el del espacio de trabajo de la clave.

api_keystringSin la cabecera Authorization

Tu clave API, de esa misma página, cuando no la envías en la cabecera.

whatsapp_clientintegerObligatorio si tienes más de un número

ID del número de WhatsApp o de la cuenta de Telegram desde la que se envía, de la configuración de WhatsApp. Si lo omites, se usa el único número conectado, WhatsApp primero: un único número de WhatsApp conectado se usa aunque también haya una cuenta de Telegram conectada, y una cuenta de Telegram solo cuando no hay ningún número de WhatsApp conectado. Un @username usa la única cuenta de Telegram conectada.

Destinatario y mensaje

phonestringobligatorio

El número de WhatsApp del destinatario. Los espacios, +, -, ., los paréntesis y un 00 inicial se eliminan automáticamente, así que +91 98765-43210 funciona. Los valores de hoja de cálculo como 919876543210.0 y 9.19876543210E+11 se leen como sus dígitos, pero uno redondeado como 9.19877E+11 se rechaza, porque le faltan dígitos. Envía el número con su código de país (919876543210) o sin él (9876543210) junto con country_code. Un número local escrito con su 0 inicial también funciona: 09876543210 con country_code 91 va a 919876543210, y 0612345678 con 39 (Italia, donde el 0 forma parte del número) va a 390612345678. Un número escrito con + o 00 lleva su propio código de país: no se le añade country_code, y un (0) entre paréntesis después del código se elimina, así que +44 (0)20 7946 0018 va a 442079460018. Desde una cuenta de Telegram, phone también puede ser un @username, un enlace t.me/username o tg:<id>.

country_codestringopcional

Código telefónico del país sin +, por ejemplo 91 para India o 1 para EE. UU. Se añade delante de phone, salvo que el número ya empiece por él o esté escrito con + o 00. Excepción: con 91, un número de 10 dígitos siempre recibe el prefijo. Con otros códigos, un número local que empiece por los mismos dígitos no recibe el prefijo, así que envíalo con el código de país incluido.

msg_typeintegeropcional

0 texto (predeterminado), 1 imagen, 2 archivo o documento.

msgstringObligatorio cuando msg_type es 0

Texto del mensaje, hasta 3.000 caracteres. En imágenes y archivos es el pie de foto y puede estar vacío. El formato de WhatsApp funciona: *bold*, _italic_, ~strikethrough~. También se acepta message como alias.

Imágenes y archivos

img_urlstringObligatorio cuando msg_type es 1 y no se sube ningún archivo

URL pública http o https de la imagen.

file_urlstringObligatorio cuando msg_type es 2 y no se sube ningún archivo

URL pública http o https desde la que se puede descargar el archivo directamente.

filefileopcional

Sube la imagen o el archivo en lugar de indicar una URL. Envía la solicitud como multipart/form-data con el campo llamado file.

file_namestringopcional

Nombre de archivo que ve el destinatario, como invoice-4821.pdf. Su extensión determina cómo se envía el archivo, así que incluye una. Se envía en minúsculas, los caracteres como & : ? * $ ; se reemplazan por _ y se recorta a 150 caracteres. Si lo omites, el nombre se toma de la URL o del archivo subido.

Opciones de entrega

expire_after_secondsintegeropcional

Marca el mensaje como caducado (estado 4) si no se ha enviado en este número de segundos, por ejemplo 3600 para una hora. Útil para mensajes urgentes, como horas estimadas de entrega. Un proceso en segundo plano lo hace al menos 30 segundos después del plazo, así que no confíes en él para plazos de menos de un minuto.

webhookstringopcional

URL que recibe un POST cuando el mensaje se envía, falla, se cancela o caduca. Consulta Webhook.

Enviar imágenes y archivos#

Límites de descarga para img_url y file_url:

  • La URL debe ser pública: http o https, accesible desde internet. Se siguen hasta 5 redirecciones, y cada una también debe llevar a una dirección pública.
  • Los archivos enlazados pueden pesar hasta 100 MB. El servidor debe empezar a responder en 45 segundos y no quedarse parado durante más tiempo.
  • El archivo se descarga cuando llamas a la API, así que un enlace roto falla de inmediato con Invalid file url.

Los archivos enviados con msg_type 2 conservan estas extensiones:

CategoríaExtensiones
Imágenes.jpg, .jpeg, .jpe, .png, .gif, .webp, .bmp
Documentos.pdf, .doc, .docx, .docm, .xls, .xlsx, .xlsm, .xlsb, .ppt, .pptx, .pptm, .txt, .csv
Audio.mp3, .mpga, .m4a, .aac, .wav, .ogg, .oga
Video.mp4, .mov, .avi, .webm
Archivos comprimidos.zip, .rar

Estas comprobaciones se hacen al enviar el mensaje, no al llamar a la API, así que los fallos solo aparecen en Estado del mensaje y en el webhook:

Problemaerror en Estado del mensaje
Una imagen (msg_type 1) de más de 16 MBFile exceeds WhatsApp size limit (16MB max)
Un video (.mp4, .webm) de más de 64 MB, también si se envía como imagen (msg_type 1)File exceeds WhatsApp size limit (64MB max)
Cualquier otro archivo (msg_type 2) de más de 100 MBFile exceeds WhatsApp size limit (100MB max)
Un archivo vacío (0 bytes)The file is empty
Un archivo .wav u .ogg enviado como imagen (msg_type 1)File type not supported

El audio WAV y OGG no se puede enviar como imagen (msg_type 1). Enviado como archivo (msg_type 2), llega como documento con su propio nombre, como recording.wav. Los archivos .mp3, .mpga, .m4a y .aac llegan como audio que se reproduce en el chat, y msg llega después como un mensaje de texto aparte (el audio no lleva pie).

Imagen desde una URL
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
  -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",
    "img_url": "https://example.com/offers/diwali-sale.jpg",
    "msg": "Our Diwali sale starts today 🎉"
  }'
Subir un archivo
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
  -F client_id=12345 \
  -F api_key=YOUR_API_KEY \
  -F whatsapp_client=678 \
  -F msg_type=2 \
  -F country_code=91 \
  -F phone=9876543210 \
  -F "msg=Your invoice for order #4821 is attached." \
  -F file_name=invoice-4821.pdf \
  -F file=@./invoice-4821.pdf

Usar los clientes oficiales#

Los clientes de Python y Node.js llaman a este endpoint por ti.

from wbiztool_client import WbizToolClient

client = WbizToolClient(api_key="YOUR_API_KEY", client_id="12345")

result = client.send_message(
    phone="9876543210",
    country_code="91",
    msg="Hi Aman, your order #4821 has shipped.",
    whatsapp_client=678,
)
print(result)

Los errores lanzan requests.HTTPError. Lee el motivo con e.response.json()["message"].

Respuesta#

Una solicitud correcta devuelve HTTP 200:

{
  "status": 1,
  "message": "Created",
  "msg_id": 9817263
}
CampoTipoDescripción
statusinteger1 si el mensaje se puso en cola, 0 si la solicitud falló.
messagestringCreated si todo va bien; en caso contrario, el error.
msg_idintegerID del mensaje en cola. Guárdalo para consultar el estado más adelante. Solo aparece si la solicitud es correcta.

"status": 1 significa que el mensaje se puso en cola, no que ya haya llegado al destinatario. Usa un webhook o Estado del mensaje para confirmar que se envió.

Errores#

Los errores devuelven HTTP 400 con status con valor 0 (Account Disabled no tiene campo status):

{ "status": 0, "message": "Msg cant be null" }
MensajeCómo solucionarlo
Auth Error - Please send correct API key and Client idEnvía un api_key que no esté vacío.
Invalid client id.Envía client_id como número.
Auth Error: invalid api keyComprueba que la clave existe, que no se ha eliminado y que pertenece a este client_id.
Either phone or group_name parameter is requiredAñade phone.
Please provide either phone OR group_name, not bothElimina uno de los dos.
Invalid phone numberphone debe ser un número de entre 6 y 17 dígitos. No se admiten letras ni otros símbolos, ni tampoco un valor de hoja de cálculo redondeado como 9.19877E+11.
Invalid Contact Number "…"Con el código de país añadido, el número debe tener entre 7 y 15 dígitos.
Msg cant be nullLos mensajes de texto (msg_type 0) necesitan msg.
Message length is too longLimita msg a 3.000 caracteres o menos.
Image Url Can't be nullPara msg_type 1, envía img_url o sube un file.
File Url Can't be nullPara msg_type 2, envía file_url o sube un file.
Invalid file url, Can't download / Invalid file urlLa URL no es pública, se agotó el tiempo de espera o el archivo supera los 100 MB.
Invalid whatsapp clientEse ID de whatsapp_client no está en tu espacio de trabajo.
Invalid whatsapp client id.Envía whatsapp_client. Es obligatorio cuando tu espacio de trabajo tiene más de un número conectado.
Telegram usernames can only be sent to from a Telegram account: pass its id as whatsapp_clientUn @username, un enlace t.me o tg:<id> en phone necesita una cuenta de Telegram como whatsapp_client.
Not enough creditsEl espacio de trabajo está en el plan gratuito y no le quedan mensajes: los planes de pago envían mensajes ilimitados. Consulta Cuando te quedas sin mensajes.
Daily limit reached: a number can send 1,000 messages in 24 hours (fair use). Send the rest tomorrow. (HTTP 429, "code": "daily_limit_reached")Este número ya aceptó 1.000 mensajes en las últimas 24 horas (uso justo). La respuesta incluye igualmente el msg_id del mensaje rechazado, que aparece como fallido. Envía el resto más tarde o desde otro número.
Demo Account can not access apisUsa una cuenta normal.
Account DisabledTu cuenta está desactivada. Contacta con soporte.
Invalid JSON format: …El cuerpo JSON no es válido, a menudo por una coma final o un salto de línea sin escapar en msg. Usa \n para los saltos de línea.

Un mensaje en cola todavía puede fallar al enviarse, por ejemplo con File exceeds WhatsApp size limit (…). Esos errores nunca aparecen en esta respuesta. Consulta Enviar imágenes y archivos y revisa Estado del mensaje.

Webhook#

Si pasas webhook, WbizTool envía un POST a esa URL cuando el mensaje se envía o falla, y también cuando se cancela o caduca antes de haberse enviado. El cuerpo va codificado como formulario (application/x-www-form-urlencoded), no como JSON:

msg_id=9817263&status=SENT
CampoValores
msg_idEl msg_id que se devolvió al enviar el mensaje.
statusSENT, FAILED, CANCELLED (cancelado antes de enviarse: con Cancelar mensaje, desde el panel, o porque se eliminó su número de WhatsApp o su campaña) o EXPIRED (no se envió antes de que se agotara expire_after_seconds)

Cada webhook va firmado: las cabeceras WbizTool-Timestamp y WbizTool-Signature (v1= y un HMAC-SHA256 de <timestamp>.<raw body> con el secreto de firma de tu espacio de trabajo) te permiten comprobar que viene de WbizTool. Consulta cómo obtener el secreto y la comprobación en Python y Node.js en Firmas de webhooks; los receptores que ignoran las cabeceras siguen funcionando.

Responde con cualquier código 2xx; si hay una redirección, se sigue, como máximo 3 veces. Si tu endpoint no responde en 10 segundos, no se puede alcanzar o devuelve 429 o 5xx, WbizTool lo reintenta a los 30 segundos, al minuto y a los 2 minutos (4 intentos en total). Las demás respuestas 4xx no se reintentan. La URL debe ser una dirección pública de internet: un webhook a una dirección privada o local (como 192.168.x.x o localhost) no se envía.

Consejos#

  • Números de teléfono: guarda los números en formato internacional y envíalos con country_code para evitar ambigüedades.
  • Saltos de línea en JSON: escríbelos como \n dentro de msg. Un salto de línea literal hace que el JSON no sea válido.
  • Mantén tu número conectado: los mensajes se envían desde tu número de WhatsApp, así que debe seguir conectado en la configuración de WhatsApp.
  • Muchos destinatarios: para enviar el mismo mensaje a varios números en una sola solicitud, usa Enviar a varios números. Para campañas grandes, sube una hoja de cálculo desde la página de Campañas.