Documentación de la API
Guía completa para integración con la API de Zapini
URL Base
https://instance-{id}.zapini.app
Autenticación
Bearer Token (Sanctum)
Rate Limit
100 requests / 15 min
Primeros Pasos
La API REST de Zapini le permite integrar capacidades de mensajería de WhatsApp en sus aplicaciones. Todas las solicitudes deben usar HTTPS e incluir autenticación Bearer token.
Tipos de API
Zapini ofrece dos tipos de API para diferentes necesidades. Elige la que mejor se adapte a tu caso de uso.
API Universal
https://instance-{id}.zapini.app
API REST completa para gestionar todas tus instancias, conversaciones, contactos y configuraciones. Usa esta API para aplicaciones web/móviles que necesitan acceso completo al sistema.
API de Instancia
https://instance-{id}.zapini.app/
API directa para enviar mensajes con baja latencia. Cada instancia de WhatsApp tiene su propia URL dedicada. Ideal para bots y automatizaciones de alto volumen.
¿Qué API debo usar?
| Caso de Uso | API Recomendada |
|---|---|
| Aplicación web/móvil | Universal (Token Sanctum) |
| Bot de mensajes | Instancia (Token sk_) |
| CRM / Sistema de soporte | Universal (Token Sanctum) |
| Envío masivo / campañas | Instancia (Token sk_) |
| Integración externa simple | Instancia (Token sk_) |
ID de Instancia
El UUID de la instancia (usado en la API Universal) se puede encontrar en la página de Instancias del panel administrativo. Copia el ID mostrado en cada tarjeta de instancia.
Headers Requeridos
Authorization: Bearer {token}
Accept: application/json
Content-Type: application/json
Formato de Respuesta
Respuesta Exitosa
{
"success": true,
"message": "Operation completed",
"data": { ... }
}
Respuesta de Error
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Error description",
"details": {}
}
}
Códigos HTTP
| Código | Descripción |
|---|---|
| 200 | OK - Solicitud exitosa |
| 201 | Created - Recurso creado exitosamente |
| 400 | Bad Request - Parámetros inválidos |
| 401 | Unauthorized - Token inválido o ausente |
| 403 | Forbidden - Sin permiso para este recurso |
| 404 | Not Found - Recurso no encontrado |
| 422 | Unprocessable Entity - Error de validación |
| 429 | Too Many Requests - Límite de solicitudes excedido |
| 500 | Internal Server Error - Error interno del servidor |
Autenticación
Tipos de Token
Hay dos tipos de tokens de autenticación, cada uno adecuado para diferentes escenarios.
Token Sanctum
Token de usuario obtenido via login. Da acceso a todas las instancias y recursos de tu tenant. Ideal para aplicaciones web/móviles donde el usuario inicia sesión.
- • Cómo obtener: POST /auth/login con email y contraseña
- • Formato: 1|abc123xyz...
- • Acceso: Todas las instancias del tenant
Token de Instancia (sk_)
Token específico de una instancia de WhatsApp. Generado en el panel administrativo. Ideal para integraciones externas y bots.
- • Cómo obtener: Generar en panel en Instancias > Tokens API
- • Formato: sk_xxxxxxxxxxxxxxxx
- • Acceso: Solo la instancia específica
Ambos tokens funcionan de la misma manera en el header Authorization:
Authorization: Bearer {token}
/auth/login
Autentica un usuario y devuelve un token de acceso.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
email |
string | Sí | Email del usuario |
password |
string | Sí | Contraseña del usuario |
device_name |
string | No | Nombre del dispositivo para identificación del token |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/auth/login \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password",
"device_name": "My App"
}'
Respuesta
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": 1,
"name": "User Name",
"email": "user@example.com",
"role": "admin"
},
"token": "1|abc123xyz...",
"token_type": "Bearer"
}
}
/auth/me
Devuelve información del usuario autenticado.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/auth/me \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/auth/logout
Revoca el token de acceso actual.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/auth/logout \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/auth/refresh
Actualiza el token de acceso.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/auth/refresh \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Instancias
/instances
Lista todas las instancias de WhatsApp en su cuenta.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
status |
string | connected, disconnected, qr_ready, pending |
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/instances?status=connected" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": {
"instances": [
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"phone_number": "5511999999999",
"status": "connected",
"connected": true,
"messages_sent_today": 50,
"remaining_quota": 450,
"can_send_messages": true,
"last_activity_at": "2025-01-15T10:30:00Z"
}
]
}
}
/instances/{uuid}
Devuelve detalles de una instancia específica.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/instances/{uuid}/qr
Devuelve el código QR para conectar la instancia.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000/qr \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": {
"status": "qr_ready",
"qr_code": "data:image/png;base64,...",
"qr_code_text": "2@...",
"qr_generated_at": "2025-01-15T10:30:00Z",
"qr_expired": false,
"message": "QR code ready to scan"
}
}
/instances/{uuid}/status
Devuelve el estado actual de la instancia.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
realtime |
boolean | Si es true, verifica el estado en tiempo real en el servidor |
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000/status?realtime=true" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/instances/{uuid}/stats
Devuelve estadísticas de uso de la instancia.
Respuesta
{
"success": true,
"data": {
"messages_sent_today": 50,
"remaining_quota": 450,
"daily_limit": 500,
"messages_this_week": 200,
"messages_this_month": 800,
"messages_received_today": 30,
"conversations_count": 150,
"contacts_count": 500
}
}
/instances/{uuid}/disconnect
Desconecta la instancia de WhatsApp.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000/disconnect \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/instances/{uuid}/reconnect
Inicia el proceso de reconexión de la instancia.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000/reconnect \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Mensajes
API de Instancia (Baileys)
API directa para enviar mensajes con baja latencia. Cada instancia de WhatsApp tiene su propia URL dedicada. Ideal para bots y automatizaciones de alto volumen.
Base URL:
https://instance-{id}.zapini.app
API Universal - /chat/send
Para enviar mensagens via API Universal, use o endpoint /chat/send (consulte a aba Chat API).
/send-message
Envía un mensaje de texto a un número de WhatsApp.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
recipient
(ou number, to)
|
string | Sí | Número de WhatsApp del destinatario (con código de país) (5511999999999) |
message |
string | Sí | Contenido del mensaje de texto |
reply_to
(ou quoted_message_id)
|
string | No | ID del mensaje para responder |
recipient, number e to são equivalentes.
Assim como reply_to e quoted_message_id.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/send-message \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"recipient": "5511999999999",
"message": "Olá! Esta é uma mensagem de teste."
}'
Respuesta
{
"success": true,
"message": "Message sent successfully",
"message_id": "3EB0B430A8B7F23C1D12",
"timestamp": "2025-12-30T17:30:00.000Z"
}
/send-media
Envía un mensaje con medios (imagen, video, audio, documento).
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
recipient
(ou number, to)
|
string | Sí | Número de WhatsApp del destinatario (con código de país) (5511999999999) |
media_url
(ou url)
|
string | Sí | URL pública del archivo de medios |
media_type
(ou type)
|
string | Sí | image, video, audio, document |
caption |
string | No | Leyenda para imágenes y videos |
filename |
string | No | Nombre del archivo para documentos |
recipient/number/to,
media_url/url e
media_type/type são equivalentes.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/send-media \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"recipient": "5511999999999",
"media_url": "https://example.com/image.jpg",
"media_type": "image",
"caption": "Confira esta imagem!"
}'
Respuesta
{
"success": true,
"message": "Media sent successfully",
"message_id": "3EB0B430A8B7F23C1D13",
"timestamp": "2025-12-30T17:30:00.000Z"
}
/send-reaction
Envía un emoji de reacción a un mensaje específico.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
to |
string | Sí | JID do chat |
messageId |
string | Sí | ID da mensagem para reagir |
emoji |
string | Sí | Emoji da reação (ex: 👍, ❤️, 😂) |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/send-reaction \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"to": "5511999999999@s.whatsapp.net",
"messageId": "3EB0B430A8B7F23C1D12",
"emoji": "👍"
}'
/status
Devuelve el estado actual de conexión de la instancia de WhatsApp.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/status \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"status": "connected",
"phone": "5511999999999",
"name": "Meu WhatsApp",
"platform": "android"
}
/qr
Devuelve el código QR para conectar la instancia de WhatsApp. Solo disponible cuando el estado es qr_ready.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/qr \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"qr": "data:image/png;base64,iVBORw0KGgoAAAA...",
"status": "qr_ready"
}
/health
Devuelve el estado de salud del servidor de la API. No requiere autenticación.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/health
Respuesta
{
"status": "ok",
"uptime": 123456,
"timestamp": "2025-12-15T14:30:00.000Z"
}
Conversaciones
/conversations
Lista todas las conversaciones activas.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
instance_id |
string | Filtrar por instancia (UUID) |
unread |
boolean | Mostrar solo conversaciones no leídas |
search |
string | Buscar por nombre o número |
is_group |
boolean | Filtrar por grupos (true/false) |
per_page |
integer | Items por página (máx 100) |
include_tags |
boolean | Incluir tags de la conversación en la respuesta |
tag_id |
uuid | Filtrar por ID de etiqueta |
tag_ids |
uuid[] | Filtrar por múltiples UUIDs de etiquetas (separados por coma o array) |
untagged |
boolean | Mostrar solo conversaciones sin etiquetas |
format |
string | Usar formato de respuesta optimizado para chat (chat) |
?format=chat: La Chat API devuelve los mismos datos que los endpoints estándar, pero con campos adicionales optimizados para renderizado de UI. También puede usar ?format=chat en los endpoints estándar.
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/conversations?unread=true&per_page=20" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440045",
"contact_number": "5511999999999",
"contact_name": "John Doe",
"display_name": "John Doe",
"is_group": false,
"profile_picture_url": "https://...",
"last_message": "Ok, deal!",
"last_message_at": "2025-01-15T10:30:00Z",
"unread_count": 2,
"is_archived": false
}
],
"meta": {
"pagination": {
"total": 100,
"per_page": 20,
"current_page": 1,
"last_page": 5
}
}
}
/conversations/{uuid}
Devuelve detalles de una conversación específica.
/conversations/{uuid}/messages
Devuelve el historial de mensajes de una conversación.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
from |
datetime | Fecha inicial (ISO 8601) |
to |
datetime | Fecha final (ISO 8601) |
before_id |
integer | Mensajes antes de este ID |
after_id |
integer | Mensajes después de este ID |
limit |
integer | Límite de mensajes (máx 100) |
format |
string | Usar formato de respuesta optimizado para chat (chat) |
?format=chat: Devuelve mensajes con formatted_body (@menciones resueltas) y reacciones agrupadas.
/conversations/{uuid}/mark-read
Marca una conversación como leída.
/conversations/{uuid}/archive
Archiva una conversación.
Respuesta
{
"success": true,
"message": "Conversation archived.",
"data": {
"archived_id": "550e8400-e29b-41d4-a716-446655440045",
"archived_at": "2025-12-29T12:00:00.000000Z"
}
}
/conversations/{uuid}/archive
Restaura una conversación archivada a estado activo.
El UUID debe ser de una conversación archivada. Use GET /conversations/archived para listar conversaciones archivadas.
Respuesta
{
"success": true,
"message": "Conversation restored.",
"data": {
"conversation_id": "550e8400-e29b-41d4-a716-446655440045",
"restored": true
}
}
/conversations/{uuid}
Elimina una conversación y sus mensajes.
Control de Automatización
Gestione la automatización de IA para conversaciones. Cuando la automatización está activa, los mensajes manuales están bloqueados hasta que asuma el chat.
Importante: Comportamiento de la Automatización
- Cuando la automatización está activa, los mensajes manuales están bloqueados para evitar conflictos con las respuestas de IA.
- Use "pause" para asumir el chat y enviar mensajes manualmente.
- Use "resume" para dejar que la IA maneje la conversación nuevamente.
- IMPORTANTE: Para reanudar la automatización, primero debe archivar la conversación.
Seguridad: Archivo Requerido para Reanudar
La automatización solo puede reanudarse después de archivar la conversación. Esto asegura que la sesión de servicio manual se cierre correctamente antes de devolver el control a la IA. Al reanudar, la conversación se desarchivará automáticamente.
/conversations/{uuid}/automation
Devuelve el estado actual de la automatización para una conversación.
Respuesta
{
"success": true,
"data": {
"conversation_id": "550e8400-e29b-41d4-a716-446655440045",
"automation_status": "active",
"is_automation_active": true,
"can_send_manual_message": false,
"paused_at": null,
"paused_by": null,
"pause_reason": null
}
}
/conversations/{uuid}/automation/pause
Pausa la automatización para una conversación, permitiendo mensajes manuales.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
reason |
string | No | Razón opcional para pausar la automatización |
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/conversations/550e8400-e29b-41d4-a716-446655440045/automation/pause" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"reason": "Manual takeover for VIP client"}'
Respuesta
{
"success": true,
"message": "Automation paused. You can now send messages manually.",
"data": {
"automation_status": "paused",
"paused_at": "2025-12-20T14:30:00Z",
"paused_by": "John Doe"
}
}
/conversations/{uuid}/automation/resume
Reanuda la automatización para una conversación, dejando que la IA maneje las respuestas.
Respuesta
{
"success": true,
"message": "Automation resumed. AI will handle this conversation.",
"data": {
"automation_status": "active"
}
}
/conversations/automation/bulk-pause
Pausa la automatización para múltiples conversaciones a la vez.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
conversation_ids |
array | Sí | Array de IDs de conversaciones a procesar |
reason |
string | No | Razón opcional para pausar la automatización |
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/conversations/automation/bulk-pause" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"conversation_ids": ["550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002", "550e8400-e29b-41d4-a716-446655440003"]}'
Respuesta
{
"success": true,
"message": "3 conversations paused successfully."
}
/conversations/automation/bulk-resume
Reanuda la automatización para múltiples conversaciones a la vez.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
conversation_ids |
array | Sí | Array de IDs de conversaciones a procesar |
Respuesta
{
"success": true,
"message": "3 conversations resumed successfully."
}
Contactos
/contacts
Lista todos los contactos guardados.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
instance_id |
string | Filtrar por instancia (UUID) |
search |
string | Buscar por nombre o número |
per_page |
integer | Items por página (máx 100) |
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/contacts?search=john&per_page=50" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": [
{
"id": 1,
"phone_number": "5511999999999",
"name": "John Doe",
"display_name": "John",
"email": "john@example.com",
"company": "Acme Inc",
"notes": "VIP customer",
"profile_picture_url": "https://...",
"is_business": false,
"created_at": "2025-01-15T10:30:00Z"
}
],
"meta": {
"pagination": {
"total": 500,
"per_page": 50,
"current_page": 1,
"last_page": 10
}
}
}
/contacts
Crea un nuevo contacto.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
instance_id |
string | Sí | ID da instância |
phone_number |
string | Sí | Número de teléfono del contacto |
name |
string | No | Nombre del contacto |
email |
string | No | Email del contacto |
company |
string | No | Empresa del contacto |
notes |
string | No | Notas sobre el contacto |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/contacts \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "550e8400-e29b-41d4-a716-446655440000",
"phone_number": "+5511999999999",
"name": "John Doe",
"email": "john@example.com",
"company": "Acme Inc",
"notes": "Met at conference"
}'
/contacts/{id}
Devuelve detalles de un contacto específico.
/contacts/{id}
Actualiza un contacto existente.
Parámetros
| Campo | Tipo | Descripción |
|---|---|---|
name |
string | Nombre del contacto |
email |
string | Email del contacto |
company |
string | Empresa del contacto |
notes |
string | Notas sobre el contacto |
/contacts/{id}
Elimina un contacto.
/contacts/import
Importa múltiples contactos a la vez.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
instance_id |
string | Sí | ID da instância |
contacts |
array | Sí | Array de objetos de contacto |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/contacts/import \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "550e8400-e29b-41d4-a716-446655440000",
"contacts": [
{"phone_number": "+5511999999999", "name": "John Doe"},
{"phone_number": "+5511888888888", "name": "Jane Smith"}
]
}'
Respuesta
{
"success": true,
"message": "Contacts imported successfully",
"data": {
"imported": 2,
"skipped": 0,
"errors": []
}
}
/contacts/export
Exporta contactos en formato JSON o CSV.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
instance_id |
string | Filtrar por instancia (UUID) |
format |
string | json, csv (default: json) |
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/contacts/export?format=csv" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Webhooks
Sistema de Webhooks
Los webhooks le permiten recibir notificaciones en tiempo real sobre eventos en sus instancias de WhatsApp.
Webhooks de Entrada
URLs que Zapini usa para recibir datos de sus instancias WhatsApp.
Webhooks de Salida
URLs que usted configura para recibir notificaciones de Zapini.
Webhooks de Salida
Recibe notificaciones en tiempo real en tu servidor
Configura webhooks para recibir notificaciones en tiempo real cuando ocurran eventos en tu instancia de WhatsApp. Zapini enviará solicitudes HTTP POST a tu URL configurada con los datos del evento.
Cómo Configurar
- Ve a la configuración de tu Token de API y haz clic en "Configurar Webhook"
- Ingresa tu URL de webhook (debe ser HTTPS en producción)
- Genera o ingresa una clave secreta para verificación de firma
- Selecciona qué eventos deseas recibir y guarda
Eventos Disponibles
| Evento | Descripción |
|---|---|
message.received |
Nuevo mensaje recibido |
message.sent |
Mensaje enviado |
message.status |
Estado del mensaje cambiado (enviado, entregado, leído) |
instance.connected |
Instancia conectó a WhatsApp |
instance.disconnected |
Instancia desconectó |
instance.qr |
Nuevo código QR generado |
Entendiendo los IDs de Mensaje
Cada mensaje tiene dos identificadores. Usa el correcto según tu caso de uso:
| Campo | Formato | Uso |
|---|---|---|
message_id |
UUID (e.g., 055f01b2-da7b-476b-...) |
Clave primaria para deduplicación y seguimiento en tu sistema |
whatsapp_message_id |
WhatsApp ID (e.g., 3EB0ABC123456789) |
Requerido para reacciones, respuestas y operaciones de WhatsApp |
Tip: Cómo evitar duplicados
Almacena el message_id cuando recibas un webhook. Antes de procesar nuevos webhooks, verifica si el message_id ya existe en tu base de datos. Si existe, actualiza el registro existente en lugar de crear uno nuevo.
Formato de Solicitud
Cada solicitud de webhook se envía como HTTP POST con los siguientes headers:
POST https://your-server.com/webhook
Content-Type: application/json
X-Webhook-Signature: a1b2c3d4e5f6...
X-Webhook-Event: message.received
X-Instance-UUID: 550e8400-e29b-41d4-a716-446655440000
User-Agent: Zapini-Webhook/1.0
Headers del Webhook
| Header | Descripción |
|---|---|
X-Webhook-Signature |
Firma HMAC-SHA256 del payload JSON usando tu clave secreta |
X-Webhook-Event |
El tipo de evento que disparó este webhook |
X-Instance-UUID |
UUID de la instancia de WhatsApp |
User-Agent |
Zapini-Webhook/1.0 |
Ejemplos de Payload
message.received
{
"event": "message.received",
"instance_uuid": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:30:00+00:00",
"data": {
"message_id": "055f01b2-da7b-476b-9a5d-dcecb3fe510c",
"whatsapp_message_id": "3EB0ABC123456789",
"sender_number": "5511999999999",
"sender_name": "John Doe",
"content": "Hello, I need help!",
"media_type": null,
"media_url": null,
"timestamp": "2025-01-15T10:30:00+00:00",
"conversation_id": 123
}
}
message.sent
{
"event": "message.sent",
"instance_uuid": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:31:00+00:00",
"data": {
"message_id": "f4a2e8c9-7b3d-4e5f-8a1c-2d9e6f0a3b7c",
"whatsapp_message_id": "3EB0ABC123456789",
"recipient_number": "5511888888888",
"content": "Thanks for contacting us!",
"media_type": null,
"media_url": null,
"timestamp": "2025-01-15T10:31:00+00:00",
"conversation_id": 123
}
}
message.status
{
"event": "message.status",
"instance_uuid": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:32:00+00:00",
"data": {
"message_id": "f4a2e8c9-7b3d-4e5f-8a1c-2d9e6f0a3b7c",
"whatsapp_message_id": "3EB0ABC123456789",
"previous_status": "sent",
"new_status": "delivered",
"recipient_number": "5511888888888",
"timestamp": "2025-01-15T10:32:00+00:00"
}
}
instance.connected
{
"event": "instance.connected",
"instance_uuid": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:00:00+00:00",
"data": {
"previous_status": "qr_ready",
"new_status": "connected",
"phone_number": "5511999999999"
}
}
/webhooks/instance/{uuid}/incoming
Recibe mensajes entrantes de las instancias WhatsApp.
Formato del Payload
{
"remoteJid": "5511999999999@s.whatsapp.net",
"message": {
"conversation": "Hello, how are you?",
"extendedTextMessage": null,
"imageMessage": null,
"videoMessage": null,
"audioMessage": null,
"documentMessage": null
},
"messageTimestamp": 1705312200,
"pushName": "John Doe",
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "3EB0ABC123456789"
},
"participant": null,
"isGroup": false
}
Tipos de Mensaje
| Tipo | Campo | Descripción |
|---|---|---|
| Text | message.conversation |
Mensaje de texto simple |
| Extended Text | message.extendedTextMessage |
Texto con vista previa de enlace |
| Image | message.imageMessage |
Imagen con leyenda |
| Video | message.videoMessage |
Mensaje de video |
| Audio | message.audioMessage |
Mensaje de audio/voz |
| Document | message.documentMessage |
Archivo/documento |
Ejemplo - Mensaje de Texto
curl -X POST https://zapini.app/webhooks/instance/{uuid}/incoming \
-H "Content-Type: application/json" \
-d '{
"remoteJid": "5511999999999@s.whatsapp.net",
"message": {
"conversation": "Hello!"
},
"messageTimestamp": 1705312200,
"pushName": "Customer Name",
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "ABC123"
}
}'
/webhooks/instance/{uuid}/status
Recibe actualizaciones de estado de mensajes enviados.
Formato del Payload
{
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"id": "3EB0ABC123456789",
"fromMe": true
},
"status": 3,
"messageTimestamp": 1705312200
}
Códigos de Estado
| Código | Status | Descripción |
|---|---|---|
1 |
pending | Mensaje pendiente de envío |
2 |
sent | Mensaje enviado al servidor |
3 |
delivered | Mensaje entregado al destinatario |
4 |
read | Mensaje leído por el destinatario |
5 |
played | Audio/video reproducido |
/webhooks/instance/{uuid}/qr
Recibe actualizaciones de código QR para conexión.
Formato del Payload
{
"qr": "2@ABC123...",
"qr_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
"generated_at": "2025-01-15T10:30:00Z"
}
/webhooks/instance/{uuid}/connection
Recibe actualizaciones del estado de conexión de la instancia.
Formato del Payload
{
"status": "connected",
"phone_number": "5511999999999",
"timestamp": "2025-01-15T10:30:00Z"
}
Estados de Conexión
| Status | Descripción |
|---|---|
| connected | Instancia conectada y funcionando |
| qr_ready | Código QR listo para escanear |
| disconnected | Instancia desconectada |
| offline | Instancia offline |
/webhooks/instance/{uuid}/reaction
Recibe reacciones emoji en mensajes.
Formato del Payload
{
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"id": "3EB0ABC123456789",
"fromMe": false
},
"reaction": {
"text": "👍",
"key": {
"id": "3EB0DEF987654321"
}
},
"senderJid": "5511888888888@s.whatsapp.net"
}
/instances/{uuid}/webhook
Configure una URL externa para recibir notificaciones de eventos.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
webhook_url |
string | Sí | URL que recibirá las notificaciones vía POST |
webhook_secret |
string | No | Clave secreta para firma de solicitudes |
events |
array | No | Eventos que dispararán el webhook |
is_active |
boolean | No | Activar o desactivar el webhook |
Eventos Disponibles
Ejemplo
curl -X PUT https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000/webhook \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-server.com/webhook",
"webhook_secret": "your_secret_key_here",
"events": ["message.incoming", "message.status"],
"is_active": true
}'
Seguridad de Webhooks
Todas las solicitudes de webhook incluyen una firma HMAC para verificación de autenticidad.
Verificación de Firma
Cada solicitud incluye un header X-Webhook-Signature con la firma HMAC-SHA256 del payload.
Header:
X-Webhook-Signature: a1b2c3d4e5f6789...
Verificar Firma (PHP)
<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = 'your_webhook_secret';
$expected = hash_hmac('sha256', $payload, $secret);
if (hash_equals($expected, $signature)) {
// Signature is valid
$data = json_decode($payload, true);
// Process webhook...
} else {
http_response_code(401);
exit('Invalid signature');
}
Verificar Firma (Node.js)
const crypto = require('crypto');
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const secret = 'your_webhook_secret';
const payload = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)) {
// Signature is valid
console.log('Webhook received:', req.body);
res.status(200).send('OK');
} else {
res.status(401).send('Invalid signature');
}
});
Buenas Prácticas
- Siempre verifique la firma antes de procesar el webhook.
- Responda rápidamente (dentro de 5 segundos) para evitar timeouts.
- Use una cola para procesar webhooks de forma asíncrona.
- Implemente idempotencia para manejar webhooks duplicados.
- Registre todos los webhooks recibidos para depuración.
Medios
Gestión de Medios
Envíe y gestione archivos de medios como imágenes, videos, audios y documentos.
/media/upload
Sube un archivo de medios para uso posterior.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
file |
file | Sí | Archivo de medios para subir (multipart/form-data) |
type |
string | No | image, video, audio, document (auto-detected) |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/media/upload \
-H "Authorization: Bearer {token}" \
-F "file=@/path/to/image.jpg" \
-F "type=image"
Respuesta
{
"success": true,
"data": {
"id": "media_abc123xyz",
"url": "https://storage.zapini.app/media/abc123xyz.jpg",
"type": "image",
"mime_type": "image/jpeg",
"size": 102400,
"filename": "image.jpg",
"expires_at": "2025-01-22T10:30:00Z"
}
}
/media/{id}
Devuelve información de un archivo de medios.
Respuesta
{
"success": true,
"data": {
"id": "media_abc123xyz",
"url": "https://storage.zapini.app/media/abc123xyz.jpg",
"type": "image",
"mime_type": "image/jpeg",
"size": 102400,
"filename": "image.jpg",
"created_at": "2025-01-15T10:30:00Z",
"expires_at": "2025-01-22T10:30:00Z"
}
}
/media/{id}
Elimina un archivo de medios.
Ejemplo
curl -X DELETE https://instance-{id}.zapini.app/media/media_abc123xyz \
-H "Authorization: Bearer {token}"
/messages/send-media
Envía un mensaje con medios adjuntos.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
instance_id |
string | Sí | ID da instância |
recipient |
string | Sí | Número de WhatsApp del destinatario (con código de país) |
media_url |
string | Sí* | URL pública del archivo de medios |
media_id |
string | Sí* | ID de un medio previamente subido |
media_type |
string | Sí | image, video, audio, document |
caption |
string | No | Leyenda para imágenes y videos |
filename |
string | No | Nombre del archivo para documentos |
* Proporcione media_url O media_id
Ejemplo - Imagen
curl -X POST https://instance-{id}.zapini.app/messages/send-media \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient": "+5511999999999",
"media_url": "https://example.com/image.jpg",
"media_type": "image",
"caption": "Check this image!"
}'
Ejemplo - Documento
curl -X POST https://instance-{id}.zapini.app/messages/send-media \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient": "+5511999999999",
"media_url": "https://example.com/report.pdf",
"media_type": "document",
"filename": "Monthly_Report.pdf",
"caption": "Here is the monthly report"
}'
Límites de Medios
| Tipo | Tamaño Máximo | Formatos |
|---|---|---|
| Imágenes | 16 MB | jpg, jpeg, png, gif, webp |
| Videos | 64 MB | mp4, 3gp, mov, avi, mkv |
| Audio | 16 MB | mp3, ogg, wav, opus, aac, m4a |
| Documentos | 100 MB | pdf, doc, docx, xls, xlsx, ppt, pptx, txt, zip |
/messages/{uuid}/media
Descarga medios recibidos en un mensaje.
Ejemplo
curl -X GET https://instance-{id}.zapini.app/messages/660e8400-e29b-41d4-a716-446655440001/media \
-H "Authorization: Bearer {token}" \
--output downloaded_media.jpg
Respuesta
Devuelve el archivo binario con el Content-Type apropiado.
Grupos
Gestione grupos de WhatsApp a través de la API. Cree grupos, agregue/elimine participantes, actualice configuraciones y más.
/instances/{uuid}/groups
Devuelve todos los grupos de WhatsApp de la instancia.
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/instances/{uuid}/groups" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": {
"groups": [
{
"jid": "120363001234567890@g.us",
"subject": "Marketing Team",
"owner": "5511987654321@s.whatsapp.net",
"size": 25,
"description": "Team discussions"
}
],
"total": 5
}
}
/instances/{uuid}/groups
Crea un nuevo grupo de WhatsApp.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
subject |
string | Sí | api-docs.group_subject_desc |
participants |
array | Sí | api-docs.group_participants_desc |
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/instances/{uuid}/groups" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"subject": "My New Group",
"participants": ["5511987654321", "5511976543210"]
}'
Respuesta
{
"success": true,
"data": {
"group": {
"jid": "120363001234567890@g.us",
"subject": "My New Group"
},
"message": "Group created successfully"
}
}
/instances/{uuid}/groups/{jid}
Devuelve metadatos detallados de un grupo específico.
Respuesta
{
"success": true,
"data": {
"jid": "120363001234567890@g.us",
"subject": "Marketing Team",
"description": "Team discussions",
"owner": "5511987654321@s.whatsapp.net",
"participants": [
{"jid": "5511987654321@s.whatsapp.net", "admin": "superadmin"},
{"jid": "5511976543210@s.whatsapp.net", "admin": null}
],
"size": 25
}
}
/instances/{uuid}/groups/{jid}
Actualiza el nombre y/o descripción del grupo.
Cuerpo de la Solicitud
| Campo | Tipo | Descripción |
|---|---|---|
subject |
string | Nuevo nombre del grupo |
description |
string | Nueva descripción del grupo |
Ejemplo
curl -X PATCH "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"subject": "New Group Name",
"description": "Updated description"
}'
/instances/{uuid}/groups/{jid}/participants
Agrega uno o más participantes al grupo.
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}/participants" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"participants": ["5511987654321", "5511976543210"]
}'
/instances/{uuid}/groups/{jid}/participants
Elimina uno o más participantes del grupo.
Ejemplo
curl -X DELETE "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}/participants" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"participants": ["5511987654321"]
}'
/instances/{uuid}/groups/{jid}/admins
api-docs.groups_promote_desc
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}/admins" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"participants": ["5511987654321"]
}'
/instances/{uuid}/groups/{jid}/admins
api-docs.groups_demote_desc
Ejemplo
curl -X DELETE "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}/admins" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"participants": ["5511987654321"]
}'
/instances/{uuid}/groups/{jid}/leave
Hace que la instancia salga de un grupo.
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/instances/{uuid}/groups/{jid}/leave" \
-H "Authorization: Bearer {token}"
/instances/{uuid}/groups/{jid}/invite
api-docs.groups_invite_get_desc
Respuesta
{
"success": true,
"data": {
"code": "AbCdEfGhIjKl",
"invite_link": "https://chat.whatsapp.com/AbCdEfGhIjKl"
}
}
/instances/{uuid}/groups/{jid}/invite
api-docs.groups_invite_revoke_desc
Respuesta
{
"success": true,
"data": {
"new_code": "MnOpQrStUvWx",
"new_invite_link": "https://chat.whatsapp.com/MnOpQrStUvWx"
},
"message": "Invite link revoked"
}
Etiquetas
Gestione etiquetas de conversaciones para organizar y categorizar chats. Las etiquetas están limitadas por tenant y pueden asignarse a múltiples conversaciones.
/tags
Lista todas las etiquetas del tenant actual.
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/tags" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"data": {
"tags": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "VIP",
"color": "#f59e0b",
"conversations_count": 15,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Support",
"color": "#3b82f6",
"conversations_count": 42,
"created_at": "2025-01-15T10:35:00Z",
"updated_at": "2025-01-15T10:35:00Z"
}
]
}
}
/tags
Crea una nueva etiqueta.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name |
string | Sí | Nombre de la etiqueta (único por tenant) (max 50) |
color |
string | Sí | Código de color hexadecimal para la etiqueta (#RRGGBB) |
Ejemplo
curl -X POST "https://instance-{id}.zapini.app/tags" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Important",
"color": "#ef4444"
}'
Respuesta
{
"success": true,
"message": "Tag created successfully",
"data": {
"tag": {
"id": "550e8400-e29b-41d4-a716-446655440003",
"name": "Important",
"color": "#ef4444",
"conversations_count": 0,
"created_at": "2025-01-15T12:00:00Z",
"updated_at": "2025-01-15T12:00:00Z"
}
}
}
/tags/{uuid}
Devuelve detalles de una etiqueta específica.
Ejemplo
curl -X GET "https://instance-{id}.zapini.app/tags/550e8400-e29b-41d4-a716-446655440001" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
/tags/{uuid}
Actualiza una etiqueta existente.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name |
string | No | Nombre de la etiqueta (único por tenant) (max 50) |
color |
string | No | Código de color hexadecimal para la etiqueta (#RRGGBB) |
Ejemplo
curl -X PATCH "https://instance-{id}.zapini.app/tags/550e8400-e29b-41d4-a716-446655440001" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Very Important",
"color": "#dc2626"
}'
/tags/{uuid}
Elimina una etiqueta. La etiqueta se eliminará automáticamente de todas las conversaciones.
Ejemplo
curl -X DELETE "https://instance-{id}.zapini.app/tags/550e8400-e29b-41d4-a716-446655440001" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Respuesta
{
"success": true,
"message": "Tag deleted successfully"
}
/conversations/{uuid}/tags
Actualiza las etiquetas asignadas a una conversación. Esto reemplaza todas las etiquetas existentes con la lista proporcionada.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
tag_ids |
array | Sí | Array de UUIDs de etiquetas para asignar a la conversación |
Ejemplo
curl -X PUT "https://instance-{id}.zapini.app/conversations/550e8400-e29b-41d4-a716-446655440000/tags" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"tag_ids": ["550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002"]
}'
Respuesta
{
"success": true,
"message": "Conversation tags updated",
"data": {
"tags": [
{"id": "550e8400-e29b-41d4-a716-446655440001", "name": "VIP", "color": "#f59e0b"},
{"id": "550e8400-e29b-41d4-a716-446655440002", "name": "Support", "color": "#3b82f6"},
{"id": "550e8400-e29b-41d4-a716-446655440003", "name": "Important", "color": "#ef4444"}
]
}
}
Para eliminar todas las etiquetas de una conversación, envíe un array vacío: {"tag_ids": []}
Chat API
OPTIMIZADO PARA UIEndpoints optimizados para crear interfaces de chat tipo WhatsApp. Devuelve datos preformateados con @menciones resueltas, reacciones agrupadas y helpers de alineación.
formatted_body
@menciones pre-resueltas en formato HTML
grouped_reactions
Reacciones agrupadas con conteo
is_from_me
Alineación fácil con is_from_me
tags
Tags de conversaciones incluidos
La Chat API devuelve los mismos datos que los endpoints estándar, pero con campos adicionales optimizados para renderizado de UI. También puede usar ?format=chat en los endpoints estándar.
/api/v1/conversations?format=chat
/api/v1/chat/conversations
Lista conversaciones con tags, fotos de perfil y conteo de no leídos optimizado para UI de lista de chat.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
instance_id |
string | Filtrar por instancia (UUID) |
search |
string | Buscar por nombre o número |
unread |
boolean | Mostrar solo conversaciones no leídas |
per_page |
integer | Items por página (máx 100) |
Ejemplo
curl -X GET "https://zapini.app/api/v1/chat/conversations?unread=true" \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440045",
"contact_number": "5521999999999",
"display_name": "John Doe",
"is_group": false,
"profile_picture_url": "https://...",
"last_message": "Hello!",
"last_message_at": "2025-12-16T10:00:00Z",
"unread_count": 3,
"tags": [
{"id": "bf287f4d-037c-4280-8413-c7b7d08df5a0", "name": "VIP", "color": "#f59e0b"}
],
"instance": {
"uuid": "21ed5c9b-51a0-4569-85db-05433ea414b7",
"phone_number": "5511988887777",
"status": "connected"
}
}
],
"meta": {
"pagination": {
"total": 50,
"per_page": 15,
"current_page": 1,
"last_page": 4
}
}
}
/api/v1/chat/conversations/{uuid}/messages
Devuelve mensajes con formatted_body (@menciones resueltas) y reacciones agrupadas.
Parámetros de Consulta
| Campo | Tipo | Descripción |
|---|---|---|
before_id |
integer | Mensajes antes de este ID |
after_id |
integer | Mensajes después de este ID |
limit |
integer | Límite de mensajes (máx 100) |
Ejemplo
curl -X GET "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/messages?limit=50" \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"data": {
"messages": [
{
"id": 456,
"unique_id": "msg-abc-123",
"direction": "incoming",
"is_from_me": false,
"message_body": "Ola @5521999999999!",
"formatted_body": "Ola <span class=\"mention\" data-phone=\"5521999999999\">@John Doe</span>!",
"mentioned_jids": ["5521999999999@s.whatsapp.net"],
"sender_name": "Maria",
"status": "read",
"grouped_reactions": [
{
"emoji": "👍",
"count": 2,
"has_my_reaction": true,
"reactors": ["5521988887777", "5521966665555"],
"reactor_names": ["Carlos", "Ana"]
}
],
"created_at": "2025-12-16T10:00:00Z"
}
],
"has_more": true,
"oldest_id": 400,
"newest_id": 456
}
}
Características Principales
formatted_body
Texto del mensaje con @menciones resueltas a nombres de contactos. Devuelve HTML con spans clicables.
Hola @Juan García!
is_from_me
Boolean indicando si el mensaje fue enviado por tu instancia. Usar para alineación de mensajes.
grouped_reactions
Reacciones agrupadas por emoji con conteos e información de los reactores.
{"emoji": "👍", "count": 2, "has_my_reaction": true}
mentioned_jids
Array de JIDs de WhatsApp mencionados en el mensaje.
/api/v1/chat/send
Envía un mensaje de texto y devuelve el mensaje en formato optimizado para chat.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
instance_id |
string | Sí | UUID de la instancia (requerido) |
recipient |
string | Sí | Número de teléfono del destinatario con código de país |
message |
string | Sí | Contenido del mensaje de texto |
reply_to |
string | No | ID del mensaje para responder |
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/send" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "18",
"recipient": "5521999999999",
"message": "Hello from Chat API!"
}'
/api/v1/chat/send-media
Envía media (imagen, video, audio, documento) y devuelve respuesta optimizada para chat.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
instance_id |
string | Sí | UUID de la instancia (requerido) |
recipient |
string | Sí | Número de teléfono del destinatario con código de país |
media_url |
string | Sí | URL del archivo de media a enviar |
media_type |
string | Sí | Tipo de media (image, video, audio, document) |
caption |
string | No | Leyenda para imagen/video |
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/send-media" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "18",
"recipient": "5521999999999",
"media_url": "https://example.com/image.jpg",
"media_type": "image",
"caption": "Check this out!"
}'
/api/v1/chat/messages/{uuid}
Edita el contenido de un mensaje enviado.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
message |
string | Sí | Nuevo contenido del mensaje |
Ejemplo
curl -X PATCH "https://zapini.app/api/v1/chat/messages/msg-abc-123" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"message": "Updated message content"}'
/api/v1/chat/messages/{uuid}
Elimina un mensaje enviado.
Ejemplo
curl -X DELETE "https://zapini.app/api/v1/chat/messages/msg-abc-123" \
-H "Authorization: Bearer {token}"
/api/v1/chat/messages/{uuid}/reaction
Agrega una reacción emoji a un mensaje.
Parámetros
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
emoji |
string | Sí | Emoji para reaccionar |
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/messages/msg-abc-123/reaction" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"emoji": "👍"}'
/api/v1/chat/messages/{uuid}/reaction
Elimina una reacción de un mensaje.
Ejemplo
curl -X DELETE "https://zapini.app/api/v1/chat/messages/msg-abc-123/reaction" \
-H "Authorization: Bearer {token}"
/api/v1/chat/conversations/{uuid}/mark-read
Marca una conversación como leída.
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/mark-read" \
-H "Authorization: Bearer {token}"
/api/v1/chat/conversations/{uuid}/archive
Archiva una conversación.
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/archive" \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"message": "Conversation archived.",
"data": {
"archived_id": "550e8400-e29b-41d4-a716-446655440045",
"archived_at": "2025-12-29T12:00:00.000000Z"
}
}
/api/v1/chat/conversations/{uuid}/archive
Restaura una conversación archivada a estado activo.
El UUID debe ser de una conversación archivada. Use GET /conversations/archived para listar conversaciones archivadas.
Ejemplo
curl -X DELETE "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/archive" \
-H "Authorization: Bearer {token}"
Respuesta
{
"success": true,
"message": "Conversation restored.",
"data": {
"conversation_id": "550e8400-e29b-41d4-a716-446655440045",
"restored": true
}
}
/api/v1/chat/conversations/{uuid}/pause-automation
Pausar la automatización de una conversación para permitir el envío de mensajes manuales.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
reason |
string | No | Razón opcional para pausar la automatización |
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/pause-automation" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"reason": "Manual takeover"}'
/api/v1/chat/conversations/{uuid}/resume-automation
Reanudar la automatización de una conversación, devolviendo el control al sistema automatizado.
Ejemplo
curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/resume-automation" \
-H "Authorization: Bearer {token}"
Automatizaciones
IMPORTANTEAviso Importante sobre Automatizaciones
Si tu instancia tiene automatizaciones (flujos o integraciones) activas, el envío de mensajes vía API puede estar bloqueado. Lee esta sección para entender cómo funciona.
¿Qué son las Automatizaciones?
Las automatizaciones son flujos automatizados que responden mensajes automáticamente. El sistema tiene dos tipos de automatización:
Flujos
Flujos de conversación creados en el editor visual que responden automáticamente basándose en reglas y condiciones.
Integraciones
Conexiones con sistemas externos (webhooks, APIs, IA) que procesan y responden mensajes automáticamente.
Bloqueo de Mensajes
Cuando una conversación tiene automatización activa, el envío de mensajes vía API está bloqueado para evitar conflictos entre respuestas automáticas y manuales.
Respuesta de Error
{
"success": false,
"error": {
"code": "AUTOMATION_ACTIVE",
"message": "Cannot send messages. This conversation has active automation. Pause the automation first to send messages manually.",
"conversation_id": 123
}
}
¿Cuándo se Bloquea el Envío?
- • La instancia tiene un flujo o integración activa
- • La conversación no fue pausada manualmente
- • La conversación todavía está siendo gestionada por la automatización
Cómo Enviar Mensajes con Automatización Activa
Para enviar mensajes manualmente cuando hay automatización activa, necesitas pausar la automatización para la conversación específica:
Verifica el Estado
Usa el endpoint de detalles de la conversación para verificar el campo automation_status.
Pausa la Automatización
Si automation_status es "active", usa el endpoint de pausa para permitir mensajes manuales.
Envía el Mensaje
Después de pausar, puedes enviar mensajes normalmente vía API.
/api/v1/chat/conversations/{uuid}
Verifica el estado de automatización de una conversación antes de intentar enviar mensajes.
Campos de Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
automation_status |
string | Estado actual de la automatización (active o paused) |
can_send_manual_message |
boolean | Si puedes enviar mensajes manuales |
automation_paused_at |
datetime|null | Fecha/hora cuando la automatización fue pausada |
Valores de Estado
| Status | Descripción | ¿Puede Enviar vía API? |
|---|---|---|
active |
La automatización está respondiendo mensajes automáticamente | No |
paused |
Automatización pausada, el usuario ha tomado el control | Sí |
/api/v1/chat/conversations/{uuid}/pause-automation
Pausa la automatización para permitir envío de mensajes manuales vía API.
Cuerpo de la Solicitud (optional)
| Campo | Tipo | Descripción |
|---|---|---|
reason |
string | Motivo opcional para pausar (ej.: "Intervención manual requerida") |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/api/v1/chat/conversations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/pause-automation \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"reason": "Manual intervention required"}'
Ejemplo de Respuesta
{
"success": true,
"message": "Automation paused successfully",
"data": {
"conversation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"automation_paused": true,
"paused_at": "2025-01-15T10:30:00+00:00",
"paused_by": "John Doe",
"reason": "Manual intervention required"
}
}
/api/v1/chat/conversations/{uuid}/resume-automation
Reanuda la automatización, devolviendo el control al sistema automatizado.
Ejemplo
curl -X POST https://instance-{id}.zapini.app/api/v1/chat/conversations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/resume-automation \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json"
Ejemplo de Respuesta
{
"success": true,
"message": "Automation resumed successfully",
"data": {
"conversation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"automation_paused": false,
"resumed_at": "2025-01-15T11:00:00+00:00"
}
}
Operaciones en Lote
Pausa o reanuda la automatización de múltiples conversaciones a la vez. Útil para mantenimiento, campañas o procesamiento por lotes. Máximo de 100 conversaciones por solicitud.
/api/v1/conversations/automation/bulk-pause
Pausa la automatización de múltiples conversaciones a la vez. Omite conversaciones que ya están pausadas o no tienen automatización activa.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
conversation_ids |
array | Sí | Array de UUIDs de conversaciones (máx 100) |
reason |
string | No | Motivo opcional para pausar (ej.: "Intervención manual requerida") |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/api/v1/conversations/automation/bulk-pause \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"conversation_ids": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"b2c3d4e5-f6a7-8901-bcde-f12345678901"
],
"reason": "Bulk pause for maintenance"
}'
Respuesta
{
"success": true,
"message": "2 conversations paused",
"data": {
"paused": 2,
"skipped": 0,
"errors": 0
}
}
/api/v1/conversations/automation/bulk-resume
Reanuda la automatización de múltiples conversaciones a la vez. Omite conversaciones que no están pausadas o no tienen automatización activa.
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
conversation_ids |
array | Sí | Array de UUIDs de conversaciones (máx 100) |
Ejemplo
curl -X POST https://instance-{id}.zapini.app/api/v1/conversations/automation/bulk-resume \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"conversation_ids": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"b2c3d4e5-f6a7-8901-bcde-f12345678901"
]
}'
Respuesta
{
"success": true,
"message": "2 automations resumed",
"data": {
"resumed": 2,
"skipped": 0,
"errors": 0
}
}
Mejores Prácticas
- Siempre verifica can_send_manual_message antes de enviar mensajes para evitar errores.
- Pausa la automatización solo cuando sea necesario para intervención humana.
- Reanuda la automatización después del servicio manual para mantener una experiencia consistente.
¿Listo para Comenzar?
Crea tu cuenta ahora y comienza a integrar WhatsApp en tus aplicaciones con nuestra API potente y fácil de usar.