Referência da API v2
Integre o WhatsApp à sua aplicação em minutos. A API v2 é compatível com Evolution API — se você já tem código funcionando no padrão Evolution, basta trocar a base URL para usar o Shiftz.
Identificador das instâncias: o instanceName que você escolhe ao criar é o identificador usado em todas as rotas subsequentes (:name). Não é preciso consultar nenhum ID interno.
Autenticação
Todas as requisições usam API Key via header apikey. As chaves são escopadas por organização — você só acessa instâncias da sua própria conta.
apikey: shz_<prefix>.<secret>Teste se sua chave é válida listando suas instâncias.
curl -X GET https://api.shiftz.com.br/v2/instance/fetchInstances \
-H "apikey: SUA_CHAVE_AQUI"Erros & Status Codes
Erros seguem o formato JSON padrão. Quando aplicável, vem o campo details com informações adicionais (ex: violações Zod).
| Código | Significado |
|---|---|
200 / 201 | Operação bem-sucedida |
400 | Body inválido (Zod). Ver details |
401 | missing_api_key ou invalid_api_key |
402 | quota_denied — limite do plano atingido |
404 | instance_not_found |
409 | instance_already_exists ou instance_not_working |
500 | Erro de engine WhatsApp ou interno |
503 | no_engine_capacity ou instance_unavailable |
{
"error": "invalid_body",
"details": [
{
"code": "invalid_type",
"path": ["text"],
"message": "Required"
}
]
}Instâncias
Criar Instância
Cria uma nova instância. O instanceName que você escolher é o identificador usado em todas as outras rotas. A criação retorna uma API Key específica da instância no campo hash.
Identificador único da instância dentro da sua organização.
WHATSAPP-BAILEYS (default), WHATSAPP-BUSINESS ou EVOLUTION.
Retorna o QR Code já na resposta de criação.
Telefone (DDI+DDD+número) para receber pairing code em vez de QR.
Configuração inicial do webhook. Ver Configurar Webhook.
Rejeita chamadas recebidas automaticamente.
Mensagem enviada após rejeição de chamada.
Ignora eventos de grupo no webhook.
Mantém presença online no WhatsApp.
Marca mensagens como lidas automaticamente.
Marca status como visualizados automaticamente.
Sincroniza histórico completo ao conectar.
Host do proxy (ex.: proxy.exemplo.com).
Porta do proxy.
http, https ou socks5.
Usuário de autenticação do proxy.
Senha de autenticação do proxy.
Quando qrcode: true, a resposta já inclui o campo qrcode com o conteúdo bruto e o base64 — sem necessidade de chamar /connect em seguida.
curl -X POST https://api.shiftz.com.br/v2/instance/create \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"instanceName": "marketing-01",
"integration": "WHATSAPP-BAILEYS",
"qrcode": true,
"rejectCall": true,
"msgCall": "Não atendemos chamadas neste número.",
"groupsIgnore": true,
"alwaysOnline": false,
"readMessages": false,
"readStatus": false,
"syncFullHistory": false,
"proxyHost": "proxy.exemplo.com",
"proxyPort": 8080,
"proxyProtocol": "http",
"proxyUsername": "user",
"proxyPassword": "pass",
"webhook": {
"enabled": true,
"url": "https://seu-servidor.com/webhook",
"base64": false,
"headers": {
"Authorization": "Bearer TOKEN_INTERNO"
},
"events": [
"messages.upsert",
"connection.update",
"qrcode.updated"
]
}
}'Listar Instâncias
Retorna todas as instâncias da sua organização com o estado de conexão atual.
curl -X GET https://api.shiftz.com.br/v2/instance/fetchInstances \
-H "apikey: SUA_CHAVE"Conectar Instância
Inicia a conexão com o WhatsApp e retorna o QR Code (raw + base64) ou o pairing code quando o telefone foi informado na criação.
O instanceName usado na criação.
QR Codes têm validade curta (~20s). Se a sessão for pra FAILED, descarte e chame /connect de novo pra obter um QR fresco.
curl -X GET https://api.shiftz.com.br/v2/instance/connect/marketing-01 \
-H "apikey: SUA_CHAVE"Estado da Conexão
Retorna o estado atual da conexão da instância. Valores: open (conectado), close (desconectado), connecting (em conexão), qr-code (aguardando leitura).
O instanceName usado na criação.
curl -X GET https://api.shiftz.com.br/v2/instance/connectionState/marketing-01 \
-H "apikey: SUA_CHAVE"Atualizar Instância
Atualiza a configuração da instância (webhook + flags de comportamento). Campos não enviados permanecem inalterados.
Nome da instância (path param).
Substitui completamente a configuração de webhook.
Rejeição automática de chamadas.
Mensagem após rejeição.
Ignora eventos de grupo.
Presença sempre online.
Marca como lida automaticamente.
Marca status como visto.
Sincronização de histórico.
curl -X PUT https://api.shiftz.com.br/v2/instance/update/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"webhook": {
"enabled": true,
"url": "https://meusite.com/webhook",
"events": ["messages.upsert", "connection.update"]
}
}'Desconectar (Logout)
Encerra a sessão do WhatsApp mas mantém a instância criada. Para reconectar depois, basta chamar /instance/connect/:name novamente. Para remover permanentemente, use Deletar Instância.
Nome da instância.
curl -X DELETE https://api.shiftz.com.br/v2/instance/logout/marketing-01 \
-H "apikey: SUA_CHAVE"Deletar Instância
Remove permanentemente a instância: encerra a sessão WhatsApp, libera a vaga no plano e apaga a configuração.
Nome da instância.
curl -X DELETE https://api.shiftz.com.br/v2/instance/delete/marketing-01 \
-H "apikey: SUA_CHAVE"Mensagens
Listar Histórico
Retorna mensagens enviadas e recebidas pela instância. Suporta paginação por cursor (use nextCursor da resposta como cursor da próxima requisição). Status reflete o último ack recebido (sent, delivered, read, played, revoked).
Filtra por JID do chat ([email protected] ou [email protected]).
in (recebidas) ou out (enviadas).
Filtra por tipo (text, image, video, audio, document, sticker, location, poll, contact, ptv, list, buttons, status).
1-200, default 50.
ISO timestamp retornado em nextCursor da página anterior.
curl -X GET "https://api.shiftz.com.br/v2/message/list/marketing-01?direction=out&limit=20" \
-H "apikey: SUA_CHAVE"Enviar Texto
Envia uma mensagem de texto. Suporta emojis, formatação WhatsApp (*bold*, _italic_, ~strikethrough~, `code`), preview de links e respostas (quoted).
Destinatário com DDI+DDD (ex: 5511999998888).
Conteúdo da mensagem.
Atraso em milissegundos antes de enviar (máx: 300000).
Renderiza preview do primeiro link encontrado.
Menciona todos em grupos.
Lista de JIDs a mencionar.
Mensagem a ser respondida ({ key: { id: "..." } }).
curl -X POST https://api.shiftz.com.br/v2/message/sendText/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"text": "Olá! 👋",
"delay": 1200
}'Enviar Mídia
Envia imagem, vídeo, documento ou áudio a partir de URL pública.
Destinatário com DDI+DDD.
image, video, document ou audio.
URL pública do arquivo.
Legenda (suporta formatação WhatsApp).
Nome do arquivo (recomendado para document).
MIME type explícito (sobrescreve o detectado).
Atraso em milissegundos (máx: 300000).
Mensagem a ser respondida.
curl -X POST https://api.shiftz.com.br/v2/message/sendMedia/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"mediatype": "image",
"media": "https://example.com/imagem.png",
"caption": "Confira nosso novo produto!"
}'Enviar Áudio (PTT)
Envia um áudio como mensagem de voz (Push-To-Talk). Aceita URL pública de MP3 ou OGG.
Número do destinatário (ex: 5511999998888).
URL pública do arquivo MP3/OGG.
Atraso em milissegundos antes de enviar (máx: 300000).
Re-encodar o áudio antes de enviar.
Mensagem a ser respondida (key.id obrigatório).
curl -X POST https://api.shiftz.com.br/v2/message/sendWhatsAppAudio/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"audio": "https://example.com/voice.mp3"
}'Enviar Figurinha
Envia uma figurinha (sticker) a partir de URL pública. WebP é o formato nativo; outros formatos podem ser convertidos.
Número do destinatário.
URL pública do arquivo WebP.
Atraso em milissegundos (máx: 300000).
Se true, não tenta converter o arquivo antes de enviar.
Mensagem a ser respondida.
curl -X POST https://api.shiftz.com.br/v2/message/sendSticker/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"sticker": "https://example.com/sticker.webp"
}'Enviar Localização
Envia um pin de localização geográfica. Coordenadas em graus decimais.
Número do destinatário.
Latitude (ex: -23.55052).
Longitude (ex: -46.633308).
Nome do local (ex: MASP).
Endereço textual complementar.
Atraso em milissegundos (máx: 300000).
curl -X POST https://api.shiftz.com.br/v2/message/sendLocation/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"latitude": -23.55052,
"longitude": -46.633308,
"name": "MASP",
"address": "Av. Paulista, 1578"
}'Enviar Enquete
Cria uma enquete com opções para o destinatário votar. O voto chega via webhook como pollUpdateMessage.
Número do destinatário.
Pergunta da enquete.
Opções de resposta (mínimo 2, máximo 12).
Quantas opções podem ser escolhidas. 0 = apenas uma (padrão), >0 = múltipla escolha.
Atraso em milissegundos (máx: 300000).
curl -X POST https://api.shiftz.com.br/v2/message/sendPoll/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"name": "Qual o melhor horário?",
"values": ["Manhã", "Tarde", "Noite"],
"selectableCount": 1
}'Enviar Contato
Envia um ou mais cartões de contato (vCard). Para múltiplos contatos, envie um único array — o WhatsApp agrupa automaticamente.
Número do destinatário.
Lista de contatos a enviar.
Nome completo do contato.
Número de telefone do contato.
WhatsApp UID do contato (se conhecido).
Organização/empresa.
E-mail do contato.
Website do contato.
Atraso em milissegundos (máx: 300000).
curl -X POST https://api.shiftz.com.br/v2/message/sendContact/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"contact": [
{
"fullName": "Ivo Silva",
"phoneNumber": "5511999997777",
"organization": "Verboo",
"email": "[email protected]"
}
]
}'Enviar Vídeo Redondo (PTV)
Envia um vídeo curto circular (Push-To-Video). Use arquivos curtos (≤60s) em MP4.
Número do destinatário.
URL pública do arquivo MP4.
Atraso em milissegundos (máx: 300000).
Mensagem a ser respondida.
curl -X POST https://api.shiftz.com.br/v2/message/sendPtv/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"video": "https://example.com/short.mp4"
}'Enviar Lista
Envia uma mensagem interativa com lista de opções selecionáveis. Ideal para menus, catálogos e formulários.
Limitação WhatsApp: listas interativas funcionam plenamente apenas no Cloud API/Business. Em sessões pessoais (WHATSAPP-BAILEYS) o destinatário pode receber a mensagem como texto degradado.
Número do destinatário.
Título da mensagem.
Descrição/corpo da mensagem.
Texto do botão que abre a lista.
Rodapé da mensagem.
Seções da lista — cada uma com title? e rows[].
Título da opção.
Descrição da opção.
ID retornado no webhook quando o usuário seleciona.
curl -X POST https://api.shiftz.com.br/v2/message/sendList/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"title": "Nossos Planos",
"description": "Escolha o plano ideal para você:",
"buttonText": "Ver opções",
"footerText": "Shiftz",
"sections": [
{
"title": "Planos",
"rows": [
{ "title": "Starter", "description": "R$ 30/mês", "rowId": "plan_starter" },
{ "title": "Pro", "description": "R$ 90/mês", "rowId": "plan_pro" }
]
}
]
}'Enviar Status (Broadcast)
Publica um status visível para todos os contatos ou para uma lista específica de JIDs. Suporta texto, imagem, áudio e vídeo.
Suporte experimental: status broadcast pode retornar 5xx em integrações pessoais conforme limitações do WhatsApp.
text, image, audio ou video.
Texto do status (quando type=text) OU URL pública do arquivo de mídia.
Legenda — apenas para image/video.
Cor de fundo HEX (ex: #FF5733) — apenas text.
Índice da fonte (0-5) — apenas text.
Se true, envia para todos os contatos.
Lista de JIDs específicos que vão ver o status (ignorado se allContacts=true).
curl -X POST https://api.shiftz.com.br/v2/message/sendStatus/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"type": "text",
"content": "Estamos com desconto hoje! 🎉",
"backgroundColor": "#FF5733",
"font": 2,
"allContacts": true
}'Chat & Presença
Gerencie estado do chat, reações, leituras e verificação de números.
Enviar Reação
Reage a uma mensagem específica com um emoji. Para remover uma reação anterior, envie reaction como string vazia.
Emoji (ex: 👍, ❤️).
Chave da mensagem alvo: { remoteJid, id, fromMe }.
JID do chat (ex: [email protected]).
ID da mensagem alvo.
Se a mensagem foi enviada por você.
curl -X POST https://api.shiftz.com.br/v2/message/sendReaction/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"reaction": "👍",
"key": {
"remoteJid": "[email protected]",
"id": "3EB0XXXXXXXX",
"fromMe": false
}
}'Enviar Presença
Simula presença num chat: digitando, gravando ou online. Use delay para definir a duração antes de pausar automaticamente.
Número do chat alvo (ex: 5511999998888).
composing (digitando) ou available (online).
text (default) ou audio — apenas com presence=composing. audio simula "gravando áudio".
Duração em ms (máx: 300000). Após esse tempo a presença é pausada.
curl -X POST https://api.shiftz.com.br/v2/chat/sendPresence/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999998888",
"presence": "composing",
"type": "text",
"delay": 3000
}'Marcar como Lido
Marca um conjunto de mensagens como lidas. Em grupos, informe sender (JID do remetente original).
Array de mensagens a marcar.
JID do chat.
ID da mensagem.
JID do remetente (obrigatório em grupos).
curl -X POST https://api.shiftz.com.br/v2/chat/markMessageAsRead/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"readMessages": [
{
"remoteJid": "[email protected]",
"id": "3EB0XXXXXXXX"
}
]
}'Verificar Número
Para cada número do array, retorna se está registrado no WhatsApp e o JID correspondente. Útil para validar antes de enviar.
Lista de números (DDI+DDD+número).
curl -X POST https://api.shiftz.com.br/v2/chat/whatsappNumbers/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"numbers": ["5511999998888", "5511777776666"]
}'Deletar Mensagem (para todos)
Revoga uma mensagem (apaga para todos). Em grupos, ao deletar mensagem de outro participante, informe participant.
ID da mensagem.
JID do chat ([email protected]) ou grupo ([email protected]).
Se a mensagem foi enviada por você.
JID do remetente original. Obrigatório ao deletar mensagem de outro participante em grupos.
curl -X DELETE https://api.shiftz.com.br/v2/chat/deleteMessageForEveryone/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"id": "3EB0XXXXXXXX",
"remoteJid": "[email protected]",
"fromMe": true
}'Listar Chats
Retorna a lista completa de chats da instância (individuais + grupos). Cada item traz chatId, name (quando o WhatsApp expõe — pode vir vazio em DMs sem nome salvo), isGroup, lastMessageTimestamp, unreadCount, archived, pinned, muteEndTimestamp. pictureUrl não vem nesse listing — chame Foto de Perfil por chat pra resolver.
curl -X GET https://api.shiftz.com.br/v2/chat/findChats/marketing-01 \
-H "apikey: SUA_CHAVE"Listar Contatos
Retorna o address-book completo do número conectado. Cada item traz remoteJid (phone JID), remoteLid (LID alternativo, chave para destravar mapping LID↔phone em contatos com privacy mode), pushName, verifiedName, profilePicUrl, isMyContact, isBlocked. Suporta filtro pontual por where.remoteJid e paginação por cursor. Útil pro sync inicial do CRM logo após o pareamento.
Filtro opcional. where.remoteJid retorna um único contato.
Tamanho da página (default 500, máx 2000).
Cursor opaco da página anterior (devolvido em nextCursor).
curl -X POST https://api.shiftz.com.br/v2/chat/findContacts/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "limit": 500 }'Foto de Perfil
Retorna a URL pública atual da foto de perfil do contato/grupo. Devolve { "url": null } se não houver ou estiver bloqueada. Também aceita variante POST /v2/chat/fetchProfilePictureUrl/:instance com { "chatId": "..." } no body — útil quando o JID complica encoding em path.
curl -X GET https://api.shiftz.com.br/v2/chat/fetchProfilePictureUrl/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE"Arquivar Chat
Toggle. Use archive: true para arquivar e false para desarquivar.
JID do chat.
true arquiva, false desarquiva.
curl -X POST https://api.shiftz.com.br/v2/chat/archiveChat/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "chatId": "[email protected]", "archive": true }'Grupos
Crie e gerencie grupos WhatsApp.
Criar Grupo
Cria um grupo WhatsApp e adiciona os participantes informados.
Nome do grupo.
Números (DDI+DDD+número) ou JIDs dos participantes.
Descrição inicial do grupo.
curl -X POST https://api.shiftz.com.br/v2/group/create/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"subject": "Time Marketing",
"participants": ["5511999998888", "5511777776666"],
"description": "Canal interno do time"
}'Informações do Grupo
Retorna metadados do grupo: subject, owner, descrição, lista de participantes (com flags isAdmin, isSuperAdmin).
curl -X GET https://api.shiftz.com.br/v2/group/findGroupInfos/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE"Adicionar Participantes
Adiciona números ao grupo.
Números/JIDs.
curl -X POST https://api.shiftz.com.br/v2/group/addParticipants/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "participants": ["5511999998888"] }'Remover Participante
Remove números do grupo. Aceita um array.
Números/JIDs.
curl -X POST https://api.shiftz.com.br/v2/group/removeParticipant/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "participants": ["5511999998888"] }'Promover Admin
Promove participantes a administradores.
Números/JIDs.
curl -X POST https://api.shiftz.com.br/v2/group/promote/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "participants": ["5511999998888"] }'Rebaixar Admin
Remove status de admin de participantes.
Números/JIDs.
curl -X POST https://api.shiftz.com.br/v2/group/demote/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "participants": ["5511999998888"] }'Sair do Grupo
Remove o número da instância como participante do grupo.
curl -X POST https://api.shiftz.com.br/v2/group/leave/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE"Link de Convite
Retorna o código de convite atual e a URL https://chat.whatsapp.com/<code>.
curl -X GET https://api.shiftz.com.br/v2/group/inviteCode/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE"Revogar Convite
Invalida o código atual e gera um novo. Links antigos param de funcionar.
curl -X POST https://api.shiftz.com.br/v2/group/revokeInvite/marketing-01/[email protected] \
-H "apikey: SUA_CHAVE"Enviar Link por DM
Pega o invite-code do grupo e envia uma mensagem de texto com o link para cada número em numbers[].
JID do grupo.
Números que receberão o convite por DM.
Texto adicional enviado antes do link.
curl -X POST https://api.shiftz.com.br/v2/group/sendInvite/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"groupJid": "[email protected]",
"numbers": ["5511999998888", "5511777776666"],
"description": "Entra no nosso grupo!"
}'Perfil
Atualize nome, foto e recado/status do número conectado.
Buscar Perfil
Retorna o perfil atual da instância: wuid, name, status, pictureUrl.
curl -X GET https://api.shiftz.com.br/v2/profile/fetchProfile/marketing-01 \
-H "apikey: SUA_CHAVE"Atualizar Nome
Define o nome de exibição do perfil.
Novo nome.
curl -X POST https://api.shiftz.com.br/v2/profile/updateProfileName/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "name": "Time Marketing" }'Atualizar Foto
Define a foto de perfil a partir de uma URL pública.
URL pública da imagem.
curl -X POST https://api.shiftz.com.br/v2/profile/updateProfilePicture/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "picture": "https://example.com/avatar.jpg" }'Atualizar Status
Define o recado/status do perfil.
Novo recado.
curl -X POST https://api.shiftz.com.br/v2/profile/updateProfileStatus/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "status": "Atendimento 9h-18h" }'Webhooks
Configurar Webhook
Define ou atualiza a configuração de webhook de uma instância. Faz upsert — chamar de novo substitui a configuração anterior.
Liga/desliga a entrega.
URL HTTPS pública. Bloqueado: localhost, IPs privados e redes internas (proteção SSRF).
Lista de eventos. Vazio = recebe todos.
Headers HTTP customizados enviados em cada POST.
Codifica payload em base64.
Cada POST inclui os headers X-Shiftz-Event, X-Shiftz-Attempt e X-Webhook-Signature (HMAC-SHA256 do body). Retry com backoff exponencial de 2s a 1h, total até 24h.
curl -X POST https://api.shiftz.com.br/v2/webhook/set/marketing-01 \
-H "apikey: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"webhook": {
"enabled": true,
"url": "https://meusite.com/webhook",
"events": ["messages.upsert", "connection.update"]
}
}'Consultar Webhook
Retorna a configuração atual de webhook da instância. Se não houver configuração, devolve um objeto neutro com enabled: false.
curl -X GET https://api.shiftz.com.br/v2/webhook/find/marketing-01 \
-H "apikey: SUA_CHAVE"Eventos de Webhook
Todos os eventos são entregues via POST na URL configurada, dentro de um envelope padrão. O campo data varia conforme o tipo do evento.
Use os nomes abaixo no array events ao configurar o webhook. events: [] ou events: ["*"] recebe todos. A filtragem aceita ambos os formatos — MESSAGES_UPSERT (Evolution v2 UPPERCASE) e messages.upsert (lowercase canônico). O Shiftz normaliza antes de comparar.
Eventos Evolution v2 (com mapping ou alias direto):
| Evolution (UPPERCASE) | Alias canônico (lowercase) | Quando dispara |
|---|---|---|
MESSAGES_UPSERT | messages.upsert | Mensagem recebida (ou enviada com fromMe: true) |
MESSAGES_UPDATE | messages.update | Ack de entrega (sent → delivered → read → played) |
MESSAGES_DELETE | messages.delete | Mensagem revogada para todos |
CONNECTION_UPDATE | connection.update | Estado da conexão muda |
QRCODE_UPDATED | qrcode.updated | QR Code novo disponível |
CONTACTS_UPSERT | contacts.upsert | Contato ou grupo atualizado |
SEND_MESSAGE | messages.upsert (fromMe) | Mensagem enviada via API |
PRESENCE_UPDATE | presence.update | Presença muda (online/typing/recording) |
GROUP_UPDATE | group.v2.update | Metadata de grupo (nome, foto) muda |
GROUP_PARTICIPANTS_UPDATE | group.v2.participants | Adição/remoção/promoção de participantes |
CALL | call.received | Chamada recebida |
Não disponíveis (Evolution-specific, não emitidos pela API): APPLICATION_STARTUP, MESSAGES_SET, CONTACTS_SET, CHATS_SET/UPSERT/UPDATE/DELETE, GROUPS_UPSERT, NEW_JWT_TOKEN, TYPEBOT_*.
presence.update: só emitido quando um contato remoto envia presença (ex: o destinatário está digitando). ChamarsendPresenceda sua instância não dispara este evento — ele é só pra você ler presenças de outros.contacts.upsert: dispara quando um contato/grupo é criado, atualizado ou tem foto/nome alterado pelo lado remoto. Mudanças no seu próprio perfil (updateProfileName/Picture/Status) não disparam este evento — atualizam direto via API REST.messages.update(ack):deliveredchega rápido (≤1s), masreadsó vem quando o destinatário abre a conversa no celular. Em testes locais, abra o WhatsApp no celular receptor pra forçar o read receipt.messages.delete: odata.keyagora contémid(mensagem revogada) eremoteJid(chat). Em algumas mensagens oremoteJidpode ser inferido do compostofalse_<chatId>_<msgId>.qrcode.updated: emitido em paralelo aconnection.updatequando há um novo QR. Use este pra renderizar QR em UI sem precisar interpretarconnection.updatecomstate: "qr-code".
Eventos adicionais (passthrough) — payload no formato canônico Shiftz:
| Evento | Quando dispara |
|---|---|
messages.reaction | Reação com emoji (incluindo remoção) |
messages.edited | Mensagem editada (até 15min) |
chats.archive | Chat arquivado/desarquivado |
group.v2.join | Você ou alguém entrou em um grupo |
group.v2.leave | Você ou alguém saiu do grupo |
group.v2.participants | Participantes adicionados/removidos/promovidos |
group.v2.update | Metadata do grupo mudou (nome, foto, descrição) |
presence.update | Presença de contato mudou (online, typing, recording) |
poll.vote | Voto em enquete |
poll.vote.failed | Falha ao registrar voto |
call.received | Chamada recebida |
call.accepted | Chamada aceita |
call.rejected | Chamada rejeitada |
event.response | RSVP em mensagem-evento (calendário) |
event.response.failed | RSVP rejeitado |
label.upsert label.deleted label.chat.added label.chat.deleted | Labels (Business) |
{
"event": "messages.upsert",
"instance": "marketing-01",
"data": { /* payload do evento */ },
"date_time": "2026-05-06T01:48:35.762Z",
"sender": "[email protected]",
"server_url": "https://api.shiftz.com.br"
}MCP
Visão geral
O MCP (Model Context Protocol) é o "plugue universal" que liga assistentes de IA a ferramentas externas. O Shiftz expõe um servidor MCP que dá ao seu agente acesso a todo o /v2/* em linguagem natural: ele cria instâncias, lê o QR Code, manda mensagem e administra grupos sozinho, sem você escrever uma linha de integração.
Três coisas definem a conexão e valem para todos os clientes desta página:
- URL:
https://api.shiftz.com.br/mcp - Autenticação: header
Authorization: Bearer <apikey>, a mesma chaveshz_...da API REST. - Transport: Streamable HTTP (stateless).
A apikey também decide o que o agente enxerga: chave org-wide vê todas as instâncias, chave instance-scoped vê só uma. Além das tools, o servidor expõe resources (shiftz://instances/*) e prompts guiados, descobertos automaticamente pelo cliente.
Você precisa de uma apikey Shiftz no formato shz_<prefixo>.<segredo>. Gere uma no dashboard da Shiftz ou pela própria API (tool shiftz_create_apikey). Trate a chave como senha: quem tem ela envia mensagem pelo seu WhatsApp.
47 ferramentas expostas pelo servidor MCP, agrupadas em 6 áreas. O cliente MCP descobre os schemas (parâmetros, tipos) automaticamente via tools/list. Cada tool mapeia 1:1 para um endpoint REST — clique em qualquer card abaixo para ver os parâmetros completos e um exemplo cURL do endpoint correspondente.
Instâncias
(7 tools)Lista todas as instâncias da sua conta com status de conexão.
Ver parâmetros →Cria uma nova instância de WhatsApp e devolve a apikey + QR.
Ver parâmetros →Inicia a conexão e retorna o QR Code (raw + base64) ou pairing code.
Ver parâmetros →Estado atual da conexão (open, close, connecting, qr-code).
Ver parâmetros →Atualiza webhook e flags de comportamento da instância.
Ver parâmetros →Encerra a sessão WhatsApp mantendo a instância criada.
Ver parâmetros →Remove permanentemente a instância e libera vaga no plano.
Ver parâmetros →Mensagens
(11 tools)Histórico paginado por cursor com filtros de chatId, tipo e direção.
Ver parâmetros →Envia mensagem de texto com formatação WhatsApp e link preview.
Ver parâmetros →Envia imagem, vídeo, documento ou áudio anexado a partir de URL pública.
Ver parâmetros →Envia áudio como mensagem de voz (PTT). MP3 ou OGG.
Ver parâmetros →Envia figurinha em WebP (ou outro formato com conversão automática).
Ver parâmetros →Envia pin de localização geográfica com nome e endereço.
Ver parâmetros →Cria enquete com 2-12 opções, single ou múltipla escolha.
Ver parâmetros →Envia um ou mais cartões de contato (vCard).
Ver parâmetros →Envia vídeo redondo curto (Push-To-Video, ≤60s).
Ver parâmetros →Mensagem interativa com lista de opções selecionáveis.
Ver parâmetros →Publica status (broadcast) em texto, imagem, áudio ou vídeo.
Ver parâmetros →Chat & Presença
(9 tools)Reage a mensagem específica com emoji (string vazia remove).
Ver parâmetros →Simula presença (digitando, gravando ou online) por uma duração.
Ver parâmetros →Marca mensagens como lidas (em grupos requer JID do remetente).
Ver parâmetros →Para cada número, retorna se está no WhatsApp e o JID.
Ver parâmetros →Revoga mensagem (apaga para todos os participantes).
Ver parâmetros →Lista chats individuais e grupos com flags de archived, pinned, unread.
Ver parâmetros →Address-book completo com remoteJid + remoteLid. Destrava mapping LID↔phone.
Ver parâmetros →URL pública atual da foto de perfil de contato ou grupo.
Ver parâmetros →Arquiva ou desarquiva um chat (toggle).
Ver parâmetros →Grupos
(11 tools)Cria um grupo e adiciona os participantes informados.
Ver parâmetros →Metadados do grupo: subject, owner, descrição, lista de participantes.
Ver parâmetros →Adiciona números ao grupo.
Ver parâmetros →Remove participantes do grupo.
Ver parâmetros →Promove participantes a administradores.
Ver parâmetros →Rebaixa administradores a participantes regulares.
Ver parâmetros →Remove o número da instância como participante do grupo.
Ver parâmetros →Retorna o código de convite atual e a URL chat.whatsapp.com.
Ver parâmetros →Invalida o código atual e gera um novo. Links antigos param de funcionar.
Ver parâmetros →Re-sincroniza cache de grupos com o WhatsApp (anti dessincronização).
Ver parâmetros →Pega o invite-code e envia o link para uma lista de números por DM.
Ver parâmetros →Perfil
(4 tools)Retorna o perfil da instância: wuid, name, pictureUrl.
Ver parâmetros →Define o nome de exibição do perfil.
Ver parâmetros →Define a foto de perfil a partir de URL pública.
Ver parâmetros →Define o recado/status do perfil.
Ver parâmetros →Admin
(5 tools)Upsert da configuração de webhook (URL, eventos, headers).
Ver parâmetros →Consulta a configuração de webhook atual da instância.
Ver parâmetros →Cria nova API key escopada por organização ou instância.
Ver parâmetros →Lista API keys ativas com prefix, escopo e data de criação.
Ver parâmetros →Revoga uma API key. A chave para de funcionar imediatamente.
Ver parâmetros →Clientes suportados
A maioria dos clientes conecta direto no endpoint HTTP usando o header de autenticação. Alguns precisam de uma ponte local ou de OAuth. Ache o seu na tabela e pule para a seção dele:
| Cliente | Como conecta | Onde configurar |
|---|---|---|
| Claude Code | HTTP nativo + header | claude mcp add ou .mcp.json |
| Claude Desktop | Ponte mcp-remote | claude_desktop_config.json |
| Claude.ai (web) | OAuth (ainda não disponível) | conector customizado |
| Codex CLI | HTTP nativo (flag) ou ponte | ~/.codex/config.toml |
| Gemini CLI | HTTP nativo + header | gemini mcp add ou settings.json |
| OpenCode | HTTP nativo (type: remote) | opencode.json |
| OpenClaw | HTTP nativo (streamable-http) | openclaw mcp add ou openclaw.json |
| Hermes | HTTP nativo + header | config YAML (mcp_servers) |
Em todos os exemplos, troque shz_xxx.yyy pela sua apikey.
Claude Code
O CLI do Claude conecta direto no endpoint HTTP, sem ponte. Use --scope user para deixar o Shiftz disponível em qualquer projeto seu:
claude mcp add --transport http --scope user shiftz \
https://api.shiftz.com.br/mcp \
--header "Authorization: Bearer shz_xxx.yyy"Numa sessão, o comando /mcp abre o painel com o status da conexão e a lista de tools. O arquivo .mcp.json (versionável) aceita variáveis de ambiente como ${SHIFTZ_API_KEY}, ideal para não commitar a chave.
Claude Desktop
O Claude Desktop tem conectores nativos, mas a UI deles só faz login por OAuth, sem campo para uma apikey fixa. Para a autenticação Bearer da Shiftz, use o mcp-remote como ponte (precisa de Node.js instalado). Edite o arquivo de config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"shiftz": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.shiftz.com.br/mcp",
"--header",
"Authorization:${AUTH}"
],
"env": {
"AUTH": "Bearer shz_xxx.yyy"
}
}
}
}O header vai sem espaço (Authorization:${AUTH}) e o valor, com o espaço depois de Bearer, fica na env AUTH. Isso contorna um bug do npx no Windows que corta espaços dentro de args. Salve, reinicie o Claude Desktop e as tools aparecem no ícone de conectores do chat.
Claude.ai (web)
Os conectores customizados do claude.ai (Configurações, Conectores, "Adicionar conector personalizado") usam OAuth: você informa a URL do MCP e o claude.ai conduz o login OAuth do servidor. Não há campo para colar uma apikey fixa.
Como o /mcp da Shiftz autentica hoje pelo header Authorization: Bearer <apikey> (sem OAuth), ele ainda não pode ser adicionado direto no claude.ai web. Para usar o Shiftz no ecossistema Claude agora, vá de Claude Code ou Claude Desktop. Quando a Shiftz publicar o fluxo OAuth no endpoint MCP, esta seção será atualizada.
Codex CLI
O Codex CLI da OpenAI lê os MCP servers de ~/.codex/config.toml. O suporte a servidores HTTP remotos é nativo, mas fica atrás de uma flag experimental (experimental_use_rmcp_client), que vai no topo do arquivo:
experimental_use_rmcp_client = true
[mcp_servers.shiftz]
url = "https://api.shiftz.com.br/mcp"
bearer_token_env_var = "SHIFTZ_API_KEY"Na primeira aba, exporte a chave (export SHIFTZ_API_KEY="shz_xxx.yyy") e o Codex a envia como Authorization: Bearer .... Em versões antigas, ou sem a flag experimental, use a segunda aba (ponte mcp-remote, igual ao Claude Desktop). O comando codex mcp add hoje só registra servers stdio, então o setup HTTP é feito editando o TOML.
Gemini CLI
O Gemini CLI do Google conecta direto via HTTP. O jeito mais rápido é o comando gemini mcp add:
gemini mcp add --transport http --scope user \
--header "Authorization: Bearer shz_xxx.yyy" \
shiftz https://api.shiftz.com.br/mcpAtenção ao campo no ~/.gemini/settings.json: para Streamable HTTP use httpUrl. O campo url (sem http) seleciona o transport SSE, que é diferente. Dentro do Gemini CLI, /mcp lista os servers conectados.
OpenCode
O OpenCode usa a chave mcp no opencode.json (na raiz do projeto) ou em ~/.config/opencode/opencode.json. Servidores remotos têm "type": "remote":
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"shiftz": {
"type": "remote",
"url": "https://api.shiftz.com.br/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer {env:SHIFTZ_API_KEY}"
}
}
}
}A interpolação de env no OpenCode é {env:VAR} (e não ${VAR}); você também pode colar a chave literal em headers. Se o OpenCode tentar abrir um fluxo OAuth ao receber o 401, adicione "oauth": false no bloco do server.
OpenClaw
O OpenClaw guarda os MCP servers em ~/.openclaw/openclaw.json, sob mcp.servers. Dá para adicionar pela CLI ou editando o arquivo:
openclaw mcp add shiftz \
--url https://api.shiftz.com.br/mcp \
--transport streamable-http \
--header "Authorization=Bearer shz_xxx.yyy"No --header do OpenClaw o separador é = (Authorization=Bearer ...), diferente do : usado por Claude e Gemini. Rode openclaw mcp status para confirmar que o server registrou.
Hermes
O Hermes Agent (Nous Research) lê os MCP servers do bloco mcp_servers da config em YAML (veja o cli-config.yaml.example do projeto). Servidores remotos usam url + headers:
mcp_servers:
shiftz:
url: "https://api.shiftz.com.br/mcp"
headers:
Authorization: "Bearer shz_xxx.yyy"Depois de editar o arquivo, recarregue com /reload-mcp dentro do Hermes. Campos opcionais por server incluem timeout e connect_timeout.
Conexão manual
Está construindo um cliente próprio ou só quer testar a conexão na unha? O handshake do MCP é um POST JSON-RPC com a apikey no header:
curl -X POST https://api.shiftz.com.br/mcp \
-H "Authorization: Bearer shz_xxx.yyy" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "curl", "version": "1" }
}
}'Exemplos de prompts
Conectado, qualquer cliente entende pedidos em linguagem natural e escolhe a tool sozinho:
- "Lista minhas instâncias do Shiftz" →
shiftz_list_instances - "Cria uma instância chamada
marketing-01e me dá o QR Code" →shiftz_create_instance(comqrcode: true) - "Como está a conexão da
marketing-01?" →shiftz_get_connection_state - "Manda 'Olá!' do
marketing-01pro 5511999998888" →shiftz_send_text
Não precisa decorar nomes de tool: descreva a intenção e o agente resolve. A apikey limita o alcance: chave org-wide enxerga todas as instâncias, chave instance-scoped só a sua.