API de mensajería
API de historial de mensajes
Obtén una lista de los mensajes de tu espacio de trabajo en un rango de fechas, con el estado de cada uno. Úsala para cuadrar lo que se envió, generar informes o encontrar mensajes fallidos para reintentarlos.
https://wbiztool.com/api/v1/report/Cuerpo: JSON (necesario para las páginas posteriores a la primera) o campos de formulario
El historial incluye todos los mensajes del espacio de trabajo de tu clave API, tanto si se enviaron a través de la API como desde el panel o una campaña. Los resultados llegan de 200 en 200 por página, del más antiguo al más reciente. Los mismos datos están disponibles en la página de Reportes.
Ejemplo rápido#
curl -X POST https://wbiztool.com/api/v1/report/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"start_date": "01-09-2026",
"end_date": "08-09-2026",
"page": 1
}'import requests
page = 1
history = []
while True:
response = requests.post(
"https://wbiztool.com/api/v1/report/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"start_date": "01-09-2026",
"end_date": "08-09-2026",
"page": page, # must be a JSON number, not a string
},
timeout=60,
)
result = response.json() # read the body even when the HTTP code is 400
if result.get("message") != "Success" or "total" not in result:
print("Failed:", result.get("message", "no message in response"))
break
history.extend(result["history"])
if page * 200 >= result["total"]:
break
page += 1
failed = [m for m in history if m["message_status"] == "Failed"]
print(len(history), "messages,", len(failed), "failed")// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const history = [];
let page = 1;
while (true) {
const response = await fetch("https://wbiztool.com/api/v1/report/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
start_date: "01-09-2026",
end_date: "08-09-2026",
page, // must be a JSON number, not a string
}),
});
const result = await response.json(); // read the body even when the HTTP code is 400
if (result.message !== "Success" || !("total" in result)) {
console.error("Failed:", result.message ?? "no message in response");
break;
}
history.push(...result.history);
if (page * 200 >= result.total) break;
page += 1;
}
const failed = history.filter((m) => m.message_status === "Failed");
console.log(`${history.length} messages, ${failed.length} failed`);<?php
$history = [];
$page = 1;
do {
$ch = curl_init('https://wbiztool.com/api/v1/report/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'start_date' => '01-09-2026',
'end_date' => '08-09-2026',
'page' => $page, // an integer, so json_encode sends a number
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['message'] ?? '') !== 'Success' || !isset($result['total'])) {
echo 'Failed: ' . ($result['message'] ?? 'no message in response');
break;
}
$history = array_merge($history, $result['history']);
$page++;
} while (($page - 1) * 200 < $result['total']);
echo count($history) . ' messages';Sustituye 12345 y YOUR_API_KEY por tus propios valores. Consulta Autenticación para saber dónde encontrarlos.
Parámetros de la solicitud#
Autenticación
client_idintegerobligatorioTu ID de cliente de la API, de Configuración → Claves API.
api_keystringobligatorioTu clave API, de esa misma página.
Filtros
start_datestringobligatorioPrimer día que se incluye, con formato
DD-MM-YYYY, por ejemplo01-09-2026.end_datestringobligatorioFin del rango, con formato
DD-MM-YYYY. Este día no se incluye. Consulta Rango de fechas.whatsapp_clientintegeropcionalDevuelve solo los mensajes enviados desde este número de WhatsApp, usando su ID de la configuración de WhatsApp. Omítelo para obtener los mensajes de todos tus números.
pageintegeropcionalNúmero de página, empezando en
1(valor predeterminado). Cada página contiene hasta 200 mensajes. Envíalo como número JSON.0o un número negativo devuelvetotalcon unhistoryvacío.
Rango de fechas#
Las fechas se interpretan como la medianoche al inicio de ese día en la hora estándar de la India (IST, UTC+5:30), y los mensajes se filtran según cuándo se crearon (se pusieron en cola o se programaron), no según cuándo se enviaron. El rango va desde start_date a las 00:00 hasta end_date a las 00:00, así que:
"start_date": "01-09-2026", "end_date": "08-09-2026"devuelve del 1 al 7 de septiembre. El 8 de septiembre no se incluye.- Para obtener un solo día, pon en
end_dateel día siguiente:"start_date": "15-09-2026", "end_date": "16-09-2026". - Si las dos fechas son iguales, no obtienes ningún mensaje.
Paginación#
Cada respuesta contiene total, el número de mensajes de todo el rango, y hasta 200 de ellos en history. Pide la page 2, 3 y así sucesivamente hasta que page × 200 sea como mínimo total.
Respuesta#
Una solicitud correcta devuelve HTTP 200:
{
"message": "Success",
"status": 0,
"total": 3,
"history": [
{ "id": 9817263, "msg_type": "Text", "contact": "919876543210", "message_status": "Sent" },
{ "id": 9817264, "msg_type": "File", "contact": "919812345670", "message_status": "Failed" },
{ "id": 9817265, "msg_type": "Image", "contact": "Sales Team Mumbai", "message_status": "Pending" }
]
}
| Campo | Tipo | Descripción |
|---|---|---|
message | string | Success cuando la solicitud funcionó; en caso contrario, el error. |
status | integer | Siempre 0. No lo uses para detectar el éxito. |
total | integer | Número de mensajes del rango de fechas en todas las páginas. Solo aparece si la solicitud es correcta. |
history | array | Hasta 200 mensajes de esta página, del más antiguo al más reciente. Vacío cuando hay un error. |
history[].id | integer | ID del mensaje, el mismo que el msg_id que se devolvió al enviarlo. |
history[].msg_type | string | Text, Image o File. |
history[].contact | string | El número de teléfono del destinatario con código de país, o el nombre del grupo en los mensajes a grupos. |
history[].message_status | string | Consulta la tabla de abajo. |
Valores de estado del mensaje#
message_status | Significado |
|---|---|
Pending | En cola o programado, aún no se ha enviado (estado 0). |
Sent | Enviado desde tu número de WhatsApp (estado 1). |
Delivered | Reservado, no se devuelve actualmente. |
Read | Reservado, no se devuelve actualmente. |
Failed | No se pudo enviar o el envío se interrumpió (estado 2). Usa Estado del mensaje para ver el error. |
Cancelled | Cancelado antes de enviarse (estado 3). |
Expired | No se envió antes de su plazo expire_after_seconds (estado 4). |
Actualmente no se registran las marcas de entrega y lectura, así que los mensajes enviados siempre aparecen como Sent. Delivered y Read son valores reservados; si alguna vez aparecen, trátalos como Sent.
Errores#
Los errores devuelven HTTP 200 con status con valor 0, salvo que se indique lo contrario:
{ "message": "Error", "status": 0, "history": [] }
| Mensaje | Cómo solucionarlo |
|---|---|
Error | Falta start_date o end_date o no tienen el formato DD-MM-YYYY, el cuerpo JSON no es válido (a menudo por una coma final) o la solicitud no era un POST. |
Auth Error | Envía client_id y api_key. |
Invalid Client Id | Envía client_id como número. Se devuelve con HTTP 403, sin history. |
Auth Error: invalid api key | Comprueba que la clave existe, que no se ha eliminado y que pertenece a este client_id. Se devuelve con HTTP 400, sin history. |
Demo Account can not access apis | Usa una cuenta normal. |
Consejos#
- Obtén el historial en rangos pequeños: un día o una semana cada vez mantiene bajo el número de páginas.
- Encuentra los mensajes fallidos: filtra
historyporFailedy luego llama a Estado del mensaje con cadaidpara ver por qué falló. Antes de reintentar, revisa elerror:Sending was interrupted and may have been delivered…significa que es posible que el destinatario ya tenga el mensaje. - Los mensajes antiguos se purgan: los mensajes que llegaron a un estado final y no han cambiado en unos 90 días pueden purgarse y dejar de aparecer aquí, igual que los mensajes que siguen en cola 90 días después de crearse o de su hora programada, en un número desconectado o eliminado.
- Seguimiento en tiempo real: para reaccionar a medida que se envían los mensajes, pasa un
webhookcuando envíes el mensaje en lugar de consultar periódicamente este endpoint.
