Carregando...

Documentação da API

Guia completo para integração com a API do Zapini

Baixar em Markdown

URL Base

https://instance-{id}.zapini.app

Autenticação

Bearer Token (Sanctum)

Rate Limit

100 requests / 15 min

Primeiros Passos

A API REST do Zapini permite integrar recursos de mensagens do WhatsApp em suas aplicações. Todas as requisições devem usar HTTPS e incluir autenticação Bearer token.

Tipos de API

O Zapini oferece dois tipos de API para diferentes necessidades. Escolha a que melhor se adapta ao seu caso de uso.

API Universal

https://zapini.app/api/v1

API REST completa para gerenciar todas as suas instâncias, conversas, contatos e configurações. Use esta API para aplicações web/mobile que precisam de acesso completo ao sistema.

Gerenciar múltiplas instâncias Conversas e contatos Tags e automações Estatísticas e relatórios

API da Instância

https://instance-{id}.zapini.app/

API direta para enviar mensagens com baixa latência. Cada instância WhatsApp possui sua própria URL dedicada. Ideal para bots e automações de alto volume.

Envio de mensagens (texto mídia) Status da conexão QR Code para conexão Webhooks em tempo real

Qual API devo usar?

Caso de Uso API Recomendada
Aplicativo web/mobile Universal (Token Sanctum)
Bot de mensagens Instância (Token sk_)
CRM / Sistema de atendimento Universal (Token Sanctum)
Envio em massa / campanhas Instância (Token sk_)
Integração externa simples Instância (Token sk_)

ID da Instância

A API aceita tanto ID numérico quanto UUID em todos os endpoints.

ID Numérico UUID
Exemplo 777 550e8400-e29b-...
Onde encontrar Exibido no card da instância. Exemplo: 777 Exibido na página de detalhes da instância. Exemplo: 550e8400-e29b-41d4-a716-446655440000

Com um token sk_, o parâmetro instance_id é opcional — ele é detectado automaticamente pelo token.

Headers Obrigatórios

Authorization: Bearer {token}
Accept: application/json
Content-Type: application/json

Formato de Resposta

Resposta de Sucesso

{
  "success": true,
  "message": "Operation completed",
  "data": { ... }
}

Resposta de Erro

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Error description",
    "details": {}
  }
}

Códigos HTTP

Código Descrição
200OK - Requisição bem-sucedida
201Created - Recurso criado com sucesso
400Bad Request - Parâmetros inválidos
401Unauthorized - Token inválido ou ausente
403Forbidden - Sem permissão para este recurso
404Not Found - Recurso não encontrado
422Unprocessable Entity - Erro de validação
429Too Many Requests - Limite de requisições excedido
500Internal Server Error - Erro interno do servidor

Autenticação

Tipos de Token

Existem dois tipos de tokens de autenticação, cada um adequado para diferentes cenários.

Token Sanctum

Token de usuário obtido via login. Dá acesso a todas as instâncias e recursos do seu tenant. Ideal para aplicações web/mobile onde o usuário faz login.

  • • Como obter: POST /auth/login com email e senha
  • • Formato: 1|abc123xyz...
  • • Acesso: Todas as instâncias do tenant

Token de Instância (sk_)

Token específico de uma instância WhatsApp. Gerado no painel administrativo. Ideal para integrações externas e bots.

  • • Como obter: Gerar no painel em Instâncias > Tokens API
  • • Formato: sk_xxxxxxxxxxxxxxxx
  • • Acesso: Apenas a instância específica

Ambos os tokens funcionam da mesma forma no header Authorization:

Authorization: Bearer {token}
POST /auth/login

Autentica um usuário e retorna um token de acesso.

Parâmetros

Campo Tipo Obrigatório Descrição
email string Sim E-mail do usuário
password string Sim Senha do usuário
device_name string Não Nome do dispositivo para identificação do token

Exemplo

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"
  }'

Resposta

