DOCUMENTAÇÃO DA API UniController Sistemas · Referência de integração
← Voltar ao painel

API WhatsApp UniZap

Envie e receba mensagens de WhatsApp por HTTP. Integre com qualquer plataforma — n8n, Make, CRM, ERP ou sistema próprio.

Toda requisição usa a URL base da sua instância e o header Client-Token. Você encontra os dois no painel, dentro da instância, em Credenciais da API.

Formato da URL base:

# troque {ID} e {TOKEN} pelos valores da sua instância
https://SEU_HOST/instances/{ID}/token/{TOKEN}

Autenticação

Além do ID e TOKEN na URL, envie o Client-Token no header de todas as chamadas:

Client-Token: SEU_CLIENT_TOKEN

Sem ele, a API responde 401. Cada instância tem tokens próprios — se precisar revogar o acesso de um cliente, é só Regenerar tokens no painel.

Conexão

GET/status
Situação atual da instância.
{ "status": "connected", "connected": true, "phone": "5547999998888" }
GET/qr-code
Gera o QR Code pra conectar. Retorna imagem em base64 (data:image/png…).
{ "connected": false, "qrcode": "data:image/png;base64,…" }
GET/phone-code/{phone}
Código de pareamento pra conectar sem escanear QR — digita o código no celular.
{ "pairingCode": "XXXX-XXXX" }
POST/disconnect
Desconecta e apaga a sessão (logout).

Enviar texto

POST/send-text
# body
{ "phone": "5547999998888", "message": "Olá!" }
curl -X POST https://SEU_HOST/instances/{ID}/token/{TOKEN}/send-text \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"phone":"5547999998888","message":"Olá!"}'

Resposta: { "messageId": "…" }

O phone é o número com DDI (55) + DDD, só dígitos. Para grupos, passe o chatId completo (ex.: 1203…@g.us).

Enviar imagem

POST/send-image
image aceita URL pública ou base64.
{ "phone": "5547999998888", "image": "https://…/foto.jpg", "caption": "Legenda opcional" }

Enviar vídeo

POST/send-video
{ "phone": "5547999998888", "video": "https://…/video.mp4", "caption": "opcional" }

Enviar áudio

POST/send-audio
ptt: true envia como áudio de voz (padrão).
{ "phone": "5547999998888", "audio": "https://…/audio.mp3", "ptt": true }

Enviar documento

POST/send-document
{ "phone": "5547999998888", "document": "https://…/nota.pdf",
  "fileName": "nota-fiscal.pdf", "mimetype": "application/pdf" }

Enviar localização

POST/send-location
{ "phone": "5547999998888", "latitude": -26.9194, "longitude": -49.0661,
  "name": "União CERT", "address": "Blumenau/SC" }

Enviar contato

POST/send-contact
{ "phone": "5547999998888", "contactName": "Suporte", "contactPhone": "5547988887777" }

Reagir a uma mensagem

POST/send-reaction
reaction é o emoji. String vazia remove a reação. Use o messageId recebido no webhook.
{ "phone": "5547999998888", "messageId": "ABCD…", "reaction": "👍" }

"Digitando…" / "Gravando áudio…"

POST/send-presence
presence: composing (digitando), recording (gravando) ou paused. durationMs volta pra "paused" sozinho.
{ "phone": "5547999998888", "presence": "composing", "durationMs": 3000 }

Checar se o número tem WhatsApp

GET/phone-exists/{phone}
Valide antes de disparar em massa — evita banimento por enviar pra número inexistente.
{ "phone": "5547999998888", "exists": true, "jid": "5547999998888@s.whatsapp.net" }

Foto de perfil

GET/profile-picture/{phone}
{ "url": "https://…jpg" }  // url = null quando não há foto ou privacidade bloqueia

Marcar mensagem como lida

POST/read-message
{ "phone": "5547999998888", "messageId": "ABCD…" }

Apagar mensagem (para todos)

POST/delete-message
Só apaga mensagens enviadas pela própria instância.
{ "phone": "5547999998888", "messageId": "ABCD…" }

Grupos · listar & informações

GET/groups
Lista todos os grupos em que a instância participa.
[ { "groupId": "1203…@g.us", "subject": "Clientes VIP", "size": 42, "owner": "5547…" } ]
GET/group/{groupId}
Detalhes do grupo, incluindo participantes e quem é admin.
{
  "groupId": "1203…@g.us", "subject": "Clientes VIP", "description": "…",
  "inviteLink": "https://chat.whatsapp.com/XXXX",
  "participants": [ { "phone": "5547…", "admin": "superadmin" } ]
}
Para enviar mensagem pra um grupo, use os endpoints normais de envio (/send-text, /send-image etc.) passando o groupId (…@g.us) no campo phone.

Criar grupo

