Documentação da API
API REST para integrar o WhatsApp ao seu sistema: provisione números, envie e receba mensagens e mídias, e receba eventos por webhook.
Visão geral
Todas as requisições usam a base URL abaixo e retornam JSON. Há dois conjuntos de rotas: as da conta (provisionar/gerenciar números, autenticadas pela chave da conta) e as da instância (enviar/receber, no padrão de mercado, autenticadas pelo Client-Token).
Base URL
https://api.rexzap.rexsuite.com
id + token na URL. O Client-Token é da sua conta e vai no header das rotas de instância.Autenticação
Não há login por OAuth: cada conjunto de rotas usa um cabeçalho próprio.
| Header | Uso |
|---|---|
X-RexZap-Account | Chave de API da conta. Autentica as rotas /provisionar*. Gere/veja no painel (card “API do seu sistema”). |
Client-Token | Token da conta. Vai no header de toda rota de instância (/instances/...). |
Início rápido
Em quatro passos: provisione um número, mostre o QR, espere conectar e envie.
# 1) provisione um número (retorna id, token, clientToken e a URL do QR) curl -X POST https://api.rexzap.rexsuite.com/provisionar \ -H "X-RexZap-Account: SUA_CHAVE_DA_CONTA" # 2) pegue o QR (data:image/png;base64,...) e exiba no seu sistema curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/qr-code/image \ -H "Client-Token: {clientToken}" # 3) verifique a conexão até status = conectado curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/status \ -H "Client-Token: {clientToken}" # 4) envie a primeira mensagem curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-text \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","message":"olá 👋"}'
Provisionar números
Rotas da conta — header X-RexZap-Account. Seu sistema cria e gerencia números sem entrar no painel.
Resposta 200
{
"id": "34DEA54FF15492214CB8FAD5470C62F8",
"token": "9E8937994C27C132E835A0680B194C21",
"clientToken": "92912E057CE1...",
"status": "desconectado",
"qrCodeUrl": "/instances/{id}/token/{token}/qr-code/image",
"statusUrl": "/instances/{id}/token/{token}/status"
}
Erros
401 chave inválida · 402 sem assinatura ativa · 409 cota esgotada
Resposta 200
[
{ "id": "...", "token": "...", "clientToken": "...",
"numero": "5544999999999", "perfilNome": "Maria", "status": "conectado" }
]
Resposta 200
{ "ok": true }Cota
Resposta 200
{ "used": 1, "limit": 10, "active": true, "status": "active" }Enviar texto
Rotas de instância — path /instances/{id}/token/{token} + header Client-Token. A resposta de envio traz os ids da mensagem.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| message req | string | Texto da mensagem. Aceita quebras de linha (envie como \n escapado no JSON). |
| mentioned | string[] | Números a mencionar (só dígitos, com DDI). Use @número no texto para o destaque aparecer. Em grupo, marca os membros citados. Opcional. |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar imagem
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| image req | string | URL pública ou base64 (data URI) da imagem. |
| caption | string | Legenda (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar documento
{extension} na URL = extensão do arquivo (ex.: pdf).Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| document req | string | URL pública ou base64 (data URI) do arquivo. |
| fileName | string | Nome do arquivo (opcional). |
| caption | string | Legenda (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
MessageStatusCallback, campo ids) e no de envio (DeliveryCallback, campo messageId). Vale para todos os send-*. Esses dois callbacks trazem também o zaapId — use-o para casar o retorno do send (zaap) com o id real do WhatsApp.Enviar áudio
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| audio req | string | URL pública ou base64 (data URI) do áudio. |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar vídeo
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| video req | string | URL pública ou base64 (data URI) do vídeo. |
| caption | string | Legenda (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Guia de links, botões e listas
O RexZap já possui quatro endpoints para criar experiências mais objetivas: prévia de link, botões de ação, respostas rápidas e menu de opções. Todos passam pela fila confiável de envio.
/send-link está disponível em todos os motores. Botões e listas são experimentais, dependem da habilitação global da plataforma e estão disponíveis somente em instâncias Baileys ou Evolution Go. Se a função estiver desabilitada, a API retorna 400; se o motor não for compatível, retorna 422 com ENGINE_INTERACTIVE_NOT_SUPPORTED.Qual endpoint usar
| Endpoint | Quando usar | Experiência para o contato |
|---|---|---|
/send-link | Produto, checkout, documento, proposta ou página externa. | Texto acompanhado da prévia visual do endereço. |
/send-button-actions | Poucas ações diretas: abrir URL, ligar ou responder. | Botões de chamada para ação abaixo da mensagem. |
/send-button-list | Poucas respostas rápidas, como Vendas, Suporte e Financeiro. | Um toque envia a opção escolhida de volta ao webhook. |
/send-option-list | Menu com várias categorias, serviços ou etapas. | O contato abre uma lista e seleciona um item. |
Compatibilidade por motor
| Motor | /send-link | Botões e listas | Comportamento |
|---|---|---|---|
| Baileys | Suportado | Suportado | Ações nativas, respostas rápidas e listas; callbacks normalizados. |
| Evolution Go | Suportado | Suportado | Ações, respostas rápidas e listas pelo contrato nativo do motor. |
| Evolution API Node | Suportado | Bloqueado | O motor pode aceitar o envio e não entregar; o RexZap rejeita antes de enfileirar. |
| WPPConnect | Suportado | Bloqueado | As rotas interativas estão depreciadas e não oferecem confirmação confiável de entrega. |
Fluxo recomendado
Use textos curtos, ofereça somente as escolhas necessárias para a etapa atual e atribua um id estável a cada resposta. Botões reply retornam buttonsResponseMessage.buttonId; itens de lista retornam listResponseMessage.selectedRowId no webhook de mensagens recebidas.
reply, ou somente ações url/call. Para respostas rápidas, prefira /send-button-list. Botões de URL e ligação abrem a ação no aparelho e não geram callback de seleção.message o que o contato deve responder se o botão ou a lista não aparecer, por exemplo: “Responda 1 para Vendas ou 2 para Suporte”. Não dependa exclusivamente do componente interativo para uma ação crítica.vendas, suporte e acompanhar_pedido em vez de usar o texto visível como identificador. Assim, a automação continua funcionando quando o rótulo for traduzido ou alterado.Enviar link
Envia um texto com prévia de link (título, descrição e imagem do site quando disponível).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| linkUrl req | string | URL que gera a prévia do link (título, descrição e imagem do site). |
| message | string | Texto enviado junto do link (opcional). Se omitido, o próprio endereço é usado como texto para garantir a entrega. |
| title | string | Título da prévia (opcional). |
| linkDescription | string | Descrição da prévia (opcional). |
| image | string | URL ou base64 da miniatura da prévia (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-link \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","linkUrl":"https://loja.exemplo.com/produtos/123","message":"Confira os detalhes e finalize seu pedido:","title":"Plano Profissional","linkDescription":"Ativação imediata após a confirmação","image":"https://loja.exemplo.com/img/plano-profissional.jpg"}'
Enviar localização
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| latitude | number | Latitude em graus decimais. A API não valida, mas envie junto com a longitude (sem isso, o pino vai em 0,0). |
| longitude | number | Longitude em graus decimais. |
| title | string | Nome do local (opcional). |
| address | string | Endereço do local (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar contato
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| contactName req | string | Nome do contato a compartilhar. |
| contactPhone req | string | Número do contato a compartilhar (só dígitos, com DDI). |
| contactBusinessDescription | string | Nome comercial do contato (opcional). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar figurinha
webp.Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| sticker req | string | URL pública ou base64 (data URI) da figurinha (webp). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Enviar GIF
mp4).Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| gif req | string | URL pública ou base64 (data URI) do GIF/vídeo (mp4). |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
| delayTyping | number | Segundos mostrando 'digitando...' antes de enviar (0-15, opcional). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Reagir a mensagem
Envia uma reação (emoji) a uma mensagem existente. Passa pela fila como os demais envios.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| messageId req | string | ID da mensagem que vai receber a reação. |
| reaction req | string | Emoji da reação (ex.: 👍). |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-reaction \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","messageId":"3EB0...","reaction":"👍"}'
Remover reação
Remove a reação previamente enviada a uma mensagem (envia uma reação vazia).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| messageId req | string | ID da mensagem cuja reação será removida. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Marcar como lida
Marca uma mensagem recebida como lida (os ticks azuis no aparelho do contato).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| messageId req | string | ID da mensagem a marcar como lida. |
Resposta 200
{ "value": true }
Editar mensagem
Edita o texto de uma mensagem enviada por você. O WhatsApp só permite editar nos primeiros 15 minutos e somente mensagens de texto próprias.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| messageId req | string | ID retornado no envio (messageId ou zaapId) da mensagem de texto própria. |
| message req | string | Novo texto da mensagem. |
Resposta 200
{ "value": true }
Você pode enviar o zaapId devolvido pelo envio: a RexZap traduz para o ID definitivo do WhatsApp. Se a mensagem ainda estiver na fila, a API responde 409 MESSAGE_PENDING. Toda falha retorna value:false, code e error. No Baileys, o SERVER_ACK sozinho não basta: a API aguarda confirmação de entrega da operação.
Erros
{ "value": false, "code": "MESSAGE_PENDING", "error": "mensagem ainda esta na fila; aguarde a confirmacao do WhatsApp e tente novamente" }
Exemplo
curl -X POST "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/edit-message" \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5511999999999","messageId":"3EB0C5A277F7F9B6C599","message":"Texto corrigido"}'
Apagar mensagem
Apaga uma mensagem própria para todos. Os parâmetros vão na query string. O messageId pode ser o zaapId devolvido pelo envio; a RexZap resolve o ID definitivo antes de chamar o motor.
Parâmetros
| Campo | Tipo | Descrição |
|---|---|---|
| messageId req | string | ID definitivo ou zaapId retornado pelo envio. |
| phone req | string | Número da conversa onde está a mensagem (só dígitos, com DDI). |
| owner req | boolean | Deve ser true. Somente mensagens enviadas pela própria instância podem ser apagadas para todos. |
Resposta 200
{ "value": true }
A API nunca responde sucesso apenas porque o gateway aceitou a chamada. No Baileys, aguarda a entrega da operação ao WhatsApp do destino; sem confirmação, retorna value:false com um código distinguível, como MESSAGE_PENDING, MESSAGE_NOT_OWN, INSTANCE_DISCONNECTED ou ENGINE_CONFIRMATION_TIMEOUT.
Erros
{ "value": false, "code": "MESSAGE_NOT_OWN", "error": "somente mensagens enviadas pela propria instancia podem ser apagadas para todos" }
Exemplo
curl -X DELETE "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/messages?messageId=3EB0...&phone=5544999999999&owner=true" \ -H "Client-Token: {clientToken}"
Encaminhar mensagem
Encaminha uma mensagem existente para outro número. Passa pela fila como os demais envios.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número de destino para onde encaminhar (só dígitos, com DDI). |
| messageId req | string | ID da mensagem a encaminhar. |
| messagePhone req | string | Número da conversa de origem onde está a mensagem (só dígitos, com DDI). |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Botões de ação (beta)
Envia uma mensagem com botões de ação (abrir link, ligar ou resposta rápida). Passa pela fila como os demais envios.
400 { "error": "recurso beta desabilitado" }.Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| message req | string | Texto principal da mensagem (corpo). |
| title | string | Título exibido acima do texto. Opcional no Baileys e obrigatório no Evolution Go. |
| footer | string | Rodapé exibido abaixo dos botões. Opcional no Baileys e obrigatório no Evolution Go. |
| buttonActions req | object[] | Até 3 botões. Cada item: type (url, call ou reply), label, url (quando url), phone (quando call) e id único. Não combine reply com url/call na mesma mensagem. |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-button-actions \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","title":"Seu pedido está pronto","message":"Escolha uma ação. Se os botões não aparecerem, acesse o link enviado no texto.","footer":"Pedido #12345","buttonActions":[{"id":"acompanhar_pedido","type":"url","label":"Acompanhar","url":"https://loja.exemplo.com/pedidos/12345"},{"id":"ligar_loja","type":"call","label":"Ligar","phone":"551140001234"}]}'
Lista de botões (beta)
Envia uma mensagem com botões de resposta rápida (o contato toca um botão e a resposta volta como mensagem). Passa pela fila como os demais envios.
400 { "error": "recurso beta desabilitado" }.Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| message req | string | Texto principal da mensagem (corpo). |
| title | string | Título exibido acima do texto. Opcional no Baileys e obrigatório no Evolution Go. |
| footer | string | Rodapé exibido abaixo dos botões. Opcional no Baileys e obrigatório no Evolution Go. |
| buttonList req | object | Objeto com até 3 itens em buttons. Cada botão usa label e um id único. O ID é devolvido em buttonsResponseMessage.buttonId; se omitido, o RexZap gera um ID estável para a mensagem. |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-button-list \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","title":"Atendimento","message":"Escolha um setor. Se os botões não aparecerem, responda VENDAS ou SUPORTE.","footer":"Você pode voltar ao menu a qualquer momento","buttonList":{"buttons":[{"id":"vendas","label":"Vendas"},{"id":"suporte","label":"Suporte"},{"id":"financeiro","label":"Financeiro"}]}}'
Lista de opções (beta)
Envia uma mensagem com um menu de lista (o contato abre a lista e escolhe uma opção). Passa pela fila como os demais envios.
400 { "error": "recurso beta desabilitado" }.Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número do destinatário (só dígitos, com DDI). |
| message req | string | Texto principal da mensagem (corpo). |
| title | string | Título exibido acima do texto (opcional). Se omitido, o Evolution Go usa optionList.title. |
| footer | string | Rodapé exibido abaixo dos botões. Opcional no Baileys e obrigatório no Evolution Go. |
| optionList req | object | Objeto com title, buttonLabel e até 10 itens em options. Cada opção usa title, description (opcional) e um id único. O ID é devolvido em listResponseMessage.selectedRowId; se omitido, o RexZap gera um ID estável para a mensagem. |
| messageId | string | ID de uma mensagem para responder (reply/citação). Opcional. |
| delayMessage | number | Segundos de espera antes de enviar (0-15, opcional). Sem isso, usa o delay padrão da conta. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/send-option-list \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","title":"Central de atendimento","message":"Selecione o assunto. Se a lista não aparecer, digite o nome da opção.","footer":"Atendimento de segunda a sexta","optionList":{"title":"Assuntos","buttonLabel":"Ver opções","options":[{"id":"novo_pedido","title":"Fazer um pedido","description":"Produtos, preços e disponibilidade"},{"id":"acompanhar_pedido","title":"Acompanhar pedido","description":"Prazo e andamento da entrega"},{"id":"troca_devolucao","title":"Troca ou devolução","description":"Ajuda após a compra"},{"id":"falar_atendente","title":"Falar com atendente","description":"Continuar com uma pessoa"}]}}'
Listar fila
Mensagens ainda na fila de envio (aguardando o delay/aquecimento). Cada item traz o zaapId usado para remover.
Resposta 200
[
{ "zaapId": "...", "phone": "5544999999999",
"type": "text", "message": "olá 👋",
"scheduled": "2024-06-10T12:00:00+00:00" }
]
type é o tipo do envio (text, image, link, etc.), message é o conteúdo enfileirado (texto, URL/base64 ou JSON do tipo) e scheduled é a data/hora ISO-8601 em que o item sai da fila. Para contar sem listar, use ?count=true → { "value": 3 }.Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/queue \ -H "Client-Token: {clientToken}"
Limpar fila
pendente da instância. Itens já em envio não são afetados.Resposta 200
{ "value": true }Remover da fila
{zaapid} na URL = o zaapId retornado no envio (ou em /queue). Só remove se ainda estiver pendente.Resposta 200
{ "value": true }Status de texto
Publica um status (story) de texto no status@broadcast. Visível a todos os contatos que têm o número salvo. É síncrono (não passa pela fila): publica direto e os três campos da resposta trazem o MessageId real da publicação.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| message req | string | Texto do status. Aceita quebras de linha (envie como \n escapado no JSON). |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Status de imagem
Publica um status (story) de imagem no status@broadcast. Visível a todos os contatos que têm o número salvo. É síncrono (não passa pela fila): publica direto e os três campos da resposta trazem o MessageId real da publicação.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| image req | string | URL pública ou base64 (data URI) da imagem. |
Resposta 200
{ "zaapId": "...", "messageId": "...", "id": "..." }
Número existe no WhatsApp
Verifica se um número tem conta no WhatsApp antes de enviar.
{phone} na URL = número a verificar (só dígitos, com DDI).Resposta 200
{ "exists": true, "phone": "5544999999999", "outputPhone": "5544999999999" }
Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/phone-exists/5544999999999 \ -H "Client-Token: {clientToken}"
Foto de perfil
null se o contato não tiver foto ou se ela estiver oculta na privacidade.Resposta 200
{ "link": "https://...whatsapp.net/...jpg" }
{ "link": null }
Listar contatos
Lista os contatos com quem o número já conversou. Não é a agenda inteira do aparelho — só quem trocou mensagens com esta instância. Paginado.
page (a partir de 1) e pageSize (padrão 50) na query são opcionais.Resposta 200
[
{ "phone": "5544999999999", "name": "Maria" }
]
Exemplo
curl "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/contacts?page=1&pageSize=50" \ -H "Client-Token: {clientToken}"
Dados do contato
{phone} na URL = número do contato (só dígitos, com DDI).Resposta 200
{
"phone": "5544999999999",
"name": "Maria",
"exists": true
}
Listar chats
Lista as conversas (chats) da instância — uma por número que já trocou mensagens. Mesma semântica de contatos: não inclui conversas sem histórico nesta instância. Paginado.
page (a partir de 1) e pageSize (padrão 50) na query são opcionais.Resposta 200
[
{ "phone": "5544999999999", "name": "Maria",
"lastMessageText": "até amanhã", "lastMessageTime": 1718000000000,
"unread": 0, "archived": false }
]
lastMessageTime é epoch em ms. unread e archived vêm fixos (0 / false) nesta lista; o estado real de leitura/arquivamento é alterado por modify-chat.Exemplo
curl "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/chats?page=1&pageSize=50" \ -H "Client-Token: {clientToken}"
Mensagens do chat
Histórico de mensagens de uma conversa, da mais recente para a mais antiga. Use lastMessageId para paginar (cursor).
{phone} na URL = número da conversa. amount (padrão 50) e lastMessageId (continuar a partir desta mensagem) na query são opcionais.Resposta 200
[
{ "phone": "5544999999999", "fromMe": false,
"tipo": "text", "texto": "oi", "messageId": "3EB0...",
"status": "RECEIVED", "momment": 1718000000000,
"midiaUrl": null, "midiaMime": null, "midiaNome": null }
]
tipo (text, image, audio, video, document, sticker, reaction, location, contact…), texto (texto ou resumo), momment (epoch ms), status (RECEIVED, SENT, READ…). Para mídia, midiaUrl é o link proxy estável do RexZap (null quando não há), com midiaMime e midiaNome.Exemplo
curl "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/chat-messages/5544999999999?amount=20" \ -H "Client-Token: {clientToken}"
Dados do chat
{phone} na URL = número da conversa (só dígitos, com DDI). Retorna 404 se não houver mensagens dessa conversa nesta instância.Resposta 200
{
"phone": "5544999999999",
"name": "Maria",
"lastMessageTime": 1718000000000,
"messagesCount": 42
}
Modificar chat
Arquiva, desarquiva, marca como lida/não lida ou apaga uma conversa. A ação delete é destrutiva (apaga a conversa) — use com cuidado.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| phone req | string | Número da conversa (só dígitos, com DDI). |
| action req | string | Ação a aplicar: archive, unarchive, read, unread ou delete. |
Resposta 200
{ "value": true }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/modify-chat \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"phone":"5544999999999","action":"archive"}'
Criar grupo
Cria um grupo e adiciona os participantes informados. O número conectado entra como administrador. Os grupos usam id@g.us; nas rotas de grupo seguintes, envie esse id no campo groupId (com o sufixo @g.us, como retornado aqui).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupName req | string | Nome do grupo a criar. |
| phones req | string[] | Números dos participantes a adicionar (só dígitos, com DDI). |
Resposta 200
{ "groupId": "120363000000000000@g.us", "invitationLink": null }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/create-group \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"groupName":"Equipe RexZap","phones":["5544999999999","5544988888888"]}'
Alterar nome do grupo
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| groupName req | string | Novo nome do grupo. |
Resposta 200
{ "value": true }
Alterar foto do grupo
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| groupPhoto req | string | URL pública ou base64 (data URI) da nova foto (imagem quadrada). |
Resposta 200
{ "value": true }
Alterar descrição do grupo
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| groupDescription | string | Nova descrição do grupo (vazio limpa a descrição). |
Resposta 200
{ "value": true }
Configurações do grupo
Controla quem pode enviar mensagens e quem pode editar os dados do grupo (nome, foto, descrição). Requer administrador.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| adminOnlyMessage | boolean | true = só administradores enviam mensagens. Opcional. |
| adminOnlySettings | boolean | true = só administradores editam os dados do grupo (nome, foto, descrição). Opcional. |
Resposta 200
{ "value": true }
Adicionar participante
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| phones req | string[] | Números a adicionar/remover/promover (só dígitos, com DDI). |
Resposta 200
{ "value": true }
Remover participante
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| phones req | string[] | Números a adicionar/remover/promover (só dígitos, com DDI). |
Resposta 200
{ "value": true }
Promover a admin
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| phones req | string[] | Números a adicionar/remover/promover (só dígitos, com DDI). |
Resposta 200
{ "value": true }
Rebaixar admin
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
| phones req | string[] | Números a adicionar/remover/promover (só dígitos, com DDI). |
Resposta 200
{ "value": true }
Sair do grupo
Body
| Campo | Tipo | Descrição |
|---|---|---|
| groupId req | string | ID do grupo (id@g.us). |
Resposta 200
{ "value": true }
Dados do grupo
Retorna os metadados do grupo: nome, descrição, dono, participantes e quem é administrador.
{phone} na URL = ID do grupo (id@g.us).Resposta 200
{
"phone": "120363000000000000",
"subject": "Equipe RexZap",
"description": "Grupo da equipe",
"owner": "5544999999999",
"participants": [
{ "phone": "5544999999999", "isAdmin": true, "isSuperAdmin": true },
{ "phone": "5544988888888", "isAdmin": false, "isSuperAdmin": false }
]
}
Dados por convite
Lê os metadados de um grupo a partir do link de convite, sem precisar fazer parte dele.
{url} = link de convite do grupo (https://chat.whatsapp.com/...).Resposta 200
{
"phone": "120363000000000000",
"subject": "Equipe RexZap",
"description": "Grupo da equipe",
"owner": "5544999999999",
"participants": [
{ "phone": "5544999999999", "isAdmin": true, "isSuperAdmin": true }
]
}
Exemplo
curl "https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/group-invitation-metadata?url=https://chat.whatsapp.com/ABC123" \ -H "Client-Token: {clientToken}"
Status
error é sempre string — vazia quando conectado.Resposta 200
{ "connected": true, "session": true, "error": "", "smartphoneConnected": true }
{ "connected": false, "session": false, "error": "You are not connected.", "smartphoneConnected": false }Dados do aparelho
device vêm como string vazia.Resposta 200
{
"phone": "5544999999999", "imgUrl": null,
"device": { "wa_version": "", "mcc": "", "mnc": "",
"os_version": "", "device_manufacturer": "", "device_model": "",
"osbuildnumber": "", "platform": "" }
}Alterar nome do perfil
Altera o nome de exibição (perfil) do número conectado.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | string | Novo nome de exibição do perfil. |
Resposta 200
{ "value": true }
Exemplo
curl -X PUT https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/update-name \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"value":"Atendimento RexZap"}'
Alterar foto do perfil
Altera a foto de perfil do número conectado. Aplicação é best-effort: o WhatsApp pode recusar a imagem (formato/tamanho) e a foto pode não trocar mesmo com resposta de sucesso.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | string | URL pública ou base64 (data URI) da nova foto (imagem quadrada). |
Resposta 200
{ "value": true }
Leitura automática
Liga/desliga a marcação automática como lida das mensagens recebidas (ticks azuis).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | boolean | true marca toda mensagem recebida como lida automaticamente; false desativa. |
Resposta 200
{ "value": true }
Rejeitar chamadas
Liga/desliga a rejeição automática de chamadas recebidas (voz e vídeo). A rejeição é best-effort: depende do comportamento do WhatsApp e pode variar.
Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | boolean | true rejeita automaticamente as chamadas recebidas; false desativa. |
Resposta 200
{ "value": true }
Mensagem de chamada rejeitada
Define o texto enviado automaticamente ao contato quando uma chamada é rejeitada (requer a rejeição automática ligada).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| value | string | Texto enviado ao contato após rejeitar a chamada (vazio limpa a mensagem). |
Resposta 200
{ "value": true }
QR Code
conectado. Enquanto não há QR (sessão já conectada ou ainda gerando), value vem null.Resposta 200
{ "value": "data:image/png;base64,iVBORw0KG..." }
{ "value": null }QR Code (texto)
/qr-code/image, mas como string PNG em base64 (data URI), para você renderizar do seu jeito. Vem null enquanto não há QR (sessão já conectada ou ainda gerando).Resposta 200
{ "value": "data:image/png;base64,iVBORw0KG..." }
{ "value": null }
Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/qr-code \ -H "Client-Token: {clientToken}"
Restaurar sessão
Resposta 200
{ "value": true }Reiniciar / Desconectar
Resposta 200
{ "value": true }Resposta 200
{ "value": true }Configurar webhooks
Defina as URLs que receberão os eventos. Rotas PUT de instância, body { "value": "https://sua-app/webhook" }.
| PUT | Dispara quando |
|---|---|
/update-webhook-received | Mensagem recebida. |
/update-webhook-received-delivery | Recebidas + enviadas pelo próprio número. |
/update-webhook-message-status | Mudança de status da mensagem. |
/update-webhook-connected | Número conectou. |
/update-webhook-disconnected | Número desconectou. |
Webhook ao enviar
POST sempre que o próprio número envia uma mensagem (saída da fila). Distinto de /update-webhook-received-delivery, que trata mensagens recebidas. Body com a URL; envie string vazia para desligar.Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | string | URL do seu endpoint (https). String vazia desliga o webhook. |
Resposta 200
{ "value": true }
Webhook de presença
POST quando muda a presença de um contato no chat (digitando, gravando áudio, online/offline). Body com a URL; envie string vazia para desligar.Body
| Campo | Tipo | Descrição |
|---|---|---|
| value req | string | URL do seu endpoint (https). String vazia desliga o webhook. |
Resposta 200
{ "value": true }
Eventos recebidos
O RexZap faz POST na sua URL com estes formatos.
Mensagem de texto
Todo ReceivedCallback traz os campos de topo abaixo e mais um objeto conforme o tipo da mensagem. senderLid é o @lid do remetente (quando houver). senderPhoto e photo vêm null no momento.
{
"waitingMessage": false, "isGroup": false,
"instanceId": "...", "messageId": "...",
"phone": "5544999999999", "senderLid": null, "fromMe": false,
"momment": 1718000000000, "status": "RECEIVED",
"chatName": "Maria", "senderPhoto": null, "senderName": "Maria",
"participantPhone": null, "photo": null, "broadcast": false,
"type": "ReceivedCallback",
"text": { "message": "olá" }
}
"referenceMessageId": "<id da mensagem citada>" (logo antes de type).Mídia (imagem, áudio, vídeo, documento, sticker)
Mesma estrutura, com um objeto por tipo. A URL é temporária: o RexZap não arquiva a mídia. Baixe e persista o arquivo na sua aplicação se precisar conservá-lo.
{
"type": "ReceivedCallback", "status": "RECEIVED", "instanceId": "...",
"phone": "...", "fromMe": false, "momment": 1718000000000, "broadcast": false,
"image": { "imageUrl": "https://api.rexzap.rexsuite.com/media/...", "caption": "...", "mimeType": "image/jpeg" },
"audio": { "audioUrl": "...", "mimeType": "audio/ogg" },
"video": { "videoUrl": "...", "caption": "...", "mimeType": "video/mp4" },
"document": { "documentUrl": "...", "mimeType": "application/pdf", "fileName": "nota.pdf" },
"sticker": { "stickerUrl": "...", "mimeType": "image/webp" }
}
Reação
Quando reagem a uma mensagem. referencedMessage aponta a mensagem reagida.
{
"type": "ReceivedCallback", "status": "RECEIVED", "instanceId": "...", "messageId": "...",
"phone": "...", "fromMe": false, "momment": 1718000000000,
"reaction": {
"value": "❤️", "time": 1718000000000,
"referencedMessage": { "messageId": "3EB0...", "fromMe": true, "phone": "5544999999999", "participant": null }
}
}
Localização
{ "type": "ReceivedCallback", "instanceId": "...", "phone": "...", "fromMe": false,
"location": { "longitude": -38.5014, "latitude": -3.7319, "address": "Rua X, 123", "url": "" } }
Contato
{ "type": "ReceivedCallback", "instanceId": "...", "phone": "...", "fromMe": false,
"contact": { "displayName": "Cesar", "vCard": "BEGIN:VCARD...END:VCARD", "phones": ["5544999999999"] } }
Resposta de botão / lista
Quando o contato escolhe um botão de resposta ou um item de lista. Botões de URL e ligação não geram este callback.
{ ..., "buttonsResponseMessage": { "buttonId": "vendas", "message": "Vendas" } }
{ ..., "listResponseMessage": { "message": "Produtos, preços e disponibilidade", "title": "Fazer um pedido", "selectedRowId": "novo_pedido" } }
Status / conexão
{ "type": "MessageStatusCallback", "instanceId": "...", "status": "SENT", "ids": ["<id real>"], "zaapId": "<id da fila>", "phone": "...", "momment": 1718000000000 }
{ "type": "ConnectedCallback", "instanceId": "...", "momment": 1718000000000 }
{ "type": "DisconnectedCallback", "instanceId": "...", "momment": 1718000000000 }
MessageStatusCallback emite SENT (saiu da fila), RECEIVED (entregue ao destinatário), READ (lido) e PLAYED (áudio ouvido), conforme os recibos do WhatsApp. Cada um traz o zaapId e o id real em ids.Ao enviar (DeliveryCallback)
Disparado quando o próprio número envia uma mensagem (saída da fila), na URL de /update-webhook-delivery.
{
"type": "DeliveryCallback",
"instanceId": "...", "messageId": "<id real>", "zaapId": "<id da fila>",
"phone": "5544999999999",
"momment": 1718000000000
}
Presença no chat (ChatPresenceCallback)
Disparado quando muda a presença de um contato no chat, na URL de /update-webhook-chat-presence. O campo status assume composing (digitando), recording (gravando áudio), available (online), unavailable (offline) ou paused (parou de digitar).
{
"type": "ChatPresenceCallback", "instanceId": "...",
"phone": "5544999999999",
"status": "composing",
"momment": 1718000000000
}
Criar produto
400 { "error": "recurso business desabilitado" }. As respostas de catálogo/produto/etiquetas são repassadas cruas do motor WhatsApp Business — os campos dependem do WhatsApp e podem variar; os exemplos abaixo são ilustrativos.Cria um produto no catálogo do número conectado (conta Business).
Body
| Campo | Tipo | Descrição |
|---|---|---|
| name req | string | Nome do produto. |
| price | number | Preço do produto (na moeda de currency). Opcional na API, mas exigido pelo WhatsApp. |
| currency | string | Código da moeda ISO 4217 (ex.: BRL). Opcional. |
| description | string | Descrição do produto (opcional). |
| images | string[] | URLs públicas ou base64 (data URI) das imagens do produto (opcional). |
| url | string | Link externo do produto (opcional). |
| retailerId | string | SKU/código interno do produto (opcional). |
| isHidden | boolean | true oculta o produto do catálogo (opcional). |
Resposta 200
{ "id": "7100...", "name": "Camiseta RexZap", "currency": "BRL", "isHidden": false }
Exemplo
curl -X POST https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/products \ -H "Client-Token: {clientToken}" \ -H "Content-Type: application/json" \ -d '{"name":"Camiseta RexZap","price":59.9,"currency":"BRL"}'
Catálogo próprio
Lista os produtos do catálogo do número conectado (conta Business).
Resposta 200
{
"products": [
{ "id": "7100...", "name": "Camiseta RexZap", "currency": "BRL" }
]
}
Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/catalogs \ -H "Client-Token: {clientToken}"
Catálogo de um número
Lista os produtos do catálogo de outro número (conta Business).
{phone} na URL = número do dono do catálogo (só dígitos, com DDI).Resposta 200
{
"products": [
{ "id": "7100...", "name": "Camiseta", "currency": "BRL" }
]
}
Dados do produto
{productId} na URL = ID do produto (retornado em /products ou /catalogs).Resposta 200
{
"id": "7100...",
"name": "Camiseta RexZap",
"currency": "BRL",
"description": "...",
"isHidden": false
}
Excluir produto
{productId} na URL = ID do produto a excluir do catálogo.Resposta 200
{ "value": true }Listar etiquetas
Lista as etiquetas (tags) da conta. Só WhatsApp Business Multi-Devices.
Resposta 200
[
{ "id": "1", "name": "Novo cliente", "color": 0 }
]
Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/tags \ -H "Client-Token: {clientToken}"
Adicionar etiqueta ao chat
Aplica uma etiqueta a uma conversa. Só WhatsApp Business Multi-Devices.
{phone} = número da conversa (só dígitos, com DDI). {tag} = ID da etiqueta (de /tags).Resposta 200
{ "value": true }
Exemplo
curl -X PUT https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/chats/5544999999999/tags/1/add \ -H "Client-Token: {clientToken}"
Remover etiqueta do chat
Remove uma etiqueta de uma conversa. Só WhatsApp Business Multi-Devices. Por compatibilidade com a PlugzAPI, esta rota usa o método GET.
{phone} = número da conversa (só dígitos, com DDI). {tag} = ID da etiqueta (de /tags).Resposta 200
{ "value": true }
Exemplo
curl https://api.rexzap.rexsuite.com/instances/{id}/token/{token}/chats/5544999999999/tags/1/remove \ -H "Client-Token: {clientToken}"
Erros
Todo erro vem como JSON com o status HTTP correspondente. As operações de editar e apagar retornam também value:false e um code estável. Antes de qualquer send-*, o número precisa estar com status conectado; nessas rotas, desconexão continua retornando 400. Em editar/apagar, desconexão retorna 503 INSTANCE_DISCONNECTED.
| Código | Significado |
|---|---|
400 | Número desconectado, parâmetro obrigatório ausente/inválido, ou recurso beta/business desabilitado. |
401 | Credencial inválida (Client-Token ou chave da conta). |
402 | Sem assinatura ou isenção ativa. |
404 | Recurso não encontrado (ex.: chat sem histórico nesta instância). |
409 | Cota de números esgotada. |
422 | O motor da instância não oferece a operação solicitada com confiabilidade. Para botões/listas, o código é ENGINE_INTERACTIVE_NOT_SUPPORTED. |
503 | Instância desconectada durante uma operação síncrona. |
504 | O motor não confirmou a operação dentro do prazo. |
Dicas — Manter o número conectado
A conexão não-oficial funciona como um aparelho vinculado ao WhatsApp do número (igual ao WhatsApp Web): o celular onde o número está logado continua sendo o dono da conta, e a estabilidade dos envios depende dele. As dicas abaixo reduzem desconexões e mensagens que não saem.
Bloqueio de tela e bateria
A economia de bateria do Android fecha o WhatsApp em segundo plano e corta a conexão. No celular do número:
• Coloque o WhatsApp como "sem restrições" na otimização/economia de bateria.
• Evite que a tela durma/bloqueie muito rápido, ou mantenha o aparelho carregando.
• Não use modo de economia agressivo que encerra apps inativos.
Manter o WhatsApp ativo no Android
Em vários fabricantes (Xiaomi, Samsung, Motorola e outros) é preciso liberar o app explicitamente:
• Permita execução em segundo plano e início automático (autostart) do WhatsApp.
• Fixe o WhatsApp na tela de apps recentes para o sistema não encerrá-lo.
• Desligue "remover permissões de apps não usados" para o WhatsApp.
• Mantenha o WhatsApp atualizado pela loja.
Estabilidade da conexão
• Mantenha o celular com internet estável (Wi-Fi bom ou 4G/5G com sinal).
• Use um número por aparelho; não fique logando o mesmo número em vários WhatsApp Web ao mesmo tempo.
• Respeite um intervalo entre os envios — o RexZap já aplica um delay anti-bloqueio por conta.
• Depois de reiniciar o celular, abra o WhatsApp para a sessão voltar.
Emuladores
Não recomendamos rodar o número em emuladores de Android no PC: são instáveis para a sessão do WhatsApp, fecham em segundo plano e aumentam o risco de bloqueio. Prefira um aparelho físico dedicado ao número — de preferência usado só para isso — ligado, carregando e com internet.
Número bloqueado pelo WhatsApp
O WhatsApp pode bloquear ou banir um número que dispara muito para desconhecidos, recebe denúncias de spam, ou é um chip muito novo usado em volume logo de cara. É uma decisão do WhatsApp sobre o número — não é falha da API.
Se for bloqueado, peça revisão dentro do próprio app do WhatsApp (a tela de bloqueio oferece a opção "Solicitar revisão").
Fila de mensagens
Toda mensagem enviada entra em uma fila antes de sair, respeitando o intervalo anti-bloqueio. Você acompanha e gerencia a fila pela API (listar, limpar, remover) e, no atendimento, pela tela Fila de envio — ver pendentes e falhadas, reenviar uma ou todas, e limpar. Falhas de origem automática (sistema/integração) re-tentam sozinhas por algumas horas; as do atendimento falham rápido para o operador reenviar.