{
  "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

Retorna informações do usuário autenticado.

Exemplo

curl -X GET https://instance-{id}.zapini.app/auth/me \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
POST /auth/logout

Revoga o token de acesso atual.

Exemplo

curl -X POST https://instance-{id}.zapini.app/auth/logout \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
POST /auth/refresh

Atualiza o token de acesso.

Exemplo

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

Instâncias

GET /instances

Lista todas as instâncias do WhatsApp da sua conta.

Parâmetros de Consulta

Campo Tipo Descrição
status string connected, disconnected, qr_ready, pending

Exemplo

curl -X GET "https://instance-{id}.zapini.app/instances?status=connected" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "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}

Retorna detalhes de uma instância específica.

A API aceita tanto ID numérico quanto UUID em todos os endpoints.

Exemplo

# 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

Retorna o QR code para conectar a instância.

Exemplo

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

Resposta

{
  "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

Retorna o status atual da instância.

Parâmetros de Consulta

Campo Tipo Descrição
realtime boolean Se true, verifica o status em tempo real no servidor

Exemplo

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

Retorna estatísticas de uso da instância.

Resposta

{
  "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 a instância do WhatsApp.

Exemplo

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

Inicia o processo de reconexão da instância.

Exemplo

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

Mensagens

API da Instância

API direta para enviar mensagens com baixa latência. Cada instância WhatsApp possui sua própria URL dedicada. Ideal para bots e automações de alto volume.

Base URL:

https://instance-{id}.zapini.app
Token de Instância (sk_) Obrigatório

API Universal - /chat/send

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

POST /send-message

Envia uma mensagem de texto para um número do WhatsApp.

Parâmetros

Campo Tipo Obrigatório Descrição
recipient (ou number, to) string Sim Número do WhatsApp do destinatário (com código do país) (5511999999999)
message string Sim Conteúdo da mensagem de texto
reply_to (ou quoted_message_id) string Não ID da mensagem para responder
Parâmetros alternativos: Os campos recipient, number e to são equivalentes. Assim como reply_to e quoted_message_id.

Exemplo

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."
  }'

Resposta

{
  "success": true,
  "message": "Message sent successfully",
  "message_id": "3EB0B430A8B7F23C1D12",
  "timestamp": "2025-12-30T17:30:00.000Z"
}
POST /send-media

Envia uma mensagem com mídia (imagem, vídeo, áudio, documento).

Parâmetros

Campo Tipo Obrigatório Descrição
recipient (ou number, to) string Sim Número do WhatsApp do destinatário (com código do país) (5511999999999)
media_url (ou url) string Sim URL pública do arquivo de mídia
media_type (ou type) string Sim image, video, audio, document
caption string Não Legenda para imagens e vídeos
filename string Não Nome do arquivo para documentos
Parâmetros alternativos: Os campos recipient/number/to, media_url/url e media_type/type são equivalentes.

Exemplo

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!"
  }'

Resposta

{
  "success": true,
  "message": "Media sent successfully",
  "message_id": "3EB0B430A8B7F23C1D13",
  "timestamp": "2025-12-30T17:30:00.000Z"
}
POST /send-reaction

Envia um emoji de reação para uma mensagem específica.

Parâmetros

Campo Tipo Obrigatório Descrição
to string Sim JID do chat
messageId string Sim ID da mensagem para reagir
emoji string Sim Emoji da reação (ex: 👍, ❤️, 😂)

Exemplo

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

Retorna o status atual de conexão da instância do WhatsApp.

Exemplo

curl -X GET https://instance-{id}.zapini.app/status \
  -H "Authorization: Bearer {token}"

Resposta

{
  "success": true,
  "status": "connected",
  "phone": "5511999999999",
  "name": "Meu WhatsApp",
  "platform": "android"
}
GET /qr

Retorna o QR code para conectar a instância do WhatsApp. Disponível apenas quando o status é qr_ready.

Exemplo

curl -X GET https://instance-{id}.zapini.app/qr \
  -H "Authorization: Bearer {token}"

Resposta

{
  "success": true,
  "qr": "data:image/png;base64,iVBORw0KGgoAAAA...",
  "status": "qr_ready"
}
GET /health

Retorna o status de saúde do servidor da API. Não requer autenticação.

Exemplo

curl -X GET https://instance-{id}.zapini.app/health

Resposta

{
  "status": "ok",
  "uptime": 123456,
  "timestamp": "2025-12-15T14:30:00.000Z"
}

Conversas

GET /conversations

Lista todas as conversas ativas.

Parâmetros de Consulta

Campo Tipo Descrição
instance_id string Filtrar por instância (UUID)
unread boolean Mostrar apenas conversas não lidas
search string Buscar por nome ou número
is_group boolean Filtrar por grupos (true/false)
per_page integer Itens por página (max 100)
include_tags boolean Incluir tags da conversa na resposta
tag_id uuid Filtrar por ID da tag
tag_ids uuid[] Filtrar por múltiplos UUIDs de tags (separados por vírgula ou array)
untagged boolean Mostrar apenas conversas sem tags
format string Usar formato de resposta otimizado para chat (chat)

?format=chat: A Chat API retorna os mesmos dados dos endpoints padrão, mas com campos adicionais otimizados para renderização de UI. Você também pode usar ?format=chat nos endpoints padrão.

Exemplo

curl -X GET "https://instance-{id}.zapini.app/conversations?unread=true&per_page=20" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "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}

Retorna detalhes de uma conversa específica.

GET /conversations/{uuid}/messages

Retorna o histórico de mensagens de uma conversa.

Parâmetros de Consulta

Campo Tipo Descrição
from datetime Data inicial (ISO 8601)
to datetime Data final (ISO 8601)
before_id integer Mensagens antes deste ID
after_id integer Mensagens após este ID
limit integer Limite de mensagens (max 100)
format string Usar formato de resposta otimizado para chat (chat)

?format=chat: Retorna mensagens com formatted_body (@menções resolvidas) e reações agrupadas.

POST /conversations/{uuid}/mark-read

Marca uma conversa como lida.

POST /conversations/{uuid}/archive

Arquiva uma conversa.

Resposta

{
  "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 uma conversa arquivada para status ativo.

O UUID deve ser de uma conversa arquivada. Use GET /conversations/archived para listar conversas arquivadas.

Resposta

{
  "success": true,
  "message": "Conversation restored.",
  "data": {
    "conversation_id": "550e8400-e29b-41d4-a716-446655440045",
    "restored": true
  }
}
DELETE /conversations/{uuid}

Exclui uma conversa e suas mensagens.

Controle de Automação

Gerencie a automação de IA para conversas. Quando a automação está ativa, mensagens manuais são bloqueadas até você assumir o chat.

Importante: Comportamento da Automação

  • Quando a automação está ativa, mensagens manuais são bloqueadas para evitar conflitos com respostas da IA.
  • Use "pause" para assumir o chat e enviar mensagens manualmente.
  • Use "resume" para deixar a IA gerenciar a conversa novamente.
  • IMPORTANTE: Para retomar a automação, você deve primeiro arquivar a conversa.

Segurança: Arquivamento Obrigatório para Retomar

A automação só pode ser retomada após arquivar a conversa. Isso garante que a sessão de atendimento manual seja encerrada corretamente antes de devolver o controle à IA. Ao retomar, a conversa será automaticamente desarquivada.

GET /conversations/{uuid}/automation

Retorna o status atual da automação para uma conversa.

Resposta

{
  "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 a automação para uma conversa, permitindo mensagens manuais.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
reason string Não Motivo opcional para pausar a automação

Exemplo

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"}'

Resposta

{
  "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

Retoma a automação para uma conversa, deixando a IA gerenciar as respostas.

Resposta

{
  "success": true,
  "message": "Automation resumed. AI will handle this conversation.",
  "data": {
    "automation_status": "active"
  }
}
POST /conversations/automation/bulk-pause

Pausa a automação para múltiplas conversas de uma vez.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
conversation_ids array Sim Array de IDs de conversas para processar
reason string Não Motivo opcional para pausar a automação

Exemplo

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"]}'

Resposta

{
  "success": true,
  "message": "3 conversations paused successfully."
}
POST /conversations/automation/bulk-resume

Retoma a automação para múltiplas conversas de uma vez.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
conversation_ids array Sim Array de IDs de conversas para processar

Resposta

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

Contatos

GET /contacts

Lista todos os contatos salvos.

Parâmetros de Consulta

Campo Tipo Descrição
instance_id string Filtrar por instância (UUID)
search string Buscar por nome ou número
per_page integer Itens por página (max 100)

Exemplo

curl -X GET "https://instance-{id}.zapini.app/contacts?search=john&per_page=50" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "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

Cria um novo contato.

Parâmetros

Campo Tipo Obrigatório Descrição
instance_id string Sim ID da instância
phone_number string Sim Número de telefone do contato
name string Não Nome do contato
email string Não E-mail do contato
company string Não Empresa do contato
notes string Não Observações sobre o contato

Exemplo

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}

Retorna detalhes de um contato específico.

PUT /contacts/{id}

Atualiza um contato existente.

Parâmetros

Campo Tipo Descrição
name string Nome do contato
email string E-mail do contato
company string Empresa do contato
notes string Observações sobre o contato
DELETE /contacts/{id}

Exclui um contato.

POST /contacts/import

Importa múltiplos contatos de uma vez.

Parâmetros

Campo Tipo Obrigatório Descrição
instance_id string Sim ID da instância
contacts array Sim Array de objetos de contato

Exemplo

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"}
    ]
  }'

Resposta

{
  "success": true,
  "message": "Contacts imported successfully",
  "data": {
    "imported": 2,
    "skipped": 0,
    "errors": []
  }
}
GET /contacts/export

Exporta contatos em formato JSON ou CSV.

Parâmetros de Consulta

Campo Tipo Descrição
instance_id string Filtrar por instância (UUID)
format string json, csv (default: json)

Exemplo

curl -X GET "https://instance-{id}.zapini.app/contacts/export?format=csv" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Webhooks

Sistema de Webhooks

Webhooks permitem que você receba notificações em tempo real sobre eventos nas suas instâncias do WhatsApp.

Webhooks de Entrada

URLs que o Zapini usa para receber dados das suas instâncias WhatsApp.

Webhooks de Saída

URLs que você configura para receber notificações do Zapini.

Webhooks de Saída

Receba notificações em tempo real no seu servidor

NEW

Configure webhooks para receber notificações em tempo real quando eventos ocorrerem na sua instância do WhatsApp. O Zapini enviará requisições HTTP POST para sua URL configurada com os dados do evento.

Como Configurar

  1. Vá para as configurações do seu Token de API e clique em "Configurar Webhook"
  2. Insira sua URL de webhook (deve ser HTTPS em produção)
  3. Gere ou insira uma chave secreta para verificação de assinatura
  4. Selecione quais eventos deseja receber e salve

Eventos Disponíveis

Evento Descrição
message.received Nova mensagem recebida
message.sent Mensagem enviada
message.status Status da mensagem alterado (enviada, entregue, lida)
instance.connected Instância conectou ao WhatsApp
instance.disconnected Instância desconectou
instance.qr Novo QR code gerado

Entendendo os IDs de Mensagem

Cada mensagem tem dois identificadores. Use o correto dependendo do seu caso de uso:

Campo Formato Uso
message_id UUID (e.g., 055f01b2-da7b-476b-...) Chave primária para deduplicação e rastreamento no seu sistema
whatsapp_message_id WhatsApp ID (e.g., 3EB0ABC123456789) Necessário para reações, respostas e operações do WhatsApp

Dica: Como evitar duplicatas

Armazene o message_id quando receber um webhook. Antes de processar novos webhooks, verifique se o message_id já existe no seu banco de dados. Se existir, atualize o registro existente em vez de criar um novo.

Formato da Requisição

Cada requisição de webhook é enviada como HTTP POST com os seguintes 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 do Webhook

Header Descrição
X-Webhook-Signature Assinatura HMAC-SHA256 do payload JSON usando sua chave secreta
X-Webhook-Event O tipo de evento que disparou este webhook
X-Instance-UUID UUID da instância do WhatsApp
User-Agent Zapini-Webhook/1.0

Exemplos 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

Recebe mensagens de entrada das instâncias WhatsApp.

Formato do 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 Mensagem

Tipo Campo Descrição
Text message.conversation Mensagem de texto simples
Extended Text message.extendedTextMessage Texto com preview de link
Image message.imageMessage Imagem com legenda
Video message.videoMessage Mensagem de vídeo
Audio message.audioMessage Mensagem de áudio/voz
Document message.documentMessage Arquivo/documento

Exemplo - Mensagem 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

Recebe atualizações de status de mensagens enviadas.

Formato do Payload

{
  "key": {
    "remoteJid": "5511999999999@s.whatsapp.net",
    "id": "3EB0ABC123456789",
    "fromMe": true
  },
  "status": 3,
  "messageTimestamp": 1705312200
}

Códigos de Status

Código Status Descrição
1 pending Mensagem pendente de envio
2 sent Mensagem enviada ao servidor
3 delivered Mensagem entregue ao destinatário
4 read Mensagem lida pelo destinatário
5 played Áudio/vídeo reproduzido
POST /webhooks/instance/{uuid}/qr

Recebe atualizações de QR code para conexão.

Formato do Payload

{
  "qr": "2@ABC123...",
  "qr_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "generated_at": "2025-01-15T10:30:00Z"
}
POST /webhooks/instance/{uuid}/connection

Recebe atualizações do status de conexão da instância.

Formato do Payload

{
  "status": "connected",
  "phone_number": "5511999999999",
  "timestamp": "2025-01-15T10:30:00Z"
}

Status de Conexão

Status Descrição
connected Instância conectada e funcionando
qr_ready QR code pronto para escanear
disconnected Instância desconectada
offline Instância offline
POST /webhooks/instance/{uuid}/reaction

Recebe reações emoji em mensagens.

Formato do 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 uma URL externa para receber notificações de eventos.

Parâmetros

Campo Tipo Obrigatório Descrição
webhook_url string Sim URL que receberá as notificações via POST
webhook_secret string Não Chave secreta para assinatura das requisições
events array Não Eventos que dispararão o webhook
is_active boolean Não Ativar ou desativar o webhook

Eventos Disponíveis

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

Exemplo

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
  }'

