v1.0

API REST — Referencia Completa

Documentación de todos los endpoints disponibles en Massiva Desktop

Bearer Token http://localhost:3000 JSON 76 endpoints

💬 Chats

Operaciones sobre chats de WhatsApp. Todos los endpoints requieren que la sesión indicada esté en estado connected.

GET Listar Chats /api/chats

Obtiene la lista de chats activos de una sesión de WhatsApp. Soporta filtros por estado de lectura, paginación y modo ligero.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión de WhatsApp
onlyUnreadbooleanNoSi es true, retorna solo chats no leídos
limitnumberNoMáximo de chats a retornar (1–100)
includePushnamebooleanNoIncluir nombre push del contacto
litebooleanNoVersión reducida de los datos
Respuesta 200
{
  "success": true,
  "data": [
    {
      "id": "593991234567@c.us",
      "name": "Juan Pérez",
      "isGroup": false,
      "unreadCount": 2,
      "timestamp": 1716739200,
      "lastMessage": { "body": "Hola, ¿cómo estás?", "fromMe": false }
    }
  ],
  "message": "5 chats obtenidos"
}
Errores
  • 400sessionId es requerido o la sesión no está conectada
  • 404Sesión no encontrada
GET Obtener Chat Específico /api/chats/:chatId

Obtiene información detallada de un chat por su ID.

Parámetros de ruta
ParámetroTipoRequeridoDescripción
chatIdstringID del chat (ej: 593991234567@c.us)
Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
Respuesta 200
{
  "success": true,
  "data": {
    "id": "593991234567@c.us",
    "name": "Juan Pérez",
    "isGroup": false,
    "unreadCount": 0,
    "timestamp": 1716739200,
    "isArchived": false,
    "isMuted": false
  }
}
  • 400chatId o sessionId requerido
  • 404Sesión o chat no encontrado
GET Mensajes del Chat /api/chats/:chatId/messages

Obtiene los mensajes de un chat específico desde WhatsApp.

Parámetros de ruta
ParámetroTipoRequeridoDescripción
chatIdstringID del chat
Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
limitnumberNoCantidad de mensajes (1–100)
acknumberNoFiltrar por estado ACK
litebooleanNoVersión reducida
Respuesta 200
{
  "success": true,
  "data": [
    {
      "id": { "id": "3EB0ABC123", "fromMe": true },
      "body": "Hola, ¿cómo estás?",
      "type": "chat",
      "timestamp": 1716739200,
      "from": "593991234567@c.us",
      "to": "593987654321@c.us",
      "ack": 3
    }
  ],
  "message": "20 mensajes obtenidos"
}
GET Foto de Perfil del Chat /api/chats/:chatId/profile-picture

Obtiene la URL de la foto de perfil de un chat o contacto de WhatsApp.

Parámetros de ruta
ParámetroTipoRequeridoDescripción
chatIdstringID del chat
Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
Respuesta 200
{
  "success": true,
  "data": {
    "profilePicUrl": "https://pps.whatsapp.net/v/t61.24694-24/abc123.jpg"
  }
}
Si el contacto no tiene foto de perfil, profilePicUrl retorna null.
POST Marcar Chat como Leído /api/chats/:chatId/read

Marca todos los mensajes no leídos de un chat como leídos.

Parámetros de ruta
ParámetroTipoRequeridoDescripción
chatIdstringID del chat
Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
Respuesta 200
{ "success": true, "message": "Chat marcado como leído" }
POST Enviar Estado Escribiendo /api/chats/:chatId/typing

Envía el indicador de estado "escribiendo..." al chat especificado.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
Respuesta 200
{ "success": true, "message": "Estado \"escribiendo\" enviado" }
POST Enviar Ubicación /api/chats/:chatId/location

Envía una ubicación geográfica al chat especificado.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
latitudenumberLatitud (ej: -0.225219)
longitudenumberLongitud (ej: -78.524493)
descriptionstringNoNombre del lugar
addressstringNoDirección del lugar
urlstringNoURL relacionada
Ejemplo
{
  "sessionId": "session-abc123",
  "latitude": -0.225219,
  "longitude": -78.524493,
  "description": "Oficina Massiva",
  "address": "Quito, Ecuador"
}
Respuesta 200
{
  "success": true,
  "data": { "id": { "id": "3EB0ABC456" }, "type": "location" },
  "message": "Ubicación enviada correctamente"
}
POST Enviar Mensaje con Botones /api/chats/:chatId/buttons

