Saltar al contenido
WbizTool

Envía mensajes de WhatsApp con Python

Envía textos, imágenes y archivos de WhatsApp desde un script de Python, desde tu propio número vinculado a WbizTool como WhatsApp Web. Usa el paquete oficial wbiztool-client o una simple llamada con requests al mismo endpoint.

Prueba gratuita: 50 mensajes en cualquier periodo de 30 días, sin tarjeta.

Cómo funciona

  1. Obtén tu clave API y vincula tu número

    Regístrate y vincula tu número de WhatsApp en la página Números de WhatsApp con un código QR o un código de vinculación, igual que WhatsApp Web. En Configuración → Claves API, crea una clave y copia tu Client ID (la guía de claves API de abajo muestra dónde). El ID que aparece en la tarjeta del número (por ejemplo, ID 678) es tu whatsapp_client.

  2. Instala el cliente, o usa requests

    Ejecuta pip install wbiztool-client para el cliente oficial. Si prefieres no añadir un paquete, la librería requests funciona igual de bien: los ejemplos de abajo muestran las dos formas.

  3. Envía el mensaje

    Haz un POST con tus credenciales, el número de teléfono y el texto a https://wbiztool.com/api/v1/send_msg/. Una respuesta con "status": 1 y un msg_id significa que el mensaje está en cola en tu número.

  4. Comprueba que salió

    Pasa una URL de webhook para que te avisen cuando el mensaje se envíe o falle, o consulta el endpoint de estado del mensaje con el msg_id.

Ejemplos de código en Python

Instalar el cliente oficial
pip install wbiztool-client
Enviar un texto con el cliente oficial
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)
Enviar un texto con requests
import requests

response = requests.post(
    "https://wbiztool.com/api/v1/send_msg/",
    json={
        "client_id": 12345,
        "api_key": "YOUR_API_KEY",
        "whatsapp_client": 678,
        "msg_type": 0,
        "country_code": "91",
        "phone": "9876543210",
        "msg": "Hi Aman, your order #4821 has shipped and will arrive on Thursday.",
    },
    timeout=60,
)
result = response.json()  # read the body even when the HTTP code is 400

if result.get("status") == 1:
    print("Queued with msg_id", result["msg_id"])
else:
    print("Failed:", result.get("message"))
Respuesta
{"status": 1, "message": "Created", "msg_id": 9817263}
Enviar un PDF (subida de archivo)
import requests

with open("invoice-4821.pdf", "rb") as f:
    response = requests.post(
        "https://wbiztool.com/api/v1/send_msg/",
        data={
            "client_id": 12345,
            "api_key": "YOUR_API_KEY",
            "whatsapp_client": 678,
            "msg_type": 2,
            "country_code": "91",
            "phone": "9876543210",
            "msg": "Your invoice for order #4821 is attached.",
            "file_name": "invoice-4821.pdf",
        },
        files={"file": f},
        timeout=120,
    )
print(response.json())
Consultar el estado del mensaje
import requests

msg_id = 9817263
response = requests.post(
    f"https://wbiztool.com/api/v1/message/status/{msg_id}/",
    json={
        "client_id": 12345,
        "api_key": "YOUR_API_KEY",
    },
    timeout=60,
)
result = response.json()  # read the body even when the HTTP code is 400

if result.get("message") == "Unknown message id":
    print("No message with this ID in your workspace")
elif "status_text" not in result:
    print("Request failed:", result.get("message", "no message in response"))
elif result["status"] == 1:
    print("Sent")
elif result["status"] == 2:
    print("Failed:", result["error"])
else:
    print("Status:", result["status_text"])
Programar un mensaje para más tarde
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

import requests

send_at = datetime.now(ZoneInfo("Asia/Kolkata")) + timedelta(hours=2)

response = requests.post(
    "https://wbiztool.com/api/v1/schedule_msg/",
    json={
        "client_id": 12345,
        "api_key": "YOUR_API_KEY",
        "whatsapp_client": 678,
        "msg_type": 0,
        "country_code": "91",
        "phone": "9876543210",
        "msg": "Hi Aman, a reminder that your appointment starts in 30 minutes.",
        "date": send_at.strftime("%d/%m/%Y"),
        "time": send_at.strftime("%H:%M"),
        "timezone": "Asia/Kolkata",
    },
    timeout=60,
)
result = response.json()  # schedule errors come back with HTTP 200 and "status": 0

if result.get("status") == 1:
    print("Scheduled with msg_id", result["msg_id"])
else:
    print("Failed:", result.get("message", "no message in response"))
Recibir el webhook de estado (Flask)
from flask import Flask, request

app = Flask(__name__)

@app.post("/wbiztool-webhook")
def wbiztool_webhook():
    # WbizTool posts form fields, not JSON.
    msg_id = request.form["msg_id"]
    status = request.form["status"]  # SENT, FAILED, CANCELLED or EXPIRED
    print(msg_id, status)
    return "", 200