Segurança de Webhooks

Todas as requisições de webhook incluem uma assinatura HMAC para verificação de autenticidade.

Verificação de Assinatura

Cada requisição inclui um header X-Webhook-Signature com a assinatura HMAC-SHA256 do payload.

Header:

X-Webhook-Signature: a1b2c3d4e5f6789...

Verificar Assinatura (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 Assinatura (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');
    }
});

Boas Práticas

  • Sempre verifique a assinatura antes de processar o webhook.
  • Responda rapidamente (dentro de 5 segundos) para evitar timeouts.
  • Use uma fila para processar webhooks de forma assíncrona.
  • Implemente idempotência para lidar com webhooks duplicados.
  • Registre todos os webhooks recebidos para depuração.

Mídia

Gerenciamento de Mídia

Envie e gerencie arquivos de mídia como imagens, vídeos, áudios e documentos.

📷
Imagens
jpg, png, gif, webp
🎥
Vídeos
mp4, 3gp, mov
🎵
Áudio
mp3, ogg, wav, opus
📄
Documentos
pdf, doc, xls, etc
POST /media/upload

Faz upload de um arquivo de mídia para uso posterior.

Parâmetros

Campo Tipo Obrigatório Descrição
file file Sim Arquivo de mídia para upload (multipart/form-data)
type string Não image, video, audio, document (auto-detected)

