Cargando...

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://zapini.app/api/v1

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

La API acepta tanto ID numérico como UUID en todos los endpoints.

ID Numérico UUID
Ejemplo 777 550e8400-e29b-...
Dónde encontrar Se muestra en la tarjeta de la instancia. Ejemplo: 777 Se muestra en la página de detalles de la instancia. Ejemplo: 550e8400-e29b-41d4-a716-446655440000

Con un token sk_, el parámetro instance_id es opcional — se detecta automáticamente desde el token.

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

Devuelve detalles de una instancia específica.

La API acepta tanto ID numérico como UUID en todos los endpoints.

Ejemplo

# ID Numéricocurl -X GET https://instance-{id}.zapini.app/instances/777 \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

# UUID
curl -X GET https://instance-{id}.zapini.app/instances/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
GET /instances/{id}/qr

Devuelve el código QR para conectar la instancia.

Ejemplo

curl -X GET https://instance-{id}.zapini.app/instances/777/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/{id}/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/777/status?realtime=true" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
GET /instances/{id}/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/{id}/disconnect

Desconecta la instancia de WhatsApp.

Ejemplo

curl -X POST https://instance-{id}.zapini.app/instances/777/disconnect \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
POST /instances/{id}/reconnect

Inicia el proceso de reconexión de la instancia.

Ejemplo

curl -X POST https://instance-{id}.zapini.app/instances/777/reconnect \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Mensajes

API de Instancia

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": "777",
    "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": "777",
    "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}"

Transcripción de Audio

Los campos de transcripción también se incluyen en el objeto de mensaje retornado por el endpoint de mensajes. Los mensajes de audio con auto-transcripción habilitada tendrán las transcripciones pobladas automáticamente.

GET /api/v1/chat/messages/{uuid}/transcription

Obtiene el estado y texto de la transcripción de un mensaje de audio.

Ejemplo

curl -X GET "https://zapini.app/api/v1/chat/messages/msg-abc-123/transcription" \
  -H "Authorization: Bearer {token}"

Respuesta

{
  "success": true,
  "data": {
    "message_id": "msg-abc-123",
    "audio_transcription": "Olá, tudo bem? Gostaria de saber mais sobre o produto.",
    "transcription_status": "completed",
    "transcription_language": "pt",
    "transcription_error": null,
    "transcription_completed_at": "2026-02-21T10:30:00.000000Z"
  }
}

Campos de Respuesta

Campo Tipo Descripción
audio_transcription string|null El texto transcrito (null si aún no está completado)
transcription_status string|null Estado: pending, processing, completed o failed
transcription_language string|null Código de idioma detectado o configurado (ej. pt, en, es)
transcription_error string|null Mensaje de error si la transcripción falló
transcription_completed_at string|null Timestamp de cuando la transcripción fue completada
POST /api/v1/chat/messages/{uuid}/transcription

Solicita la transcripción de un mensaje de audio. Si ya fue completada, retorna la transcripción existente. Soporta proveedores Whisper, Gemini y ElevenLabs.

Ejemplo

curl -X POST "https://zapini.app/api/v1/chat/messages/msg-abc-123/transcription" \
  -H "Authorization: Bearer {token}"

Respuesta

{
  "success": true,
  "message": "Transcription queued successfully.",
  "data": {
    "message_id": "msg-abc-123",
    "transcription_status": "pending"
  }
}

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.

API de Voz & IVR

62 endpoints

Visión General de la API de Voz

La API de Voz permite gestionar toda la infraestructura de telefonía programáticamente: números de teléfono, configuración IVR, llamadas, colas, callbacks, skills de agentes y clonación de voz.

URL Base

https://zapini.app/api/v1/voice

Autenticación

Autenticación Bearer Token + Permiso Twilio Voice

Endpoints

62 endpoints disponibles

Esta API requiere que la funcionalidad Twilio Voice esté habilitada en su tenant. Contacte al administrador para activarla.

Números de Teléfono

Gestione números de teléfono: registrar, configurar modo de atención (IA, humano, IVR), grabación, SIP y más.

Modos de atención disponibles

ai_onlySolo IA - La IA atiende todas las llamadas automáticamente
human_onlySolo Humano - Llamadas dirigidas a agentes humanos vía WebRTC
ai_with_handoffIA con Transferencia - IA atiende y puede transferir a humano
ivr_menuMenú IVR - Menú interactivo con opciones numéricas
GET /voice/numbers