Lo que puedes hacer

  • Textos, imágenes y archivos

    Pon msg_type en 0 para texto, 1 para una imagen o 2 para un archivo. Indica una img_url o file_url pública, o sube el propio archivo con files= en requests.

  • Mensajes personalizados con tus datos

    Construye msg con tus propios datos: un nombre, un número de pedido, una fecha de vencimiento. El formato de WhatsApp como *negrita* y _cursiva_ funciona, hasta 3.000 caracteres.

  • Estado por webhook o consultándolo

    Un webhook recibe un POST con el msg_id y SENT, FAILED, CANCELLED o EXPIRED. O llama al endpoint de estado del mensaje: un mensaje fallido viene con su error, como Phone number invalid.

  • Programa para más tarde

    Haz un POST a /api/v1/schedule_msg/ con date (dd/mm/aaaa), time (HH:MM) y una timezone como Asia/Kolkata. strftime("%d/%m/%Y") y strftime("%H:%M") los construyen por ti.

  • Descarta los mensajes que llegan tarde

    expire_after_seconds marca un mensaje como caducado si no salió a tiempo, algo útil para mensajes urgentes como una hora estimada de entrega.

  • Recordatorios recurrentes

    La API de recordatorios repite un mensaje según una programación cron, por ejemplo a las 10:00 el día 1 de cada mes. Los recordatorios requieren un plan de pago.

Conviene saber

  • "status": 1 significa que el mensaje está en cola, no que se entregó. Sent es el estado final de éxito; la API no informa si el mensaje se entregó o se leyó.
  • Los errores al enviar un mensaje llegan con HTTP 400 (429 en el límite diario); los errores al programar un mensaje suelen llegar con HTTP 200 y "status": 0, así que lee response.json() y comprueba status en lugar del código HTTP. El cliente oficial lanza requests.HTTPError: lee el motivo con e.response.json()["message"].
  • El cliente oficial todavía no cubre bien todos los endpoints: sus schedule_message y check_credentials() no funcionan con la API actual. Llama a /api/v1/schedule_msg/ con requests como se muestra arriba, y a /api/v1/me/ de la misma forma.
  • Guarda la clave API en tu servidor, por ejemplo en una variable de entorno. Cualquiera que la tenga puede enviar desde tus números, así que nunca la pongas en JavaScript del navegador, en una app móvil ni en código que publiques.
  • La prueba gratuita incluye 50 mensajes en cualquier periodo de 30 días y 1 número, sin tarjeta. Los planes de pago empiezan en $25 al mes en EE. UU. (tu precio aparece en Precios) y envían mensajes ilimitados con uso justo: hasta 1.000 al día por número.
  • Los mensajes salen desde tu propio número de WhatsApp, así que se aplican las reglas de WhatsApp: escribe a personas que esperan saber de ti.

Preguntas frecuentes

¿Hay una librería oficial de Python para la API de WbizTool?
Sí: wbiztool-client en PyPI (pip install wbiztool-client). Usa sus send_message y get_message_status. Para programar mensajes y comprobar las credenciales, llama a los endpoints con requests.
¿Cómo envío un PDF o una imagen desde Python?
Usa msg_type 1 con img_url para una imagen, o msg_type 2 con file_url para un archivo. Para enviar un archivo desde el disco, súbelo como multipart form data en un campo llamado file, e indica file_name con su extensión, como invoice-4821.pdf.
¿Cómo sé si el mensaje se envió?
Una respuesta con "status": 1 y un msg_id significa que está en cola. Pasa una URL de webhook para recibir un POST con SENT, FAILED, CANCELLED o EXPIRED, o llama al endpoint de estado del mensaje con el msg_id. Sent es el estado final: la API no informa si se entregó o se leyó.
¿En qué formato envío el número de teléfono?
Envía el número con su código de país (919876543210), o sin él (9876543210) junto con country_code (91). Los espacios, el +, los guiones y los paréntesis se quitan por ti, así que +91 98765-43210 también funciona.
¿Necesito la API de WhatsApp Business o la aprobación de Meta?
No. WbizTool envía desde tu propio número de WhatsApp o WhatsApp Business, vinculado como WhatsApp Web. No hay aprobación de Meta ni plantillas de mensajes que aprobar.
¿Se paga por mensaje?
No. La prueba gratuita incluye 50 mensajes en cualquier periodo de 30 días. Los planes de pago envían mensajes ilimitados con uso justo, hasta 1.000 al día por número: Lite $25, Standard $59 y Advanced $149 al mes en EE. UU.; la página de Precios muestra el precio de tu país.

Lee las guías

Relacionado

Envía hoy tu primer mensaje automatizado de WhatsApp

Crea una cuenta, escanea el código QR y envía un mensaje en menos de cinco minutos.

Empieza gratis

Planes de pago desde $25 al mes en EE. UU. Precios