Exemplo

curl -X POST https://instance-{id}.zapini.app/media/upload \
  -H "Authorization: Bearer {token}" \
  -F "file=@/path/to/image.jpg" \
  -F "type=image"

Resposta

{
  "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}

Retorna informações de um arquivo de mídia.

Resposta

{
  "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}

Exclui um arquivo de mídia.

Exemplo

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

Envia uma mensagem com mídia anexada.

Parâmetros

Campo Tipo Obrigatório Descrição
instance_id string Sim ID da instância
recipient string Sim Número do WhatsApp do destinatário (com código do país)
media_url string Sim* URL pública do arquivo de mídia
media_id string Sim* ID de uma mídia previamente enviada via upload
media_type string Sim image, video, audio, document
caption string Não Legenda para imagens e vídeos
filename string Não Nome do arquivo para documentos

* Forneça media_url OU media_id

Exemplo - Imagem

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!"
  }'

Exemplo - 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"
  }'

Limites de Mídia

Tipo Tamanho Máximo Formatos
Imagens 16 MB jpg, jpeg, png, gif, webp
Vídeos 64 MB mp4, 3gp, mov, avi, mkv
Áudio 16 MB mp3, ogg, wav, opus, aac, m4a
Documentos 100 MB pdf, doc, docx, xls, xlsx, ppt, pptx, txt, zip
GET /messages/{uuid}/media

Faz download de mídia recebida em uma mensagem.

Exemplo

curl -X GET https://instance-{id}.zapini.app/messages/660e8400-e29b-41d4-a716-446655440001/media \
  -H "Authorization: Bearer {token}" \
  --output downloaded_media.jpg

Resposta

Retorna o arquivo binário com o Content-Type apropriado.

Grupos

Gerencie grupos do WhatsApp através da API. Crie grupos, adicione/remova participantes, atualize configurações e muito mais.

GET /instances/{uuid}/groups

Retorna todos os grupos do WhatsApp da instância.

Exemplo

curl -X GET "https://instance-{id}.zapini.app/instances/{uuid}/groups" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "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

Cria um novo grupo do WhatsApp.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
subject string Sim api-docs.group_subject_desc
participants array Sim api-docs.group_participants_desc

Exemplo

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"]
  }'

Resposta

{
  "success": true,
  "data": {
    "group": {
      "jid": "120363001234567890@g.us",
      "subject": "My New Group"
    },
    "message": "Group created successfully"
  }
}
GET /instances/{uuid}/groups/{jid}

Retorna metadados detalhados de um grupo específico.

Resposta

{
  "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}

Atualiza o nome e/ou descrição do grupo.

Corpo da Requisição

Campo Tipo Descrição
subject string Novo nome do grupo
description string Nova descrição do grupo

Exemplo

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

Adiciona um ou mais participantes ao grupo.

Exemplo

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

Remove um ou mais participantes do grupo.

Exemplo

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

Exemplo

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

Exemplo

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

Faz a instância sair de um grupo.

Exemplo

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

Resposta

{
  "success": true,
  "data": {
    "code": "AbCdEfGhIjKl",
    "invite_link": "https://chat.whatsapp.com/AbCdEfGhIjKl"
  }
}
DELETE /instances/{uuid}/groups/{jid}/invite

api-docs.groups_invite_revoke_desc

Resposta

{
  "success": true,
  "data": {
    "new_code": "MnOpQrStUvWx",
    "new_invite_link": "https://chat.whatsapp.com/MnOpQrStUvWx"
  },
  "message": "Invite link revoked"
}

Tags

Gerencie tags de conversas para organizar e categorizar chats. Tags são escopadas por tenant e podem ser atribuídas a múltiplas conversas.

GET /tags

Lista todas as tags do tenant atual.

Exemplo

curl -X GET "https://instance-{id}.zapini.app/tags" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "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

Cria uma nova tag.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
name string Sim Nome da tag (único por tenant) (max 50)
color string Sim Código de cor hexadecimal para a tag (#RRGGBB)

Exemplo

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"
  }'

Resposta

{
  "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}

Retorna detalhes de uma tag específica.

Exemplo

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}

Atualiza uma tag existente.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
name string Não Nome da tag (único por tenant) (max 50)
color string Não Código de cor hexadecimal para a tag (#RRGGBB)

Exemplo

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}

Exclui uma tag. A tag será automaticamente removida de todas as conversas.

Exemplo

curl -X DELETE "https://instance-{id}.zapini.app/tags/550e8400-e29b-41d4-a716-446655440001" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Resposta

{
  "success": true,
  "message": "Tag deleted successfully"
}
PUT /conversations/{uuid}/tags

Atualiza as tags atribuídas a uma conversa. Isso substitui todas as tags existentes pela lista fornecida.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
tag_ids array Sim Array de UUIDs de tags para atribuir à conversa

Exemplo

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"]
  }'

Resposta