Gestione números de teléfono: registrar, configurar modo de atención (IA, humano, IVR), grabación, SIP y más.

Ejemplo

curl -X GET https://zapini.app/api/v1/voice/numbers \
  -H "Authorization: Bearer {token}"

Respuesta

{
  "success": true,
  "data": [
    {
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "phone_number": "+5511999999999",
      "friendly_name": "Main Line",
      "status": "active",
      "connection_type": "twilio",
      "call_handling_mode": "ai_only",
      "ai_enabled": true,
      "recording_enabled": false,
      "ivr_enabled": false,
      "created_at": "2026-02-14T10:00:00Z"
    }
  ]
}
POST /voice/numbers

Register a new phone number.

Parámetros

ParâmetroTipoRequeridoDescripción
phone_numberstringyesE.164 format (+5511999999999)
friendly_namestringnoDisplay name
connection_typestringnotwilio, asterisk_sip, asterisk_hardphone

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/numbers \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+5511999999999",
    "friendly_name": "Main Line",
    "connection_type": "twilio"
  }'
GET /voice/numbers/{uuid}

Get full details of a phone number including AI config, SIP settings and business hours summary.

PATCH /voice/numbers/{uuid}

Update phone number settings.

Parámetros

ParâmetroTipoDescripción
friendly_namestringDisplay name
call_handling_modestringai_only, human_only, ai_with_handoff, ivr_menu
ai_system_promptstringAI system prompt for calls
ai_voicestringAI voice ID
recording_enabledbooleanEnable call recording
sip_enabledbooleanEnable SIP
statusstringactive, inactive
DELETE /voice/numbers/{uuid}

Delete/release a phone number. Returns 204 on success.

Horario de Atención & Festivos

Configure horarios de atención y festivos para cada número. Las llamadas fuera de horario pueden redirigirse automáticamente.

GET /voice/numbers/{uuid}/business-hours

Get business hours schedule and current status (open/closed).

Respuesta

{
  "success": true,
  "data": {
    "enabled": true,
    "timezone": "America/Sao_Paulo",
    "is_currently_open": true,
    "schedule": {
      "monday": { "enabled": true, "open": "09:00", "close": "18:00" },
      "tuesday": { "enabled": true, "open": "09:00", "close": "18:00" },
      "wednesday": { "enabled": true, "open": "09:00", "close": "18:00" },
      "thursday": { "enabled": true, "open": "09:00", "close": "18:00" },
      "friday": { "enabled": true, "open": "09:00", "close": "17:00" },
      "saturday": { "enabled": false },
      "sunday": { "enabled": false }
    },
    "outside_hours_action": "voicemail",
    "outside_hours_message": "We are currently closed."
  }
}
PUT /voice/numbers/{uuid}/business-hours

Set full business hours schedule. Send the complete schedule object.

GET /voice/numbers/{uuid}/holidays

Gestione festivos con mensajes personalizados. Soporta festivos recurrentes (anuales) y fechas específicas.

Respuesta

{
  "success": true,
  "data": {
    "holidays": [
      {
        "index": 0,
        "name": "Christmas",
        "date": "2026-12-25",
        "recurring": true,
        "message": "Merry Christmas!"
      }
    ]
  }
}
POST /voice/numbers/{uuid}/holidays

Add a single holiday. Required: name, date. Optional: recurring, message.

PUT /voice/numbers/{uuid}/holidays

Replace all holidays. Send an array of holiday objects.

DELETE /voice/numbers/{uuid}/holidays/{index}

Remove a holiday by its index (0-based).

Configuración IVR

Configure menús interactivos de voz con opciones numéricas, mensajes TTS, recolección de datos, transferencias y más.

Tipos de Opción IVR

collect_cpfRecolectar CPF del llamante
collect_numberRecolectar número digitado
record_voiceGrabar mensaje de voz
transfer_agentTransferir a agente humano
transfer_aiTransferir a servicio IA
transfer_externalTransferir a número externo
play_messageReproducir mensaje
submenuAbrir submenú
callbackSolicitar callback
scheduleAgendar cita
customAcción personalizada
GET /voice/numbers/{uuid}/ivr

Get full IVR configuration including messages, timeouts and options.

Respuesta