POST/create-group
Cria o grupo com os participantes iniciais e já retorna o link de convite.
{ "subject": "Novo Grupo", "participants": ["5547999998888", "5547988887777"] }

Participantes & admin

POST/group/{groupId}/participants
action: add (adicionar), remove (remover), promote (tornar admin), demote (rebaixar).
{ "participants": ["5547999998888"], "action": "add" }

Editar & configurar

PUT/group/{groupId}/subject
{ "subject": "Novo nome do grupo" }
PUT/group/{groupId}/description
{ "description": "Descrição do grupo" }
PUT/group/{groupId}/setting
setting: announcement (só admin envia), not_announcement (todos enviam), locked (só admin edita infos), unlocked (todos editam).
{ "setting": "announcement" }

Convite · entrar & sair

GET/group/{groupId}/invite
Pega o link de convite atual.
{ "inviteLink": "https://chat.whatsapp.com/XXXX" }
POST/group/{groupId}/invite/revoke
Revoga o link antigo e gera um novo (o antigo para de funcionar).
POST/join-group
A instância entra num grupo pelo link ou código de convite.
{ "inviteCode": "https://chat.whatsapp.com/XXXX" }
POST/group/{groupId}/leave
A instância sai do grupo.
POST/transcribe
Transcreve um áudio pra texto (português). Passe messageId (usa o áudio guardado), audio (base64) ou url. Requer o serviço de transcrição configurado.
{ "messageId": "ABCD…" }
// ou { "audio": "base64…" }  ou  { "url": "https://…/audio.ogg" }
{ "text": "texto transcrito completo", "language": "pt", "duration": 12.4 }

Webhooks · eventos & payloads

Configure as URLs no painel (ou via API). Quando um evento acontece, a UniZap faz um POST JSON na sua URL. Se você definir um secret, ele vem no header X-Webhook-Secret — valide pra ter certeza de que o disparo é seu.

EventoQuando dispara
message.receivedChega uma mensagem
message.sentA instância envia uma mensagem
message.statusMuda o status (enviada, entregue, lida, reproduzida)
chat.presenceO outro lado está digitando/gravando
call.receivedChegou uma ligação (traz rejected se foi recusada)
instance.connectedInstância conecta
instance.disconnectedInstância cai ou desconecta

message.received (texto):

{
  "event": "message.received",
  "instanceId": "…", "instanceName": "Cliente X", "momment": 1720000000000,
  "messageId": "ABCD…", "fromMe": false,
  "phone": "5547999998888", "chatId": "5547999998888@s.whatsapp.net",
  "isGroup": false, "senderName": "Fulano", "timestamp": 1720000000000,
  "messageType": "text", "text": "Oi"
}

Para mídia (image, video, audio, document, sticker) vêm mimetype e caption/fileName. Até 8MB vai em base64 no webhook. Acima disso, é guardada 7 dias e o webhook traz mediaStored: true + mediaUrl (link direto pra baixar) + mediaId.

GET/media/{messageId}
Baixa a mídia de uma mensagem recebida quando quiser (dentro dos 7 dias). Retorna o binário; use ?base64=true pra receber em JSON. O mediaUrl do webhook aponta pra um link público equivalente (/media/{id}, id não-adivinhável).

message.status:

{ "event": "message.status", "messageId": "…", "phone": "…", "status": "delivered" }
// status: sent | delivered | read | played | error

instance.disconnected:

{ "event": "instance.disconnected", "connected": false, "reason": "connection_lost", "reconnecting": true }

Configurar webhooks via API

GET/webhooks
Lê a configuração atual.
PUT/webhooks
Atualiza qualquer campo. Mande só o que quer mudar.
{
  "wh_on_receive": "https://seusite.com/hook",
  "ignore_on_receive": false,
  "notify_sent_by_me": true,
  "f_ignore_groups": true,
  "webhook_secret": "um-segredo-forte",
  "reject_calls": true,
  "reject_call_message": "Não atendemos ligações, envie mensagem."
}

Campos de URL: wh_on_send, wh_on_receive, wh_on_connect, wh_on_disconnect, wh_message_status, wh_chat_presence.
Toggles de ignorar (mesmo nome com prefixo ignore_) e filtros de recebimento Chamadas: reject_calls (rejeita ligações automaticamente) e reject_call_message (aviso enviado a quem liga). (f_ignore_groups, f_ignore_private, f_ignore_text, f_ignore_image, f_ignore_video, f_ignore_audio, f_ignore_document).

Boas práticas anti-ban: a UniZap já serializa os envios com um intervalo entre mensagens. Ainda assim, aqueça números novos, evite disparo em massa pra desconhecidos e valide os números com /phone-exists antes. É protocolo não-oficial (WhatsApp Web), então abuso leva a banimento pelo próprio WhatsApp.

UniZap API · UniController Sistemas — powered by Blumenau/SC 🇧🇷