{
  "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 remover todas as tags de uma conversa, envie um array vazio: {"tag_ids": []}

Chat API

OTIMIZADO PARA UI

Endpoints otimizados para criar interfaces de chat tipo WhatsApp. Retorna dados pré-formatados com @menções resolvidas, reações agrupadas e helpers de alinhamento.

formatted_body

@menções pré-resolvidas em formato HTML

grouped_reactions

Reações agrupadas com contagem

is_from_me

Alinhamento fácil com is_from_me

tags

Tags das conversas incluídas

A Chat API retorna os mesmos dados dos endpoints padrão, mas com campos adicionais otimizados para renderização de UI. Você também pode usar ?format=chat nos endpoints padrão.

/api/v1/conversations?format=chat
GET /api/v1/chat/conversations

Lista conversas com tags, fotos de perfil e contagem de não lidas otimizada para UI de lista de chat.

Parâmetros de Consulta

Campo Tipo Descrição
instance_id string Filtrar por instância (UUID)
search string Buscar por nome ou número
unread boolean Mostrar apenas conversas não lidas
per_page integer Itens por página (max 100)

Exemplo

curl -X GET "https://zapini.app/api/v1/chat/conversations?unread=true" \
  -H "Authorization: Bearer {token}"

Resposta

{
  "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

Retorna mensagens com formatted_body (@menções resolvidas) e reações agrupadas.

Parâmetros de Consulta

Campo Tipo Descrição
before_id integer Mensagens antes deste ID
after_id integer Mensagens após este ID
limit integer Limite de mensagens (max 100)

Exemplo

curl -X GET "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/messages?limit=50" \
  -H "Authorization: Bearer {token}"

Resposta

{
  "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
  }
}

Recursos Principais

formatted_body

Texto da mensagem com @menções resolvidas para nomes de contatos. Retorna HTML com spans clicáveis.

Olá @João Silva!
is_from_me

Boolean indicando se a mensagem foi enviada pela sua instância. Use para alinhamento de mensagens.

grouped_reactions

Reações agrupadas por emoji com contagens e informações dos reagentes.

{"emoji": "👍", "count": 2, "has_my_reaction": true}
mentioned_jids

Array de JIDs do WhatsApp mencionados na mensagem.

POST /api/v1/chat/send

Envia uma mensagem de texto e retorna a mensagem em formato otimizado para chat.

Parâmetros

Campo Tipo Obrigatório Descrição
instance_id string Sim UUID da instância (obrigatório)
recipient string Sim Número de telefone do destinatário com código do país
message string Sim Conteúdo da mensagem de texto
reply_to string Não ID da mensagem para responder

Exemplo

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

Envia mídia (imagem, vídeo, áudio, documento) e retorna resposta otimizada para chat.

Parâmetros

Campo Tipo Obrigatório Descrição
instance_id string Sim UUID da instância (obrigatório)
recipient string Sim Número de telefone do destinatário com código do país
media_url string Sim URL do arquivo de mídia a enviar
media_type string Sim Tipo de mídia (image, video, audio, document)
caption string Não Legenda para imagem/vídeo

Exemplo

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 o conteúdo de uma mensagem enviada.

Parâmetros

Campo Tipo Obrigatório Descrição
message string Sim Novo conteúdo da mensagem

Exemplo

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}

Exclui uma mensagem enviada.

Exemplo

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

Adiciona uma reação emoji a uma mensagem.

Parâmetros

Campo Tipo Obrigatório Descrição
emoji string Sim Emoji para reagir

Exemplo

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

Remove uma reação de uma mensagem.

Exemplo

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 uma conversa como lida.

Exemplo

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

Arquiva uma conversa.

Exemplo

curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/archive" \
  -H "Authorization: Bearer {token}"

Resposta

{
  "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 uma conversa arquivada para status ativo.

O UUID deve ser de uma conversa arquivada. Use GET /conversations/archived para listar conversas arquivadas.

Exemplo

curl -X DELETE "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/archive" \
  -H "Authorization: Bearer {token}"

Resposta

{
  "success": true,
  "message": "Conversation restored.",
  "data": {
    "conversation_id": "550e8400-e29b-41d4-a716-446655440045",
    "restored": true
  }
}
POST /api/v1/chat/conversations/{uuid}/pause-automation

Pausar a automação de uma conversa para permitir envio de mensagens manuais.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
reason string Não Motivo opcional para pausar a automação

Exemplo

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

Retomar a automação de uma conversa, devolvendo o controle ao sistema automatizado.

Exemplo

curl -X POST "https://zapini.app/api/v1/chat/conversations/550e8400-e29b-41d4-a716-446655440045/resume-automation" \
  -H "Authorization: Bearer {token}"

Transcrição de Áudio

Os campos de transcrição também são incluídos no objeto de mensagem retornado pelo endpoint de mensagens. Mensagens de áudio com auto-transcrição habilitada terão as transcrições preenchidas automaticamente.

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

Obtém o status e texto da transcrição de uma mensagem de áudio.

Exemplo

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

Resposta

{
  "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 da Resposta

Campo Tipo Descrição
audio_transcription string|null O texto transcrito (null se ainda não concluído)
transcription_status string|null Status: pending, processing, completed ou failed
transcription_language string|null Código do idioma detectado ou configurado (ex. pt, en, es)
transcription_error string|null Mensagem de erro se a transcrição falhou
transcription_completed_at string|null Timestamp de quando a transcrição foi concluída
POST /api/v1/chat/messages/{uuid}/transcription

Solicita a transcrição de uma mensagem de áudio. Se já foi concluída, retorna a transcrição existente. Suporta provedores Whisper, Gemini e ElevenLabs.

Exemplo

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

Resposta

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

Automações

IMPORTANTE

Aviso Importante sobre Automações

Se sua instância tem automações (fluxos ou integrações) ativas, o envio de mensagens via API pode ser bloqueado. Leia esta seção para entender como funciona.

O que são Automações?

Automações são fluxos automatizados que respondem mensagens automaticamente. O sistema possui dois tipos de automação:

Fluxos

Fluxos de conversação criados no editor visual que respondem automaticamente baseado em regras e condições.

Integrações

Conexões com sistemas externos (webhooks, APIs, IA) que processam e respondem mensagens automaticamente.

Bloqueio de Mensagens

Quando uma conversa tem automação ativa, o envio de mensagens pela API é bloqueado para evitar conflitos entre respostas automáticas e manuais.

Resposta de Erro

{
  "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
  }
}

Quando o Envio é Bloqueado?

  • • A instância tem um fluxo ou integração ativa
  • • A conversa não foi pausada manualmente
  • • A conversa ainda está sendo gerenciada pela automação

Como Enviar Mensagens com Automação Ativa

Para enviar mensagens manualmente quando há automação ativa, você precisa pausar a automação para a conversa específica:

1

Verifique o Status

Use o endpoint de detalhes da conversa para verificar o campo automation_status.

2

Pause a Automação

Se automation_status for "active", use o endpoint de pausa para permitir mensagens manuais.

3

Envie a Mensagem

Após pausar, você pode enviar mensagens normalmente via API.

GET /api/v1/chat/conversations/{uuid}

Verifique o status de automação de uma conversa antes de tentar enviar mensagens.

Campos de Resposta

Campo Tipo Descrição
automation_status string Status atual da automação (active ou paused)
can_send_manual_message boolean Se você pode enviar mensagens manuais
automation_paused_at datetime|null Data/hora de quando a automação foi pausada

Valores de Status

Status Descrição Pode Enviar via API?
active Automação está respondendo mensagens automaticamente Não
paused Automação pausada, usuário assumiu o controle Sim
POST /api/v1/chat/conversations/{uuid}/pause-automation

Pausa a automação para permitir envio de mensagens manuais via API.

Corpo da Requisição (optional)

Campo Tipo Descrição
reason string Motivo opcional para pausar (ex.: "Intervenção manual necessária")

Exemplo

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"}'

Exemplo de Resposta

{
  "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

Retoma a automação, devolvendo o controle ao sistema automatizado.

Exemplo

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"

Exemplo de Resposta

{
  "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"
  }
}

Operações em Lote

Pause ou retome a automação de múltiplas conversas de uma vez. Útil para manutenção, campanhas ou processamento em lote. Máximo de 100 conversas por requisição.

POST /api/v1/conversations/automation/bulk-pause

Pausa a automação de múltiplas conversas de uma vez. Ignora conversas que já estão pausadas ou não têm automação ativa.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
conversation_ids array Sim Array de UUIDs de conversas (máx 100)
reason string Não Motivo opcional para pausar (ex.: "Intervenção manual necessária")

Exemplo

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"
  }'