{
  "success": true,
  "data": {
    "ivr_enabled": true,
    "ivr_welcome_message": "Welcome to our company.",
    "ivr_menu_intro": "Press 1 for sales, 2 for support.",
    "ivr_invalid_option_message": "Invalid option.",
    "ivr_goodbye_message": "Goodbye!",
    "ivr_input_timeout": 5,
    "ivr_max_attempts": 3,
    "options": [
      {
        "uuid": "a1b2c3d4...",
        "digit": "1",
        "label": "Sales",
        "type": "transfer_agent",
        "is_enabled": true,
        "order": 1
      }
    ]
  }
}
PUT /voice/numbers/{uuid}/ivr

Update IVR configuration.

Parámetros

ParâmetroTipoDescripción
ivr_enabledbooleanCampos de configuración IVR
ivr_welcome_messagestringMensaje de bienvenida reproducido al contestar
ivr_menu_introstringTexto del menú con las opciones disponibles
ivr_invalid_option_messagestringMensaje para opción inválida
ivr_goodbye_messagestringMensaje de despedida
ivr_input_timeoutintegerTiempo de espera por input (1-30 segundos)
ivr_max_attemptsintegerMáximo de intentos inválidos (1-10)
GET /voice/numbers/{uuid}/ivr/types

List all available IVR option types with descriptions.

POST /voice/numbers/{uuid}/ivr/options

Create a new IVR menu option.

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/numbers/{uuid}/ivr/options \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "digit": "1",
    "label": "Sales Department",
    "type": "transfer_agent",
    "message": "Transferring you to our sales team.",
    "is_enabled": true
  }'
GET /voice/numbers/{uuid}/ivr/options

List all IVR menu options for a number, ordered by position.

PATCH /voice/numbers/{uuid}/ivr/options/{optionUuid}

Update an IVR option (digit, label, type, message, enabled).

DELETE /voice/numbers/{uuid}/ivr/options/{optionUuid}

Delete an IVR option.

POST /voice/numbers/{uuid}/ivr/options/reorder

Reorder IVR options. Send array of UUIDs in desired order.

{ "order": ["uuid-option-2", "uuid-option-1", "uuid-option-3"] }
POST /voice/numbers/{uuid}/ivr/regenerate-audio

Regenerate TTS audio cache for IVR messages. Optional: voice_id, language.

Llamantes VIP

Gestione llamantes prioritarios con enrutamiento personalizado. Los llamantes VIP pueden saltar la cola o recibir servicio diferenciado.

Niveles de prioridad

vipVIP - Máxima prioridad, salta cola
priorityPrioridad - Servicio preferencial
standardEstándar - Servicio normal
blockedBloqueado - Llamadas rechazadas automáticamente
GET /voice/numbers/{uuid}/vip-callers

List all VIP callers for a phone number.

POST /voice/numbers/{uuid}/vip-callers

Add a VIP caller.

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/numbers/{uuid}/vip-callers \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+5511988887777",
    "name": "John CEO",
    "priority": "vip",
    "notes": "Always connect immediately"
  }'
GET /voice/numbers/{uuid}/vip-callers/check/{phone}

Check if a phone number is in the VIP list. Returns VIP details or is_vip: false.

PATCH /voice/numbers/{uuid}/vip-callers/{vipUuid} | DELETE /voice/numbers/{uuid}/vip-callers/{vipUuid}

Update or delete a VIP caller by UUID.

Gestión de Cola

Configure y monitoree colas de atención con música de espera, anuncio de posición y callback automático.

GET /voice/numbers/{uuid}/queue

Get queue status, configuration and metrics.

Respuesta

{
  "success": true,
  "data": {
    "config": {
      "queue_enabled": true,
      "max_queue_size": 10,
      "max_wait_time": 300,
      "hold_music_url": null,
      "announce_position": true,
      "callback_enabled": true
    },
    "status": {
      "active_entries": 3,
      "waiting_count": 2,
      "connected_count": 1
    }
  }
}
PATCH /voice/numbers/{uuid}/queue

Update queue configuration (max_queue_size, max_wait_time, hold_music_url, announce_position, callback_enabled).

GET /voice/numbers/{uuid}/queue/entries | DELETE /voice/numbers/{uuid}/queue/entries/{id}

List active queue entries or remove a specific entry from the queue.

Llamadas

