Documentación de la API

Guía completa para integración con la API de Zapini

Descargar Markdown

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.

Gestionar múltiples instancias Conversaciones y contactos Etiquetas y automatizaciones Estadísticas e informes

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.

Envío de mensajes (texto media) Estado de conexión Código QR para conexión Webhooks en tiempo real

¿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
200OK - Solicitud exitosa
201Created - Recurso creado exitosamente
400Bad Request - Parámetros inválidos
401Unauthorized - Token inválido o ausente
403Forbidden - Sin permiso para este recurso
404Not Found - Recurso no encontrado
422Unprocessable Entity - Error de validación
429Too Many Requests - Límite de solicitudes excedido
500Internal 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}
POST /auth/login

Autentica un usuario y devuelve un token de acceso.

Parámetros

Campo Tipo Requerido Descripción
email string Email del usuario
password string 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"
  }
}
GET /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"
POST /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"
POST /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

GET /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"
      }
    ]
  }
}
GET /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"
GET /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"
  }
}
GET /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"
GET /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
  }
}
POST /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"
POST /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
Token de Instancia (sk_) Requerido

API Universal - /chat/send

Para enviar mensagens via API Universal, use o endpoint /chat/send (consulte a aba Chat API).

POST /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 Número de WhatsApp del destinatario (con código de país) (5511999999999)
message string Contenido del mensaje de texto
reply_to (ou quoted_message_id) string No ID del mensaje para responder
Parámetros alternativos: Os campos 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"
}
POST /send-media

Envía un mensaje con medios (imagen, video, audio, documento).

Parámetros

Campo Tipo Requerido Descripción
recipient (ou number, to) string Número de WhatsApp del destinatario (con código de país) (5511999999999)
media_url (ou url) string URL pública del archivo de medios
media_type (ou type) string image, video, audio, document
caption string No Leyenda para imágenes y videos
filename string No Nombre del archivo para documentos
Parámetros alternativos: Os campos 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"
}
POST /send-reaction

Envía un emoji de reacción a un mensaje específico.

Parámetros

Campo Tipo Requerido Descripción
to string JID do chat
messageId string ID da mensagem para reagir
emoji string 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": "👍"
  }'
GET /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"
}
GET /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"
}
GET /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

GET /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
    }
  }
}
GET /conversations/{uuid}

Devuelve detalles de una conversación específica.

GET /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.

POST /conversations/{uuid}/mark-read

Marca una conversación como leída.

POST /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"
  }
}
DELETE /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
  }
}
DELETE /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.

GET /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
  }
}
POST /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"
  }
}
POST /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"
  }
}
POST /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 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."
}
POST /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 Array de IDs de conversaciones a procesar

Respuesta

{
  "success": true,
  "message": "3 conversations resumed successfully."
}

Contactos

GET /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
    }
  }
}
POST /contacts

Crea un nuevo contacto.

Parámetros

Campo Tipo Requerido Descripción
instance_id string ID da instância
phone_number string 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"
  }'
GET /contacts/{id}

Devuelve detalles de un contacto específico.

PUT /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
DELETE /contacts/{id}

Elimina un contacto.

POST /contacts/import

Importa múltiples contactos a la vez.

Parámetros

Campo Tipo Requerido Descripción
instance_id string ID da instância
contacts array 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": []
  }
}
GET /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

NEW

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

  1. Ve a la configuración de tu Token de API y haz clic en "Configurar Webhook"
  2. Ingresa tu URL de webhook (debe ser HTTPS en producción)
  3. Genera o ingresa una clave secreta para verificación de firma
  4. 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"
  }
}
POST /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"
    }
  }'
POST /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
POST /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"
}
POST /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
POST /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"
}
PUT /instances/{uuid}/webhook

Configure una URL externa para recibir notificaciones de eventos.

Parámetros

Campo Tipo Requerido Descripción
webhook_url string 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

message.incoming message.outgoing message.status message.reaction message.deleted connection.update qr.update contact.update

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.

📷
Imágenes
jpg, png, gif, webp
🎥
Videos
mp4, 3gp, mov
🎵
Audio
mp3, ogg, wav, opus
📄
Documentos
pdf, doc, xls, etc
POST /media/upload

Sube un archivo de medios para uso posterior.

Parámetros

Campo Tipo Requerido Descripción
file file 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"
  }
}
GET /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"
  }
}
DELETE /media/{id}

Elimina un archivo de medios.

Ejemplo

curl -X DELETE https://instance-{id}.zapini.app/media/media_abc123xyz \
  -H "Authorization: Bearer {token}"
POST /messages/send-media

Envía un mensaje con medios adjuntos.

Parámetros

Campo Tipo Requerido Descripción
instance_id string ID da instância
recipient string 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 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
GET /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.

GET /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
  }
}
POST /instances/{uuid}/groups

Crea un nuevo grupo de WhatsApp.

Cuerpo de la Solicitud

Campo Tipo Requerido Descripción
subject string api-docs.group_subject_desc
participants array 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"
  }
}
GET /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
  }
}
PATCH /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"
  }'
POST /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"]
  }'
DELETE /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"]
  }'
POST /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"]
  }'
DELETE /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"]
  }'
POST /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}"
GET /instances/{uuid}/groups/{jid}/invite

api-docs.groups_invite_get_desc

Respuesta

{
  "success": true,
  "data": {
    "code": "AbCdEfGhIjKl",
    "invite_link": "https://chat.whatsapp.com/AbCdEfGhIjKl"
  }
}
DELETE /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.

GET /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"
      }
    ]
  }
}
POST /tags

Crea una nueva etiqueta.

Cuerpo de la Solicitud

Campo Tipo Requerido Descripción
name string Nombre de la etiqueta (único por tenant) (max 50)
color string 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"
    }
  }
}
GET /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"
PATCH /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"
  }'
DELETE /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"
}
PUT /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 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 UI

Endpoints 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
GET /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
    }
  }
}
GET /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.

POST /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 UUID de la instancia (requerido)
recipient string Número de teléfono del destinatario con código de país
message string 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!"
  }'
POST /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 UUID de la instancia (requerido)
recipient string Número de teléfono del destinatario con código de país
media_url string URL del archivo de media a enviar
media_type string 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!"
  }'
PATCH /api/v1/chat/messages/{uuid}

Edita el contenido de un mensaje enviado.

Parámetros

Campo Tipo Requerido Descripción
message string 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"}'
DELETE /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}"
POST /api/v1/chat/messages/{uuid}/reaction

Agrega una reacción emoji a un mensaje.

Parámetros

Campo Tipo Requerido Descripción
emoji string 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": "👍"}'
DELETE /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}"
POST /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}"
POST /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"
  }
}
DELETE /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
  }
}
POST /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"}'
POST /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

IMPORTANTE

Aviso 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:

1

Verifica el Estado

Usa el endpoint de detalles de la conversación para verificar el campo automation_status.

2

Pausa la Automatización

Si automation_status es "active", usa el endpoint de pausa para permitir mensajes manuales.

3

Envía el Mensaje

Después de pausar, puedes enviar mensajes normalmente vía API.

GET /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
POST /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"
  }
}
POST /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.

POST /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 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
  }
}
POST /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 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.