Resposta

{
  "success": true,
  "message": "2 conversations paused",
  "data": {
    "paused": 2,
    "skipped": 0,
    "errors": 0
  }
}
POST /api/v1/conversations/automation/bulk-resume

Retoma a automação de múltiplas conversas de uma vez. Ignora conversas que não estão pausadas ou não têm automação ativa.

Corpo da Requisição

Campo Tipo Obrigatório Descrição
conversation_ids array Sim Array de UUIDs de conversas (máx 100)

Exemplo

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"
    ]
  }'

Resposta

{
  "success": true,
  "message": "2 automations resumed",
  "data": {
    "resumed": 2,
    "skipped": 0,
    "errors": 0
  }
}

Boas Práticas

  • Sempre verifique can_send_manual_message antes de enviar mensagens para evitar erros.
  • Pause a automação apenas quando necessário para intervenção humana.
  • Retome a automação após o atendimento manual para manter a experiência consistente.

API de Voz & URA

62 endpoints

Visão Geral da API de Voz

A API de Voz permite gerenciar toda a infraestrutura de telefonia programaticamente: números de telefone, configuração de URA, ligações, filas, callbacks, skills de agentes e clonagem de voz.

URL Base

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

Autenticação

Autenticação Bearer Token + Permissão Twilio Voice

Endpoints

62 endpoints disponíveis

Esta API requer que a funcionalidade Twilio Voice esteja habilitada no seu tenant. Contate o administrador para ativar.

Números de Telefone

Gerencie números de telefone: cadastrar, configurar modo de atendimento (IA, humano, URA), gravação, SIP e mais.

Modos de atendimento disponíveis

ai_onlySomente IA - A IA atende todas as ligações automaticamente
human_onlySomente Humano - Ligações direcionadas para agentes humanos via WebRTC
ai_with_handoffIA com Transferência - IA atende e pode transferir para humano
ivr_menuMenu URA - Menu interativo com opções numéricas
GET /voice/numbers

Gerencie números de telefone: cadastrar, configurar modo de atendimento (IA, humano, URA), gravação, SIP e mais.

Exemplo

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

Resposta