Inicie, monitoree y gestione llamadas. Incluye transferencia a IA, estadísticas y costos detallados.

GET /voice/calls

List calls with filters.

Filtros disponibles

ParâmetroTipoDescripción
directionstringinbound, outbound
statusstringringing, in-progress, completed, failed, etc.
number_uuidstringFilter by phone number UUID
date_fromdateYYYY-MM-DD
date_todateYYYY-MM-DD
per_pageintegerResults per page (default: 25)

Ejemplo

curl -X GET "https://zapini.app/api/v1/voice/calls?direction=inbound&status=completed&per_page=10" \
  -H "Authorization: Bearer {token}"
POST /voice/calls

Initiate an outbound call.

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/calls \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "from_number_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "to": "+5511988887777",
    "record": true
  }'
GET /voice/calls/statistics

Get call statistics: total, by direction, average duration, costs.

Respuesta

{
  "success": true,
  "data": {
    "period": "monthly",
    "total_calls": 150,
    "inbound": 90,
    "outbound": 60,
    "total_duration_seconds": 45000,
    "average_duration_seconds": 300,
    "total_cost": 75.50,
    "minutes_used": 750,
    "minutes_limit": 1000,
    "minutes_remaining": 250
  }
}
GET /voice/calls/{uuid}

Get detailed call information with duration, costs, recording URL and transcript.

Call Actions:

POST /voice/calls/{uuid}/end
POST /voice/calls/{uuid}/transfer-to-ai
POST /voice/calls/{uuid}/reject

End an active call, transfer it to AI, or reject an incoming call.

Callbacks

Gestione solicitudes de callback: listar, ejecutar, cancelar y reprogramar.

GET /voice/callbacks

List callback requests. Filters: status (pending, completed, cancelled, expired), number_uuid, date_from, date_to.

Ejemplo

curl -X GET "https://zapini.app/api/v1/voice/callbacks?status=pending" \
  -H "Authorization: Bearer {token}"

Callback Actions:

GET /voice/callbacks/{uuid}
POST /voice/callbacks/{uuid}/execute
POST /voice/callbacks/{uuid}/cancel
POST /voice/callbacks/{uuid}/reschedule

Get details, execute now, cancel, or reschedule a callback.

Reschedule requires: scheduled_for (ISO 8601 datetime)

Skills de Agentes

Gestione competencias de agentes para enrutamiento inteligente de llamadas basado en habilidades.

GET /voice/agents/skill-types

Get available skill types (sales, support, billing, technical, etc.).

Agent Skills CRUD:

GET /voice/agents/skills
GET /voice/agents/{userId}/skills
POST /voice/agents/{userId}/skills
PATCH /voice/agents/{userId}/skills/{skillId}
DELETE /voice/agents/{userId}/skills/{skillId}

Manage agent skills. Add skill requires: skill_type, proficiency (1-5).

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/agents/{userId}/skills \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "skill_type": "sales",
    "proficiency": 5
  }'

Voces Clonadas

Clone voces usando IA para IVR y servicio automatizado. Suba muestras de audio para crear voces personalizadas.

GET /voice/voices

List all cloned voices for the tenant.

POST /voice/voices

Clone a new voice from audio samples (multipart/form-data).

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/voices \
  -H "Authorization: Bearer {token}" \
  -F "name=My Voice Clone" \
  -F "description=Custom voice for IVR" \
  -F "samples[]=@sample1.mp3" \
  -F "samples[]=@sample2.mp3"
GET /voice/voices/{uuid} | PATCH /voice/voices/{uuid} | DELETE /voice/voices/{uuid}

Get details, update name/description, or delete a cloned voice.

Credenciales Twilio

Gestione credenciales de acceso a Twilio: Account SID, Auth Token y API Keys para WebRTC.

GET /voice/credentials

Get credential status (masked values, never exposes secrets).

Respuesta

{
  "success": true,
  "data": {
    "configured": true,
    "is_verified": true,
    "account_sid_masked": "AC****1234",
    "has_api_keys": true,
    "api_key_sid_masked": "SK****5678",
    "created_at": "2026-02-14T10:00:00Z"
  }
}
POST /voice/credentials

Save Twilio credentials.

Parámetros