Envía un mensaje interactivo con botones de respuesta rápida al chat.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
messageBodystringCuerpo del mensaje
buttonsarrayArray de {id, text}
titlestringNoTítulo del mensaje
footerstringNoPie de mensaje
Ejemplo
{
  "sessionId": "session-abc123",
  "messageBody": "¿Deseas continuar?",
  "buttons": [
    { "id": "btn_si", "text": "Sí" },
    { "id": "btn_no", "text": "No" }
  ],
  "title": "Confirmación",
  "footer": "Massiva"
}
POST Enviar Mensaje con Lista /api/chats/:chatId/list

Envía un mensaje interactivo con una lista desplegable de opciones.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
listBodystringCuerpo del mensaje
buttonTextstringTexto del botón desplegable
sectionsarrayArray de secciones con {title, rows: [{id, title, description}]}
titlestringNoTítulo del mensaje
footerstringNoPie de mensaje
Ejemplo
{
  "sessionId": "session-abc123",
  "listBody": "Selecciona una opción:",
  "buttonText": "Ver opciones",
  "sections": [
    {
      "title": "Soporte",
      "rows": [
        { "id": "soporte_tecnico", "title": "Soporte técnico", "description": "Problemas con el sistema" },
        { "id": "facturacion", "title": "Facturación", "description": "Consultas de pago" }
      ]
    }
  ]
}

👥 Contactos

Gestión del directorio de contactos local (SQLite) y operaciones de consulta hacia WhatsApp.

GETListar Contactos/api/contacts

Obtiene la lista paginada de contactos con búsqueda y filtros.