{
  "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âmetroTipoObrigatórioDescrição
phone_numberstringyesE.164 format (+5511999999999)
friendly_namestringnoDisplay name
connection_typestringnotwilio, asterisk_sip, asterisk_hardphone

Exemplo

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âmetroTipoDescrição
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.

Horário de Funcionamento & Feriados

Configure horários de atendimento e feriados para cada número. Ligações fora do horário podem ser redirecionadas automaticamente.

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

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

Resposta

{
  "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

Gerencie feriados com mensagens personalizadas. Suporta feriados recorrentes (anuais) e datas específicas.

Resposta

{
  "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).

Configuração da URA (IVR)

Configure menus interativos de voz com opções numéricas, mensagens TTS, coleta de dados, transferências e mais.

Tipos de Opção da URA

collect_cpfColetar CPF do chamador
collect_numberColetar número digitado
record_voiceGravar mensagem de voz
transfer_agentTransferir para agente humano
transfer_aiTransferir para atendimento IA
transfer_externalTransferir para número externo
play_messageReproduzir mensagem
submenuAbrir submenu
callbackSolicitar callback
scheduleAgendar atendimento
customAção personalizada
GET /voice/numbers/{uuid}/ivr

Get full IVR configuration including messages, timeouts and options.

Resposta

{
  "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âmetroTipoDescrição
ivr_enabledbooleanCampos de configuração da URA
ivr_welcome_messagestringMensagem de boas-vindas reproduzida ao atender
ivr_menu_introstringTexto do menu com as opções disponíveis
ivr_invalid_option_messagestringMensagem para opção inválida
ivr_goodbye_messagestringMensagem de despedida
ivr_input_timeoutintegerTempo de espera por input (1-30 segundos)
ivr_max_attemptsintegerMáximo de tentativas inválidas (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.

Exemplo

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.

Chamadores VIP

Gerencie chamadores prioritários com roteamento personalizado. Chamadores VIP podem pular a fila ou receber atendimento diferenciado.

Níveis de prioridade

vipVIP - Máxima prioridade, pula fila
priorityPrioridade - Atendimento preferencial
standardPadrão - Atendimento normal
blockedBloqueado - Ligações rejeitadas automaticamente
GET /voice/numbers/{uuid}/vip-callers

List all VIP callers for a phone number.

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

Add a VIP caller.

Exemplo

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.

Gerenciamento de Fila

Configure e monitore filas de atendimento com música de espera, anúncio de posição e callback automático.

GET /voice/numbers/{uuid}/queue

Get queue status, configuration and metrics.

Resposta

{
  "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.

Ligações

Inicie, monitore e gerencie ligações. Inclui transferência para IA, estatísticas e custos detalhados.

GET /voice/calls

List calls with filters.

Filtros disponíveis

ParâmetroTipoDescrição
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)

Exemplo

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.

Exemplo

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.

Resposta

{
  "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

Gerencie solicitações de callback: listar, executar, cancelar e reagendar.

GET /voice/callbacks

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

Exemplo

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

Gerencie competências dos agentes para roteamento inteligente de ligações baseado em 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).

Exemplo

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
  }'

Vozes Clonadas

Clone vozes usando IA para uso em URA e atendimento automatizado. Upload de amostras de áudio para criar vozes personalizadas.

GET /voice/voices

List all cloned voices for the tenant.

POST /voice/voices

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

Exemplo

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.

Credenciais Twilio

Gerencie credenciais de acesso ao Twilio: Account SID, Auth Token e API Keys para WebRTC.

GET /voice/credentials

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

Resposta

{
  "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âmetroObrigatórioDescrição
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.

Áudio & WebRTC

Upload de áudio para URA e gere previews de TTS. Obtenha tokens WebRTC para softphone.

POST /voice/audio/upload

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

Exemplo

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.

Exemplo

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.

Resposta

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

Códigos de Erro

CodeHTTPDescrição
NO_VOICE_ACCESS403Funcionalidade Twilio Voice não habilitada no tenant
NO_CREDENTIALS400Credenciais Twilio não configuradas
NUMBER_NOT_FOUND404Número de telefone não encontrado ou não autorizado
CALL_NOT_FOUND404Ligação não encontrada ou não autorizada
MINUTES_EXCEEDED429Limite mensal de minutos excedido
CALL_NOT_ACTIVE400Ligação não está em andamento
CALLBACK_EXPIRED400Callback expirado ou já executado
IVR_NOT_ENABLED400URA não está habilitada neste número

Configuração Completa

Para usar a API de Voz, siga estes passos:

1

1. Salve suas credenciais Twilio via POST /credentials

2

2. Verifique as credenciais via POST /credentials/verify

3

3. Cadastre um número via POST /numbers

4

4. Configure o modo de atendimento (IA, humano ou URA)

5

5. Se URA: configure opções via POST /numbers/{uuid}/ivr/options

6

6. Inicie ligações via POST /calls ou receba via WebRTC

API Kanban

21 endpoints

API Kanban

Gerencie quadros Kanban, colunas e leads programaticamente. Automatize seu pipeline de vendas e integre com CRMs ou ferramentas de relatório.

URL Base

/api/v1/kanban

Autenticação

Bearer Token (sk_*)

Endpoints

21 endpoints

Acesso ao Kanban obrigatório

Esta API requer kanban_enabled na sua conta. Contate o administrador para habilitar o Kanban.

Quadros

GET /api/v1/kanban/boards Lista todos os quadros Kanban da instância atual.
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/kanban/boards"
POST /api/v1/kanban/boards Cria um novo quadro Kanban com colunas padrão.
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} Obtém detalhes do quadro incluindo colunas e estatí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}

Atualiza nome, descrição ou configurações do quadro.

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

Exclui um quadro e todas as suas colunas e leads.

Colunas

GET /api/v1/kanban/boards/{uuid}/columns Lista colunas de um quadro (ordenadas por posição).
POST /api/v1/kanban/boards/{uuid}/columns Cria uma nova coluna em um quadro.
POST /api/v1/kanban/boards/{uuid}/columns/reorder Reordena colunas fornecendo array ordenado de UUIDs.
PUT /api/v1/kanban/columns/{uuid} Atualiza nome, cor ou configurações da coluna.
DELETE /api/v1/kanban/columns/{uuid} Exclui uma coluna, opcionalmente movendo leads para outra coluna.

Exemplo — 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 um quadro com filtros opcionais.
POST /api/v1/kanban/leads Cria um novo lead em um quadro.
GET /api/v1/kanban/leads/{uuid} Obtém detalhes do lead incluindo notas, campos personalizados e análise IA.
PUT /api/v1/kanban/leads/{uuid} Atualiza campos do lead (título, valor, prioridade, etc.).
DELETE /api/v1/kanban/leads/{uuid} Exclui (soft delete) um lead.
POST /api/v1/kanban/leads/{uuid}/move Move um lead para uma coluna diferente.
POST /api/v1/kanban/leads/{uuid}/won Marca um lead como ganho.
POST /api/v1/kanban/leads/{uuid}/lost Marca um lead como perdido com motivo opcional.
POST /api/v1/kanban/leads/{uuid}/note Adiciona uma nota com timestamp a um lead.
GET /api/v1/kanban/leads/{uuid}/activities Obtém o histórico de atividades de um lead.
POST /api/v1/kanban/leads/{uuid}/ai-qualify Executa análise de qualificação IA no lead.

Exemplo — Cria um novo lead em um quadro.

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"

Resposta:

{
  "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 Descrição
statusopen | won | lost | all (default: open)
prioritylow | medium | high | urgent
column_uuidFiltrar por UUID de coluna
searchBuscar por nome ou número

API Calendário

9 endpoints

API Calendário

Gerencie agendamentos e eventos de calendário. Crie, atualize e acompanhe transições de status de agendamentos programaticamente.

URL Base

/api/v1/calendar

Autenticação

Bearer Token (sk_*)

Endpoints

9 endpoints

Status de Agendamentos

scheduled Status inicial — agendamento criado
confirmed Cliente confirmou presença
completed Agendamento foi realizado
cancelled Agendamento foi cancelado
no_show Cliente não compareceu

Agendamentos

GET /api/v1/calendar/appointments Lista agendamentos para um intervalo de datas (padrão: mês atual).
POST /api/v1/calendar/appointments Cria um novo agendamento.
GET /api/v1/calendar/appointments/{uuid} Obtém detalhes de um agendamento.
PUT /api/v1/calendar/appointments/{uuid} Atualiza detalhes ou status do agendamento.
DELETE /api/v1/calendar/appointments/{uuid} Exclui um agendamento.
POST /api/v1/calendar/appointments/{uuid}/confirm Transiciona status do agendamento para confirmado.
POST /api/v1/calendar/appointments/{uuid}/complete Transiciona status do agendamento para concluído.
POST /api/v1/calendar/appointments/{uuid}/cancel Cancela um agendamento (não pode cancelar agendamentos já concluídos).
POST /api/v1/calendar/appointments/{uuid}/to-kanban Cria um lead Kanban a partir deste agendamento.

Exemplo — 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"

Resposta:

{
  "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 Descrição Default
startData inicial (ISO 8601)Start of month
endData final (ISO 8601)End of month
statusscheduled | confirmed | completed | cancelled | no_show
per_pageItens por página (max 100)50

Endpoint to-kanban

Converte um agendamento em um lead Kanban. Requer kanban_enabled na sua conta. Opcionalmente especifique board_uuid; caso contrário o quadro padrão é usado.

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 Funções de IA

9 endpoints

API de Funções de IA

Gerencie funções de IA (ferramentas baseadas em webhook) que seu agente de IA pode chamar durante conversas. Crie, configure, teste e monitore funções personalizadas que estendem as capacidades do seu agente de IA.

⚡ Requer uma integração de Agente de IA ativa na sua conta.

Endpoints

Method Endpoint Description
GET/api/v1/ai-functionsListar Funções de IA
POST/api/v1/ai-functionsCriar Função de IA
GET/api/v1/ai-functions/{uuid}Obter Função de IA
PUT/api/v1/ai-functions/{uuid}Atualizar Função de IA
DELETE/api/v1/ai-functions/{uuid}Excluir Função de IA
POST/api/v1/ai-functions/{uuid}/toggleAlternar Função de IA
POST/api/v1/ai-functions/{uuid}/testTestar Função de IA
GET/api/v1/ai-functions/{uuid}/executionsListar Execuções
GET/api/v1/ai-functions/executions/{uuid}Detalhes da Execução
GET /api/v1/ai-functions

Retorna uma lista paginada de todas as funções de IA da sua conta.

Query Parameters

integration_uuidFiltrar por UUID da integração
typeFiltrar por tipo de função
enabledFiltrar por status de ativação
searchBuscar por nome ou descrição
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

Cria uma nova função de IA com parâmetros opcionais. A função deve estar vinculada a uma integração de Agente de IA.

Body Parameters

integration_uuid *UUID da integração de Agente de IA
name *Nome da função (minúsculas, apenas underscores)
display_name *Nome de exibição amigável
description *Descrição exibida ao agente de IA
type *Tipo da função: fetch_data, collect_submit, action
endpoint_urlURL do webhook a ser chamado
http_methodMétodo HTTP (GET, POST, PUT, PATCH, DELETE)
auth_typeTipo de autenticação: none, bearer, basic, api_key, custom
parametersArray de parâmetros da função
is_enabledSe a função está ativa

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 o estado ativado/desativado de uma função 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

Executa uma chamada de teste ao endpoint da função com os parâmetros fornecidos.

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 — Nenhuma integração de Agente de IA ativa
DUPLICATE_NAME422 — DUPLICATE_NAME — Nome de função já existe
ACTIVE_EXECUTIONS409 — ACTIVE_EXECUTIONS — Não é possível excluir enquanto execuções estão em andamento
INVALID_INTEGRATION_TYPE422 — INVALID_INTEGRATION_TYPE — A integração não é do tipo Agente de IA

API de Funções Externas

8 endpoints

API de Funções Externas

Gerencie funções externas — endpoints de webhook que permitem que sistemas externos acionem ações do WhatsApp (enviar mensagens, gerenciar contatos, controlar automações). Cada função recebe uma chave de API única para autenticação.

⚡ Requer uma integração de Agente de IA ativa na sua conta.

Endpoints

Method Endpoint Description
GET/api/v1/external-functionsListar Funções Externas
POST/api/v1/external-functionsCriar Função Externa
GET/api/v1/external-functions/{uuid}Obter Função Externa
PUT/api/v1/external-functions/{uuid}Atualizar Função Externa
DELETE/api/v1/external-functions/{uuid}Excluir Função Externa
POST/api/v1/external-functions/{uuid}/toggleAlternar Função Externa
POST/api/v1/external-functions/{uuid}/regenerate-keyRegenerar Chave de API
GET/api/v1/external-functions/{uuid}/logsListar Logs
POST /api/v1/external-functions

Cria uma nova função externa com uma chave de API gerada automaticamente. A chave de API em texto simples é retornada apenas uma vez — armazene-a com segurança.

Body Parameters

instance_uuid *UUID da instância do WhatsApp
name *Nome da função
slug *Slug da URL (minúsculas, apenas hífens)
action_type *Tipo de ação: send_message, send_buttons, send_media, create_contact, update_contact, create_lead, update_lead, pause_automation, resume_automation
descriptionDescrição da função
configConfiguração específica da ação
rate_limitMáximo de chamadas por dia (padrão: 1000)
allowed_ipsArray de endereços IP permitidos (vazio = todos permitidos)
is_enabledSe a função está ativa

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

Gera uma nova chave de API e invalida a antiga. A nova chave é retornada apenas uma vez.

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

Tipos de Ação Disponíveis

send_messagesend_message — Enviar uma mensagem de texto
send_buttonssend_buttons — Enviar uma mensagem com botões
send_mediasend_media — Enviar mídia (imagem, vídeo, documento)
create_contactcreate_contact — Criar um novo contato
update_contactupdate_contact — Atualizar um contato existente
create_leadcreate_lead — Criar um lead no Kanban
update_leadupdate_lead — Atualizar um lead no Kanban
pause_automationpause_automation — Pausar automação de IA de uma conversa
resume_automationresume_automation — Retomar automação de IA de uma conversa

Error Codes

AI_AGENT_NOT_ENABLED403 — AI_AGENT_NOT_ENABLED — Nenhuma integração de Agente de IA ativa
DUPLICATE_SLUG422 — DUPLICATE_SLUG — Slug já existe para esta conta

Pronto para Começar?

Crie sua conta agora e comece a integrar o WhatsApp em suas aplicações com nossa API poderosa e fácil de usar.