ParâmetroRequeridoDescripción
account_sidyesTwilio Account SID (ACxxxxxxx)
auth_tokenyesTwilio Auth Token
api_key_sidnoAPI Key SID for WebRTC (SKxxxxxxx)
api_key_secretnoAPI Key Secret for WebRTC
POST /voice/credentials/verify | PATCH /voice/credentials | DELETE /voice/credentials

Verify credentials against Twilio API, update, or remove credentials entirely.

Audio & WebRTC

Suba audio para IVR y genere previews TTS. Obtenga tokens WebRTC para softphone.

POST /voice/audio/upload

Upload audio file for IVR greetings, hold music, etc. (multipart/form-data)

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/audio/upload \
  -H "Authorization: Bearer {token}" \
  -F "audio=@greeting.mp3" \
  -F "type=ivr_greeting"
POST /voice/audio/tts-preview

Generate a TTS (Text-to-Speech) audio preview.

Ejemplo

curl -X POST https://zapini.app/api/v1/voice/audio/tts-preview \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Welcome to our company. How can I help you?",
    "voice_id": "optional-elevenlabs-voice-id",
    "language": "pt-BR"
  }'
POST /voice/token

Get WebRTC capability token for browser-based softphone.

Respuesta

{
  "success": true,
  "data": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "identity": "tenant_29",
    "expires_in": 3600
  }
}

Códigos de Error

CodeHTTPDescripción
NO_VOICE_ACCESS403Funcionalidad Twilio Voice no habilitada en el tenant
NO_CREDENTIALS400Credenciales Twilio no configuradas
NUMBER_NOT_FOUND404Número de teléfono no encontrado o no autorizado
CALL_NOT_FOUND404Llamada no encontrada o no autorizada
MINUTES_EXCEEDED429Límite mensual de minutos excedido
CALL_NOT_ACTIVE400La llamada no está en curso
CALLBACK_EXPIRED400Callback expirado o ya ejecutado
IVR_NOT_ENABLED400IVR no está habilitado en este número

Configuración Completa

Para usar la API de Voz, siga estos pasos:

1

1. Guarde sus credenciales Twilio vía POST /credentials

2

2. Verifique las credenciales vía POST /credentials/verify

3

3. Registre un número vía POST /numbers

4

4. Configure el modo de atención (IA, humano o IVR)

5

5. Si IVR: configure opciones vía POST /numbers/{uuid}/ivr/options

6

6. Realice llamadas vía POST /calls o reciba vía WebRTC

API Kanban

21 endpoints

API Kanban

Gestiona tableros Kanban, columnas y leads programáticamente. Automatiza tu pipeline de ventas e intégrate con CRMs o herramientas de reporte.

URL Base

/api/v1/kanban

Autenticación

Bearer Token (sk_*)

Endpoints

21 endpoints

Acceso a Kanban requerido

Esta API requiere kanban_enabled en tu cuenta. Contacta al administrador para habilitar Kanban.

Tableros

GET /api/v1/kanban/boards Lista todos los tableros Kanban de la instancia actual.
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/kanban/boards"
POST /api/v1/kanban/boards Crea un nuevo tablero Kanban con columnas predeterminadas.
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"name":"Sales Pipeline","is_default":true}' \
  "https://zapini.app/api/v1/kanban/boards"
Body: name*, description, is_default
GET /api/v1/kanban/boards/{uuid} Obtiene detalles del tablero incluyendo columnas y estadísticas.
// Response includes stats + columns
{
  "uuid": "...",
  "name": "Sales Pipeline",
  "stats": {
    "total_leads": 12, "open_leads": 9, "won_leads": 2, "lost_leads": 1,
    "total_value": 15000.00, "won_value": 5000.00,
    "conversion_rate": 66.7, "avg_time_to_close": 14.5
  },
  "columns": [...]
}
PUT /api/v1/kanban/boards/{uuid}

Actualiza nombre, descripción o configuración del tablero.

DELETE /api/v1/kanban/boards/{uuid}

Elimina un tablero y todas sus columnas y leads.

Columnas

GET /api/v1/kanban/boards/{uuid}/columns Lista columnas de un tablero (ordenadas por posición).
POST /api/v1/kanban/boards/{uuid}/columns Crea una nueva columna en un tablero.
POST /api/v1/kanban/boards/{uuid}/columns/reorder Reordena columnas proporcionando array ordenado de UUIDs.
PUT /api/v1/kanban/columns/{uuid} Actualiza nombre, color o configuración de la columna.
DELETE /api/v1/kanban/columns/{uuid} Elimina una columna, opcionalmente moviendo leads a otra columna.