Query Params
ParámetroTipoRequeridoDescripción
pagenumberNoNúmero de página (default: 1)
limitnumberNoRegistros por página (1–100, default: 50)
searchstringNoBúsqueda por nombre o teléfono
isGroupbooleanNoFiltrar solo grupos
isBlockedbooleanNoFiltrar solo bloqueados
tagIdstringNoFiltrar por etiqueta
allbooleanNoRetornar todos sin paginación
Respuesta 200
{
  "success": true,
  "data": [
    {
      "id": "clxyz123",
      "name": "Juan Pérez",
      "phoneNumber": "+593991234567",
      "isGroup": false,
      "isBlocked": false,
      "createdAt": "2026-01-15T10:00:00.000Z",
      "tags": [{ "tag": { "id": "tag-abc", "name": "Cliente", "color": "#3B82F6" } }]
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 120, "totalPages": 3 }
}
POSTCrear Contacto/api/contacts

Crea un nuevo contacto en la base de datos local.

Body JSON
CampoTipoRequeridoDescripción
phoneNumberstringNúmero de teléfono (ej: +593991234567)
namestringNoNombre del contacto
isGroupbooleanNoSi es grupo de WhatsApp
avatarstringNoURL de foto de perfil
Respuesta 201
{
  "success": true,
  "data": { "id": "clxyz456", "name": "María García", "phoneNumber": "+593991234567", "isBlocked": false },
  "message": "Contacto creado correctamente"
}
  • 400phoneNumber es requerido o contacto ya existe
GETObtener Contacto/api/contacts/:id

Obtiene la información detallada de un contacto por su ID (CUID).

Respuesta 200
{
  "success": true,
  "data": { "id": "clxyz123", "name": "Juan Pérez", "phoneNumber": "+593991234567", "isBlocked": false, "tags": [] }
}
  • 404Contacto no encontrado
PUTActualizar Contacto/api/contacts/:id

Actualiza los campos de un contacto. Solo se actualizan los campos enviados.

Body JSON
CampoTipoRequeridoDescripción
namestringNoNuevo nombre
phoneNumberstringNoNuevo número
avatarstringNoURL de foto de perfil
isBlockedbooleanNoEstado de bloqueo
Respuesta 200
{ "success": true, "data": { "id": "clxyz123", "name": "Juan Pérez Actualizado" }, "message": "Contacto actualizado correctamente" }
DELETEEliminar Contacto/api/contacts/:id

Elimina un contacto de la base de datos local de forma permanente.

Respuesta 200
{ "success": true, "message": "Contacto eliminado correctamente" }
POSTBloquear Contacto/api/contacts/:id/block

Marca un contacto como bloqueado (isBlocked = true).

{ "success": true, "data": { "id": "clxyz123", "isBlocked": true }, "message": "Contacto bloqueado correctamente" }
POSTDesbloquear Contacto/api/contacts/:id/unblock

Desmarca el bloqueo de un contacto (isBlocked = false).

{ "success": true, "data": { "id": "clxyz123", "isBlocked": false }, "message": "Contacto desbloqueado correctamente" }
GETMensajes del Contacto/api/contacts/:id/messages

Historial de mensajes almacenados en BD para un contacto, orden descendente.

Query Params
ParámetroTipoRequeridoDescripción
pagenumberNoPágina (default: 1)
limitnumberNoRegistros por página (default: 50)
Respuesta 200
{
  "success": true,
  "data": [
    { "id": "msg-abc123", "content": "Hola", "direction": "INBOUND", "isRead": true, "timestamp": "2026-05-26T10:00:00.000Z" }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 10, "totalPages": 1 }
}
GETEstadísticas de Contactos/api/contacts/stats

Conteos generales sobre los contactos en la base de datos.

{
  "success": true,
  "data": { "total": 350, "groups": 12, "blocked": 5, "recent": 28 }
}
recent indica contactos creados en los últimos 7 días.
GETListar Etiquetas/api/contacts/tags

Obtiene todas las etiquetas disponibles con conteo de contactos asignados.

{
  "success": true,
  "data": [
    { "id": "tag-abc123", "name": "Cliente VIP", "color": "#3B82F6", "_count": { "contacts": 45 } }
  ]
}
POSTCrear Etiqueta/api/contacts/tags

Crea una nueva etiqueta para organizar contactos.

Body JSON
CampoTipoRequeridoDescripción
namestringNombre único de la etiqueta
colorstringNoColor hex (default: #3B82F6)
{ "success": true, "data": { "id": "tag-xyz789", "name": "Proveedor", "color": "#F59E0B" }, "message": "Etiqueta creada correctamente" }
  • 400Nombre requerido o ya existe una etiqueta con ese nombre
PUTActualizar Etiqueta/api/contacts/tags/:id

Actualiza el nombre o color de una etiqueta existente.

Body JSON
CampoTipoRequeridoDescripción
namestringNoNuevo nombre
colorstringNoNuevo color hex
{ "success": true, "data": { "id": "tag-abc123", "name": "Cliente Premium", "color": "#8B5CF6" }, "message": "Etiqueta actualizada correctamente" }
DELETEEliminar Etiqueta/api/contacts/tags/:id

Elimina una etiqueta. Las relaciones con contactos se eliminan automáticamente (CASCADE).

{ "success": true, "message": "Etiqueta eliminada correctamente" }
POSTAsignar Etiqueta a Contacto/api/contacts/:id/tags

Asigna una etiqueta existente a un contacto.

Body JSON
CampoTipoRequeridoDescripción
tagIdstringID de la etiqueta a asignar
{ "success": true, "data": { "id": "clxyz123", "tags": [{ "tag": { "id": "tag-abc", "name": "Cliente VIP" } }] }, "message": "Etiqueta asignada correctamente" }
  • 400Esta etiqueta ya está asignada al contacto
DELETERemover Etiqueta de Contacto/api/contacts/:id/tags/:tagId

Remueve una etiqueta asignada a un contacto.

{ "success": true, "data": { "id": "clxyz123", "tags": [] }, "message": "Etiqueta desasignada correctamente" }
GETVerificar Registro en WhatsApp/api/contacts/check/:phone

Verifica si un número está registrado en WhatsApp en tiempo real.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión (debe estar conectada)
{ "success": true, "data": { "phone": "+593991234567", "isRegistered": true } }
GETInfo de Contacto desde WhatsApp/api/contacts/whatsapp/:phone

Obtiene información de un contacto directamente desde WhatsApp (nombre push, ID, etc.).

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
{
  "success": true,
  "data": { "id": "593991234567@c.us", "name": "Juan Pérez", "pushname": "Juancho", "isMyContact": true, "isWAContact": true }
}
GETFoto de Perfil (WhatsApp)/api/contacts/whatsapp/:phone/profile-picture

Foto de perfil de un contacto desde WhatsApp. Consulta caché local primero; si no existe, consulta WhatsApp y actualiza la caché.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
{ "success": true, "data": { "profilePicUrl": "https://pps.whatsapp.net/v/t61.24694-24/abc123.jpg" } }
POSTSincronizar Fotos de Perfil/api/contacts/sync-profile-pictures

Actualiza en batch las fotos de perfil de todos los contactos en BD.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión conectada
{ "success": true, "message": "Fotos sincronizadas", "data": { "updated": 45, "failed": 2, "total": 47 } }
POSTSincronizar Contactos desde WhatsApp/api/contacts/sync/:sessionId

Importa y actualiza la lista de contactos desde WhatsApp hacia la base de datos local.

{
  "success": true,
  "data": { "synced": 120, "created": 15, "updated": 105, "failed": 0 },
  "message": "120 contactos sincronizados (15 nuevos, 105 actualizados, 0 fallidos)"
}
GETDiagnosticar ID de Chat/Contacto/api/contacts/diagnose/:id

Analiza el tipo de un ID de chat o contacto. Útil para depuración y validación de IDs de WhatsApp.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringID de la sesión
{
  "success": true,
  "data": { "id": "593991234567@c.us", "type": "contact", "isValid": true, "phoneNumber": "593991234567", "isGroup": false }
}

✉️ Mensajes

Envío, consulta y gestión de mensajes de WhatsApp almacenados en la base de datos local.

GETListar Mensajes/api/messages

Lista paginada de mensajes en BD con filtros opcionales.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringNoFiltrar por sesión
chatIdstringNoFiltrar por chat (también acepta contactId)
pagenumberNoPágina (default: 1)
limitnumberNoRegistros por página (default: 50)
directionstringNoINBOUND o OUTBOUND
Respuesta 200
{
  "success": true,
  "data": [
    {
      "id": "msg-abc123", "content": "Hola mundo", "direction": "OUTBOUND",
      "type": "TEXT", "isRead": true, "timestamp": "2026-05-26T10:00:00.000Z",
      "contact": { "id": "clxyz123", "name": "Juan Pérez", "phoneNumber": "+593991234567" },
      "session": { "id": "session-abc", "name": "Mi sesión" }
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 200, "totalPages": 4 }
}
POSTEnviar Mensaje/api/messages

Envía un mensaje de texto o multimedia. Usuarios FREE tienen límite diario; usuarios PRO son ilimitados.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
chatIdstringSí*ID del chat o número de teléfono (también acepta phoneNumber)
contentstringSí**Texto del mensaje
mediaUrlstringNoURL de imagen/video/audio o Base64
mediaFilenamestringNoNombre del archivo adjunto
quotedMessageIdstringNoID del mensaje citado (reply)
sendAsVoicebooleanNoEnviar audio como nota de voz
** content o mediaUrl son obligatorios; al menos uno debe estar presente.
Ejemplo
{
  "sessionId": "session-abc123",
  "chatId": "+593991234567",
  "content": "Hola, ¿cómo estás?"
}
Respuesta 201
{
  "success": true,
  "data": { "id": "msg-newxyz", "content": "Hola, ¿cómo estás?", "direction": "OUTBOUND", "type": "TEXT" },
  "message": "Mensaje enviado correctamente"
}
  • 400Sesión no conectada o campos requeridos faltantes
  • 429Límite diario de mensajes alcanzado (usuarios FREE)
GETObtener Mensaje/api/messages/:id

Información detallada de un mensaje por su ID interno.

{
  "success": true,
  "data": {
    "id": "msg-abc123", "content": "Hola mundo", "direction": "OUTBOUND",
    "contact": { "name": "Juan Pérez", "phoneNumber": "+593991234567" }
  }
}
  • 404Mensaje no encontrado
PUTMarcar Mensaje como Leído/api/messages/:id/read

Marca un mensaje como leído en BD (isRead = true).

{ "success": true, "message": "Mensaje marcado como leído" }
DELETEEliminar Mensaje/api/messages/:id

Elimina un mensaje de la BD local permanentemente.

{ "success": true, "message": "Mensaje eliminado correctamente" }
GETEstadísticas de Mensajes/api/messages/stats

Conteos estadísticos con filtros opcionales por sesión, chat y fechas.

Query Params
ParámetroTipoRequeridoDescripción
sessionIdstringNoFiltrar por sesión
chatIdstringNoFiltrar por chat
startDatestringNoFecha inicial ISO 8601
endDatestringNoFecha final ISO 8601
{ "success": true, "data": { "total": 1500, "sent": 900, "received": 600, "unread": 45 } }
POSTEnvío Masivo/api/messages/bulk

Programa el envío de un mensaje a múltiples destinatarios. Se encola y procesa de forma asíncrona.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
contactsarrayArray de números de teléfono (mínimo 1)
contentstringContenido del mensaje
mediaUrlstringNoURL del multimedia a adjuntar
Ejemplo
{
  "sessionId": "session-abc123",
  "contacts": ["+593991234567", "+593987654321"],
  "content": "Hola, tenemos una promoción especial para ti."
}
Respuesta 200
{ "success": true, "message": "Envío masivo programado para 2 contactos", "data": { "totalContacts": 2, "status": "queued" } }
POSTReaccionar a Mensaje/api/messages/:messageId/react

Envía una reacción emoji a un mensaje de WhatsApp. Para eliminar la reacción, envía reaction: "".

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
reactionstringEmoji (ej: "👍", "❤️", "" para eliminar)
{ "success": true, "message": "Reacción enviada correctamente" }
POSTReenviar Mensaje/api/messages/:messageId/forward

Reenvía un mensaje existente a otro chat.

Body JSON
CampoTipoRequeridoDescripción
sessionIdstringID de la sesión
toChatIdstringID del chat destino
{ "success": true, "message": "Mensaje reenviado correctamente" }

📊 Campañas

Gestión completa del ciclo de vida de campañas de envío masivo: creación, destinatarios, control, adjuntos y análisis.

GETListar Campañas/api/campaigns

Lista paginada de campañas con filtros por estado y sesión.

Query Params
ParámetroTipoRequeridoDescripción
statusstringNoDRAFT SCHEDULED RUNNING PAUSED COMPLETED CANCELLED FAILED
sessionIdstringNoFiltrar por sesión
pagenumberNoPágina (default: 1)
limitnumberNoRegistros por página (1–50, default: 20)
{
  "campaigns": [
    { "id": "camp-abc123", "name": "Promo Mayo 2026", "status": "DRAFT", "totalRecipients": 150, "sentCount": 0 }
  ],
  "total": 8, "page": 1, "totalPages": 1
}
GETObtener Campaña/api/campaigns/:id

Detalles y estadísticas de una campaña. Opcionalmente incluye lista previa de destinatarios.

Query Params
ParámetroTipoRequeridoDescripción
includeRecipientsbooleanNoIncluir lista previa de destinatarios
recipientsLimitnumberNoCantidad a incluir (1–100, default: 50)
{
  "id": "camp-abc123", "name": "Promo Mayo 2026", "status": "RUNNING",
  "totalRecipients": 150, "sentCount": 75, "deliveredCount": 70, "readCount": 40, "failedCount": 5
}
POSTCrear Campaña/api/campaigns

Crea una nueva campaña en estado DRAFT. Agrega destinatarios en pasos posteriores.

Body JSON
CampoTipoRequeridoDescripción
namestringNombre descriptivo
sessionIdstringID de la sesión a usar
messageContentstringContenido del mensaje. Soporta variables: {{name}}, {{phone}}
descriptionstringNoDescripción de la campaña
sendingConfigobjectNoConfiguración de envío
Ejemplo
{
  "name": "Promo Junio 2026",
  "sessionId": "session-abc123",
  "messageContent": "Hola {{name}}, tienes un descuento especial.",
  "sendingConfig": { "delaySeconds": 5, "maxRetries": 3 }
}
Respuesta 201
{ "id": "camp-newxyz", "name": "Promo Junio 2026", "status": "DRAFT", "totalRecipients": 0 }
PUTActualizar Campaña/api/campaigns/:id

Actualiza los datos de una campaña. Solo funciona en estado DRAFT.

Body JSON
CampoTipoRequeridoDescripción
namestringNoNuevo nombre
messageContentstringNoNuevo contenido
descriptionstringNoNueva descripción
sendingConfigobjectNoNueva configuración de envío
  • 400Solo se pueden editar campañas en borrador
DELETEEliminar Campaña/api/campaigns/:id

Elimina permanentemente una campaña y todos sus datos. No se pueden eliminar campañas en estado RUNNING.

{ "success": true, "message": "Campaña eliminada exitosamente" }
  • 400No se puede eliminar una campaña en ejecución
POSTIniciar Campaña/api/campaigns/:id/start

Inicia el proceso de envío. La campaña pasa al estado RUNNING.

{ "success": true, "message": "Campaña iniciada" }
POSTPausar Campaña/api/campaigns/:id/pause

Pausa temporalmente el envío. Estado pasa a PAUSED.

{ "success": true, "message": "Campaña pausada" }
POSTReanudar Campaña/api/campaigns/:id/resume

Reanuda el envío de una campaña pausada. Estado vuelve a RUNNING.

{ "success": true, "message": "Campaña reanudada" }
POSTCancelar Campaña/api/campaigns/:id/cancel

Cancela permanentemente. Estado pasa a CANCELLED y no puede reiniciarse.

{ "success": true, "message": "Campaña cancelada" }
POSTProgramar Campaña/api/campaigns/:id/schedule

Programa la campaña para iniciarse automáticamente en una fecha futura.

Body JSON
CampoTipoRequeridoDescripción
startAtstringFecha/hora ISO 8601 (ej: 2026-06-01T09:00:00.000Z)
{ "success": true, "message": "Campaña programada exitosamente" }
POSTCancelar Programación/api/campaigns/:id/cancel-schedule

Cancela la programación, regresando la campaña al estado DRAFT.

{ "success": true, "message": "Programación cancelada" }
POSTAgregar Destinatarios/api/campaigns/:id/recipients

Agrega uno o más destinatarios a una campaña existente.

Body JSON
CampoTipoRequeridoDescripción
recipientsarrayArray de destinatarios con al menos phoneNumber
Ejemplo
{
  "recipients": [
    { "phoneNumber": "+593991234567", "name": "Juan Pérez" },
    { "phoneNumber": "+593987654321", "name": "María García" }
  ]
}
{ "success": true, "message": "Destinatarios agregados correctamente" }
GETListar Destinatarios/api/campaigns/:id/recipients

Lista paginada de destinatarios con filtro por estado de envío.

Query Params
ParámetroTipoRequeridoDescripción
statusstringNoPENDING SENDING SENT DELIVERED READ FAILED SKIPPED
pagenumberNoPágina (default: 1)
limitnumberNoRegistros por página (default: 50)
{
  "recipients": [
    { "id": "recip-abc", "phoneNumber": "+593991234567", "name": "Juan Pérez", "status": "DELIVERED" }
  ],
  "total": 150, "page": 1, "totalPages": 3
}
POSTReintentar Destinatarios Fallidos/api/campaigns/:id/retry-failed

Restablece destinatarios fallidos a PENDING para reintento. Usa /resume después para continuar.

{ "success": true, "message": "12 destinatarios reseteados. Usa /resume para continuar.", "retriedCount": 12 }
GETExportar Resultados/api/campaigns/:id/export

Exporta los resultados como archivo descargable. La respuesta es un archivo binario (Content-Disposition: attachment).

Query Params
ParámetroTipoRequeridoDescripción
formatstringNoexcel (default) o csv
La respuesta es un archivo binario, no JSON.
GETAnalytics Avanzados/api/campaigns/:id/analytics

Métricas avanzadas y análisis de desempeño de la campaña.

{
  "deliveryRate": 95.3, "readRate": 62.1, "failureRate": 4.7, "avgDeliveryTimeMs": 3200,
  "statusBreakdown": { "SENT": 150, "DELIVERED": 143, "READ": 93, "FAILED": 7 }
}
GETMétricas de Performance/api/campaigns/:id/performance

Métricas de rendimiento en tiempo real de una campaña en ejecución.

{ "messagesPerMinute": 12.5, "estimatedTimeRemainingMs": 180000, "progress": 0.5, "currentStatus": "RUNNING" }
GETLogs de Campaña/api/campaigns/:id/logs

Logs de eventos de la campaña, filtrable por severidad.

Query Params
ParámetroTipoRequeridoDescripción
levelstringNoinfo, warn o error
pagenumberNoPágina
limitnumberNoRegistros (default: 100)
{
  "logs": [{ "id": "log-abc", "level": "info", "message": "Mensaje enviado a +593991234567", "timestamp": "2026-05-10T09:05:00.000Z" }],
  "total": 150, "page": 1, "totalPages": 2
}
POSTSubir Adjunto/api/campaigns/:id/attachments

Sube un archivo adjunto a la campaña. Content-Type: multipart/form-data. Tamaño máximo: 10 MB.

Form Data
CampoTipoRequeridoDescripción
filefileArchivo a subir (imagen, video, audio, PDF, Excel, CSV)
messageIndexnumberNoÍndice del mensaje (default: 0)
{ "id": "attach-abc123", "campaignId": "camp-abc123", "filename": "promocion.jpg", "mimeType": "image/jpeg", "size": 204800, "type": "IMAGE" }
GETListar Adjuntos/api/campaigns/:id/attachments

Obtiene la lista de archivos adjuntos de una campaña.

[{ "id": "attach-abc123", "filename": "promocion.jpg", "mimeType": "image/jpeg", "size": 204800, "type": "IMAGE" }]
PATCHActualizar Tipo de Adjunto/api/campaigns/:id/attachments/:attachmentId

Cambia manualmente el tipo de un adjunto cuando la detección automática no es correcta.

Body JSON
CampoTipoRequeridoDescripción
typestringIMAGE, VIDEO, AUDIO o DOCUMENT
{ "id": "attach-abc123", "type": "DOCUMENT", "filename": "contrato.pdf" }
DELETEEliminar Adjunto/api/campaigns/:id/attachments/:attachmentId

Elimina un adjunto de la campaña.

{ "success": true }
POSTReinicializar Campaña/api/campaigns/:id/reinitialize

Reinicializa una campaña completada o cancelada: resetea contadores y destinatarios a PENDING, y cambia a estado DRAFT. Útil para reutilizar una campaña con los mismos destinatarios.

{ "success": true, "message": "Campaña reinicializada exitosamente. Ahora está en estado DRAFT y lista para volver a ejecutarse." }

📱 Sesiones

Gestión del ciclo de vida de sesiones de WhatsApp: creación, conexión, QR, pairing code y eliminación.

GETListar Sesiones/api/sessions

Obtiene todas las sesiones del usuario con su estado actual.

{
  "success": true,
  "data": [
    { "id": "session-abc123", "name": "Mi negocio", "status": "connected", "phoneNumber": "+593991234567" }
  ]
}
Estados posibles: connected, disconnected, connecting, qr_code, pairing_code_requested
GETEstado de Sesiones Activas/api/sessions/status

Conteo y lista de sesiones actualmente conectadas.

{ "success": true, "data": { "activeCount": 2, "activeSessions": [{ "id": "session-abc123", "name": "Mi negocio", "status": "connected" }] } }
POSTCrear Sesión/api/sessions

Crea una nueva sesión de WhatsApp. Plan FREE: 1 sesión. Planes PRO: hasta 10.

Body JSON
CampoTipoRequeridoDescripción
namestringNombre descriptivo de la sesión
{ "success": true, "data": { "id": "session-newxyz", "name": "Tienda Norte", "status": "disconnected" }, "message": "Sesión creada correctamente" }
  • 403Límite de sesiones excedido para el plan actual
GETObtener Sesión/api/sessions/:id

Datos de una sesión específica por su ID.

{ "success": true, "data": { "id": "session-abc123", "name": "Mi negocio", "status": "connected", "phoneNumber": "+593991234567" } }
GETEstado de Sesión/api/sessions/:id/status

Estado actual de una sesión específica.

{ "success": true, "data": { "id": "session-abc123", "status": "connected", "phoneNumber": "+593991234567" } }
GETObtener QR Code/api/sessions/:id/qr

QR code para vincular WhatsApp. Solo disponible después de llamar a /connect.

{ "success": true, "data": { "qrCode": "data:image/png;base64,iVBORw0KGgo...", "sessionId": "session-abc123" } }
  • 400QR no disponible (sesión no está en espera de QR)
POSTConectar Sesión/api/sessions/:id/connect

Inicia el proceso de conexión. Genera un QR disponible en /qr para escanear con WhatsApp móvil.

{ "success": true, "message": "Conexión iniciada. Escanea el QR code cuando aparezca.", "data": { "status": "connecting" } }
  • 400La sesión ya está conectada
POSTDesconectar Sesión/api/sessions/:id/disconnect

Desconecta la sesión sin eliminarla ni cerrar sesión en WhatsApp.

{ "success": true, "message": "Sesión desconectada", "data": { "status": "disconnected" } }
POSTReiniciar Sesión/api/sessions/:id/restart

Reinicia el cliente de WhatsApp sin hacer logout. Mantiene la autenticación y reconecta automáticamente sin nuevo QR.

{ "success": true, "data": { "status": "connected" } }
POSTSolicitar Pairing Code/api/sessions/:id/pairing-code

Solicita un código de 8 caracteres para vincular WhatsApp sin QR. El código aparece en la app móvil: Configuración → Dispositivos vinculados → Vincular con número.

Body JSON
CampoTipoRequeridoDescripción
phoneNumberstringNúmero en formato internacional sin + (ej: 5939XXXXXXXX)
{ "success": true, "message": "Pairing code solicitado. Revisa tu WhatsApp móvil.", "data": { "status": "pairing_code_requested" } }
DELETEEliminar Sesión/api/sessions/:id

Elimina permanentemente la sesión incluyendo datos de autenticación. No puede deshacerse.

{ "success": true, "message": "Sesión eliminada correctamente" }

🔔 Webhooks

Registro y gestión de webhooks para recibir notificaciones de eventos de WhatsApp en tiempo real en una URL externa.

GETListar Webhooks/api/webhook

Obtiene todos los webhooks registrados, ordenados por fecha de creación.

{
  "success": true,
  "data": [
    {
      "id": "wh-abc123", "name": "Mi servidor",
      "url": "https://mi-servidor.com/webhook",
      "events": ["message:received", "session:disconnected"],
      "isActive": true, "failureCount": 0
    }
  ]
}
sessionIds vacío significa que el webhook recibe eventos de todas las sesiones.
POSTCrear Webhook/api/webhook

Registra un nuevo webhook para recibir notificaciones de eventos de WhatsApp.

Body JSON
CampoTipoRequeridoDescripción
namestringNombre descriptivo
urlstringURL pública de destino
eventsarrayArray de eventos a escuchar
sessionIdsarrayNoIDs de sesiones a filtrar (vacío = todas)
secretstringNoClave para firma X-Massiva-Signature
Eventos disponibles
EventoDescripción
message:receivedMensaje entrante recibido
message:sentMensaje enviado confirmado
message:deliveredMensaje entregado al destinatario
message:readMensaje leído por el destinatario
session:connectedSesión conectada a WhatsApp
session:disconnectedSesión desconectada
session:qrNuevo QR code generado
Ejemplo
{
  "name": "CRM Integration",
  "url": "https://mi-crm.com/api/webhooks/massiva",
  "events": ["message:received", "session:disconnected"],
  "sessionIds": ["session-abc123"],
  "secret": "mi-clave-secreta-segura"
}
Respuesta 200
{
  "success": true,
  "data": { "id": "wh-newxyz", "name": "CRM Integration", "url": "https://mi-crm.com/api/webhooks/massiva", "isActive": true }
}
PUTActualizar Webhook/api/webhook/:id

Actualiza la configuración de un webhook. Solo se actualizan los campos enviados.

Body JSON
CampoTipoRequeridoDescripción
namestringNoNuevo nombre
urlstringNoNueva URL
eventsarrayNoNueva lista de eventos
isActivebooleanNoActivar/desactivar. Al reactivar se resetea el contador de fallos
secretstringNoNueva clave secreta
{ "success": true, "data": { "id": "wh-abc123", "name": "CRM Actualizado", "isActive": true, "failureCount": 0 } }
DELETEEliminar Webhook/api/webhook/:id

Elimina permanentemente un webhook registrado.

{ "success": true }
POSTProbar Webhook/api/webhook/:id/test

Envía un evento de prueba (test.event) a la URL del webhook para verificar conectividad.

Respuesta 200
{ "success": true, "message": "Test event queued" }
Payload enviado al webhook
{
  "event": "test.event",
  "data": { "message": "This is a test event from Massiva", "triggeredBy": "user-id" },
  "timestamp": "2026-05-26T10:00:00.000Z"
}
  • 404Webhook no encontrado
¿Necesitas más ayuda?

Revisa el API Tester integrado en la aplicación o contáctanos.