Ejemplo — Reorder Columns

curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"order":["col-uuid-1","col-uuid-2","col-uuid-3"]}' \
  "https://zapini.app/api/v1/kanban/boards/{board-uuid}/columns/reorder"

Leads

GET /api/v1/kanban/boards/{uuid}/leads Lista leads de un tablero con filtros opcionales.
POST /api/v1/kanban/leads Crea un nuevo lead en un tablero.
GET /api/v1/kanban/leads/{uuid} Obtiene detalles del lead incluyendo notas, campos personalizados y análisis IA.
PUT /api/v1/kanban/leads/{uuid} Actualiza campos del lead (título, valor, prioridad, etc.).
DELETE /api/v1/kanban/leads/{uuid} Elimina (soft delete) un lead.
POST /api/v1/kanban/leads/{uuid}/move Mueve un lead a una columna diferente.
POST /api/v1/kanban/leads/{uuid}/won Marca un lead como ganado.
POST /api/v1/kanban/leads/{uuid}/lost Marca un lead como perdido con razón opcional.
POST /api/v1/kanban/leads/{uuid}/note Agrega una nota con timestamp a un lead.
GET /api/v1/kanban/leads/{uuid}/activities Obtiene el historial de actividades de un lead.
POST /api/v1/kanban/leads/{uuid}/ai-qualify Ejecuta análisis de calificación IA en el lead.

Ejemplo — Crea un nuevo lead en un tablero.

curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "board_uuid": "board-uuid-here",
    "title": "John Doe - Pro Plan",
    "phone_number": "5511999999999",
    "email": "john@example.com",
    "value": 299.00,
    "priority": "high",
    "notes": "Interested in annual subscription"
  }' \
  "https://zapini.app/api/v1/kanban/leads"

Respuesta:

{
  "success": true,
  "data": {
    "uuid": "...",
    "title": "John Doe - Pro Plan",
    "phone_number": "5511999999999",
    "value": "299.00",
    "value_formatted": "R$ 299,00",
    "priority": "high",
    "priority_label": "High",
    "source": "api",
    "ai_score": null,
    "is_open": true, "is_won": false, "is_lost": false,
    "column": { "uuid": "...", "name": "New Lead", "color": "#3B82F6" }
  }
}

Parámetros de Consulta — GET /boards/{uuid}/leads

Campo Descripción
statusopen | won | lost | all (default: open)
prioritylow | medium | high | urgent
column_uuidFiltrar por UUID de columna
searchBuscar por nombre o número

API Calendario

9 endpoints

API Calendario

Gestiona citas y eventos de calendario. Crea, actualiza y rastrea transiciones de estado de citas programáticamente.

URL Base

/api/v1/calendar

Autenticación

Bearer Token (sk_*)

Endpoints

9 endpoints

Estados de Citas

scheduled Estado inicial — cita reservada
confirmed Cliente confirmó asistencia
completed Cita fue completada
cancelled Cita fue cancelada
no_show Cliente no se presentó

Citas

GET /api/v1/calendar/appointments Lista citas para un rango de fechas (predeterminado: mes actual).
POST /api/v1/calendar/appointments Crea una nueva cita.
GET /api/v1/calendar/appointments/{uuid} Obtiene detalles de una cita.
PUT /api/v1/calendar/appointments/{uuid} Actualiza detalles o estado de la cita.
DELETE /api/v1/calendar/appointments/{uuid} Elimina una cita.
POST /api/v1/calendar/appointments/{uuid}/confirm Transiciona estado de la cita a confirmado.
POST /api/v1/calendar/appointments/{uuid}/complete Transiciona estado de la cita a completado.
POST /api/v1/calendar/appointments/{uuid}/cancel Cancela una cita (no se puede cancelar citas ya completadas).
POST /api/v1/calendar/appointments/{uuid}/to-kanban Crea un lead Kanban a partir de esta cita.

Ejemplo — Create Appointment

curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "client_email": "john@example.com",
    "starts_at": "2026-05-01T10:00:00",
    "ends_at": "2026-05-01T11:00:00",
    "location": "Online - Google Meet",
    "reminder_minutes": 30
  }' \
  "https://zapini.app/api/v1/calendar/appointments"

Respuesta:

{
  "success": true,
  "data": {
    "uuid": "...",
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "starts_at": "2026-05-01T10:00:00+00:00",
    "ends_at": "2026-05-01T11:00:00+00:00",
    "duration_minutes": 60,
    "status": "scheduled",
    "color": "#3b82f6",
    "reminder_minutes": 30,
    "created_at": "2026-01-01T00:00:00+00:00"
  }
}

Parámetros de Consulta — GET /calendar/appointments

Campo Descripción Default
startFecha inicial (ISO 8601)Start of month
endFecha final (ISO 8601)End of month
statusscheduled | confirmed | completed | cancelled | no_show
per_pageItems por página (máx 100)50

Endpoint to-kanban

Convierte una cita en un lead Kanban. Requiere kanban_enabled en tu cuenta. Opcionalmente especifica board_uuid; de lo contrario se usa el tablero predeterminado.

curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"board_uuid": "optional-board-uuid"}' \
  "https://zapini.app/api/v1/calendar/appointments/{uuid}/to-kanban"

API de Funciones de IA

9 endpoints

API de Funciones de IA

Gestione funciones de IA (herramientas basadas en webhook) que su agente de IA puede llamar durante las conversaciones. Cree, configure, pruebe y monitoree funciones personalizadas que amplían las capacidades de su agente de IA.

⚡ Requiere una integración de Agente de IA activa en su cuenta.

Endpoints

Method Endpoint Description
GET/api/v1/ai-functionsListar Funciones de IA
POST/api/v1/ai-functionsCrear Función de IA
GET/api/v1/ai-functions/{uuid}Obtener Función de IA
PUT/api/v1/ai-functions/{uuid}Actualizar Función de IA
DELETE/api/v1/ai-functions/{uuid}Eliminar Función de IA
POST/api/v1/ai-functions/{uuid}/toggleAlternar Función de IA
POST/api/v1/ai-functions/{uuid}/testProbar Función de IA
GET/api/v1/ai-functions/{uuid}/executionsListar Ejecuciones
GET/api/v1/ai-functions/executions/{uuid}Detalles de Ejecución
GET /api/v1/ai-functions

Devuelve una lista paginada de todas las funciones de IA de su cuenta.

Query Parameters

integration_uuidFiltrar por UUID de integración
typeFiltrar por tipo de función
enabledFiltrar por estado de activación
searchBuscar por nombre o descripción
per_pageResults per page (max 100, default 20)

Example

curl -X GET "https://zapini.app/api/v1/ai-functions?type=fetch_data&enabled=true" \
  -H "Authorization: Bearer {token}"
POST /api/v1/ai-functions

Crea una nueva función de IA con parámetros opcionales. La función debe estar vinculada a una integración de Agente de IA.

Body Parameters

integration_uuid *UUID de la integración de Agente de IA
name *Nombre de la función (minúsculas, solo guiones bajos)
display_name *Nombre de visualización amigable
description *Descripción mostrada al agente de IA
type *Tipo de función: fetch_data, collect_submit, action
endpoint_urlURL del webhook a llamar
http_methodMétodo HTTP (GET, POST, PUT, PATCH, DELETE)
auth_typeTipo de autenticación: none, bearer, basic, api_key, custom
parametersArray de parámetros de la función
is_enabledSi la función está activa

Example

curl -X POST "https://zapini.app/api/v1/ai-functions" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_uuid": "abc-123-def",
    "name": "check_order_status",
    "display_name": "Check Order Status",
    "description": "Checks the status of a customer order by order number",
    "type": "fetch_data",
    "endpoint_url": "https://api.myshop.com/orders/status",
    "http_method": "GET",
    "auth_type": "bearer",
    "auth_config": {"token": "my-shop-api-key"},
    "parameters": [
      {
        "name": "order_number",
        "display_name": "Order Number",
        "description": "The customer order number",
        "type": "string",
        "is_required": true,
        "collect_from_user": true
      }
    ]
  }'
POST /api/v1/ai-functions/{uuid}/toggle

Alterna el estado activado/desactivado de una función de IA.

curl -X POST "https://zapini.app/api/v1/ai-functions/{uuid}/toggle" \
  -H "Authorization: Bearer {token}"
POST /api/v1/ai-functions/{uuid}/test

Ejecuta una llamada de prueba al endpoint de la función con los parámetros proporcionados.

curl -X POST "https://zapini.app/api/v1/ai-functions/{uuid}/test" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"parameters": {"order_number": "ORD-12345"}}'

Error Codes

AI_AGENT_NOT_ENABLED403 — AI_AGENT_NOT_ENABLED — Sin integración de Agente de IA activa
DUPLICATE_NAME422 — DUPLICATE_NAME — El nombre de la función ya existe
ACTIVE_EXECUTIONS409 — ACTIVE_EXECUTIONS — No se puede eliminar mientras hay ejecuciones en curso
INVALID_INTEGRATION_TYPE422 — INVALID_INTEGRATION_TYPE — La integración no es de tipo Agente de IA

API de Funciones Externas

8 endpoints

API de Funciones Externas

Gestione funciones externas — endpoints de webhook que permiten a sistemas externos activar acciones de WhatsApp (enviar mensajes, gestionar contactos, controlar automatizaciones). Cada función recibe una clave API única para autenticación.

⚡ Requiere una integración de Agente de IA activa en su cuenta.

Endpoints

Method Endpoint Description
GET/api/v1/external-functionsListar Funciones Externas
POST/api/v1/external-functionsCrear Función Externa
GET/api/v1/external-functions/{uuid}Obtener Función Externa
PUT/api/v1/external-functions/{uuid}Actualizar Función Externa
DELETE/api/v1/external-functions/{uuid}Eliminar Función Externa
POST/api/v1/external-functions/{uuid}/toggleAlternar Función Externa
POST/api/v1/external-functions/{uuid}/regenerate-keyRegenerar Clave API
GET/api/v1/external-functions/{uuid}/logsListar Logs
POST /api/v1/external-functions

Crea una nueva función externa con una clave API generada automáticamente. La clave API en texto plano solo se devuelve una vez — almacénela de forma segura.

Body Parameters

instance_uuid *UUID de la instancia de WhatsApp
name *Nombre de la función
slug *Slug de la URL (minúsculas, solo guiones)
action_type *Tipo de acción: send_message, send_buttons, send_media, create_contact, update_contact, create_lead, update_lead, pause_automation, resume_automation
descriptionDescripción de la función
configConfiguración específica de la acción
rate_limitMáximo de llamadas por día (por defecto: 1000)
allowed_ipsArray de direcciones IP permitidas (vacío = todas permitidas)
is_enabledSi la función está activa

Example

curl -X POST "https://zapini.app/api/v1/external-functions" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "instance_uuid": "abc-123-def",
    "name": "CRM Order Notification",
    "slug": "crm-order-notify",
    "action_type": "send_message",
    "description": "Sends order status updates from CRM",
    "config": {
      "message_template": "Order {{order_id}}: {{status}}"
    },
    "rate_limit": 500,
    "allowed_ips": ["203.0.113.10"]
  }'

⚠️ The api_key is returned only once in the create response. Store it securely — it cannot be retrieved later.

POST /api/v1/external-functions/{uuid}/regenerate-key

Genera una nueva clave API e invalida la anterior. La nueva clave solo se devuelve una vez.

curl -X POST "https://zapini.app/api/v1/external-functions/{uuid}/regenerate-key" \
  -H "Authorization: Bearer {token}"

Tipos de Acción Disponibles

send_messagesend_message — Enviar un mensaje de texto
send_buttonssend_buttons — Enviar un mensaje con botones
send_mediasend_media — Enviar multimedia (imagen, video, documento)
create_contactcreate_contact — Crear un nuevo contacto
update_contactupdate_contact — Actualizar un contacto existente
create_leadcreate_lead — Crear un lead en Kanban
update_leadupdate_lead — Actualizar un lead en Kanban
pause_automationpause_automation — Pausar automatización de IA de una conversación
resume_automationresume_automation — Reanudar automatización de IA de una conversación

Error Codes

AI_AGENT_NOT_ENABLED403 — AI_AGENT_NOT_ENABLED — Sin integración de Agente de IA activa
DUPLICATE_SLUG422 — DUPLICATE_SLUG — El slug ya existe para esta cuenta

¿Listo para Comenzar?

Crea tu cuenta ahora y comienza a integrar WhatsApp en tus aplicaciones con nuestra API potente y fácil de usar.