Pular para o conteúdo
PluguiZap

Documentação da API

A PluguiZap conecta um número de WhatsApp ao seu sistema. As rotas seguem o padrão de mercado /instances/{ID}/token/{TOKEN}/…, usado pelas APIs de WhatsApp mais conhecidas no Brasil. Se o seu sistema já usa esse padrão, basta trocar a URL base.

Início rápido

  1. Crie uma conta e uma instância no painel.
  2. Leia o QR Code com o celular da empresa.
  3. Copie o ID, o Token e o Client-Token na tela da instância.
  4. Envie a primeira mensagem:
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Olá! Esta é a primeira mensagem pela API."
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Olá! Esta é a primeira mensagem pela API.'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Olá! Esta é a primeira mensagem pela API."
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Olá! Esta é a primeira mensagem pela API.",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Olá! Esta é a primeira mensagem pela API."
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Olá! Esta é a primeira mensagem pela API.""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Olá! Esta é a primeira mensagem pela API."' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Olá! Esta é a primeira mensagem pela API."
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

Autenticação

Toda chamada usa a URL base da instância, com o ID e o Token no caminho, e o header Client-Token:

https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/{rota}

Client-Token: SEU_CLIENT_TOKEN
Content-Type: application/json

O ID e o Token valem só para aquela instância. Guarde-os no servidor do seu sistema, nunca no navegador ou num aplicativo instalado no celular. Se o token vazar, gere outro no painel: o antigo para de funcionar na hora.

Telefones e respostas

  • Telefone: só dígitos, com DDI e DDD: 5579999998888. Números brasileiros sem o 55 também são aceitos, e o 9º dígito do celular é ajustado sozinho.
  • Grupo: o ID do grupo tem o formato 120363019502650977-group e vai no mesmo campo phone.
  • Número oculto (@lid): às vezes o WhatsApp esconde o número de quem escreveu, e o webhook traz phone como 123456789012345@lid. Para responder, use esse mesmo valor.
  • Envios respondem zaapId, messageId e id. O messageId é o que aparece depois nos webhooks de status.
  • Ritmo: os envios de uma instância saem em fila, com um intervalo de 1,5 a 4 segundos entre eles, para proteger o número.

Erros

Erros respondem um código HTTP e um JSON no formato {"error": "mensagem"}.

CódigoQuando acontece
400Falta um campo obrigatório ou o valor é inválido.
401ID, Token ou Client-Token errado. Sem o Client-Token, a mensagem é null not allowed.
402Instância bloqueada por assinatura pendente. Pague a fatura no painel e o envio volta na hora.
404O número não tem WhatsApp, ou a rota não existe.
409A instância não está conectada. Leia o QR Code no painel.
500 / 503Falha temporária. Tente de novo em alguns segundos.

Migrar de outra API

Troque a URL base do seu provedor atual por https://api.pluguizap.com.br e use o ID, o Token e o Client-Token do painel. Os corpos e as respostas são iguais.

RecursoSituação
Status, QR Code, código pelo número, reiniciar, desconectarIgual
Texto, imagem, documento, áudio, vídeo, link, localização, contato, reação, apagar, marcar como lidaIgual
Enquete e votosIgual
Botões e listasMesma rota e mesmo webhook; o cliente recebe um menu numerado (veja abaixo)
Grupos: criar, participantes, admins, nome, descrição, foto, convite, sair, listarIgual
Webhooks de recebidas, entrega, status, conectou, desconectou e enviadas por mimIgual
Chats, contatos, etiquetas, status do WhatsApp, catálogo, comunidades, chamadasAinda não disponível

Instância

GET /status

Situação da conexão

curl -X GET "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status" \
  -H "Client-Token: SEU_CLIENT_TOKEN"
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status', {
  method: 'GET',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
}).then(r => r.json());
import requests

resposta = requests.get(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .GET()
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var resposta = await http.GetAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status");
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  try
    Resposta := Http.Get(URL);
    ShowMessage(Resposta);
  finally
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	pedido, _ := http.NewRequest("GET", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/status", nil)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}
{
  "connected": true,
  "error": "You are already connected.",
  "smartphoneConnected": true
}

GET /qr-code/image

QR Code para conectar

Devolve a imagem pronta para um <img src="...">. O QR muda a cada 20 segundos: consulte de novo a cada 15 segundos até connected ser true. /qr-code responde o mesmo.

{ "connected": false, "value": "data:image/png;base64,iVBORw0KGgo..." }

GET /phone-code/{telefone}

Conectar sem QR Code

Gera um código de 8 caracteres. No celular: Aparelhos conectados, Conectar um aparelho, Conectar com número de telefone.

{ "value": "ABCD1234" }

GET /restart

Reiniciar a conexão

Reconecta sem perder a sessão. GET /disconnect desconecta o número; para voltar, é preciso ler o QR de novo. GET /me traz o ID, o nome e o número conectado. Todas respondem {"value": true}, menos /me.

GET /phone-exists/{telefone}

Confere se o número tem WhatsApp

{ "exists": true, "phone": "5579999998888", "lid": null }

GET /profile-picture?phone={telefone}

Foto do perfil de um contato ou grupo

{ "link": "https://pps.whatsapp.net/v/t61.24694-24/..." }

Vem null quando o contato não tem foto ou esconde a foto na privacidade. O link é do próprio WhatsApp e expira em alguns dias: se for mostrar a foto no seu sistema por muito tempo, baixe e guarde a imagem. Para pedir a foto de novo, ignorando a guardada, acrescente &atualizar=1.

Mensagens

POST /send-text

Enviar texto

CampoTipoObrigatórioDescrição
phonestringSimTelefone ou ID do grupo
messagestringSimTexto. Aceita a formatação do WhatsApp: *negrito*, _itálico_
delayTypingnúmeroNãoSegundos mostrando "digitando…" antes de enviar (1 a 15)
delayMessagenúmeroNãoSegundos de pausa antes da próxima mensagem da fila (1 a 15)
messageIdstringNãoID de uma mensagem para responder citando ela
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",
  "delayTyping": 2
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Olá, *Maria*! Seu pedido #1042 saiu para entrega.',
    'delayTyping' => 2
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",
    "delayTyping": 2
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",
        "delayTyping": 2,
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",
          "delayTyping": 2
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Olá, *Maria*! Seu pedido #1042 saiu para entrega."",
  ""delayTyping"": 2
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",' +
    '  "delayTyping": 2' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Olá, *Maria*! Seu pedido #1042 saiu para entrega.",
	  "delayTyping": 2
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-text", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}
{
  "zaapId": "3999984263738042930CD6ECDE9VDWSA",
  "messageId": "3EB0C4F17A9B2D51E8F0",
  "id": "3EB0C4F17A9B2D51E8F0"
}

POST /send-image

Enviar imagem

CampoTipoObrigatórioDescrição
phonestringSimTelefone ou ID do grupo
imagestringSimLink da imagem ou base64 começando com data:image/png;base64,
captionstringNãoLegenda
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "image": "https://seusite.com.br/cardapio.jpg",
  "caption": "Cardápio de hoje"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'image' => 'https://seusite.com.br/cardapio.jpg',
    'caption' => 'Cardápio de hoje'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "image": "https://seusite.com.br/cardapio.jpg",
    "caption": "Cardápio de hoje"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "image": "https://seusite.com.br/cardapio.jpg",
        "caption": "Cardápio de hoje",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "image": "https://seusite.com.br/cardapio.jpg",
          "caption": "Cardápio de hoje"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""image"": ""https://seusite.com.br/cardapio.jpg"",
  ""caption"": ""Cardápio de hoje""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "image": "https://seusite.com.br/cardapio.jpg",' +
    '  "caption": "Cardápio de hoje"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "image": "https://seusite.com.br/cardapio.jpg",
	  "caption": "Cardápio de hoje"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-image", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-document/{extensao}

Enviar documento (PDF, planilha, XML…)

CampoTipoObrigatórioDescrição
phonestringSimTelefone ou ID do grupo
documentstringSimLink do arquivo ou base64 (data:application/pdf;base64,...)
fileNamestringNãoNome que o cliente vê
captionstringNãoTexto junto com o arquivo
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "document": "https://seusite.com.br/boletos/1042.pdf",
  "fileName": "boleto-outubro.pdf",
  "caption": "Segue o boleto de outubro"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'document' => 'https://seusite.com.br/boletos/1042.pdf',
    'fileName' => 'boleto-outubro.pdf',
    'caption' => 'Segue o boleto de outubro'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "document": "https://seusite.com.br/boletos/1042.pdf",
    "fileName": "boleto-outubro.pdf",
    "caption": "Segue o boleto de outubro"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "document": "https://seusite.com.br/boletos/1042.pdf",
        "fileName": "boleto-outubro.pdf",
        "caption": "Segue o boleto de outubro",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "document": "https://seusite.com.br/boletos/1042.pdf",
          "fileName": "boleto-outubro.pdf",
          "caption": "Segue o boleto de outubro"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""document"": ""https://seusite.com.br/boletos/1042.pdf"",
  ""fileName"": ""boleto-outubro.pdf"",
  ""caption"": ""Segue o boleto de outubro""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "document": "https://seusite.com.br/boletos/1042.pdf",' +
    '  "fileName": "boleto-outubro.pdf",' +
    '  "caption": "Segue o boleto de outubro"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "document": "https://seusite.com.br/boletos/1042.pdf",
	  "fileName": "boleto-outubro.pdf",
	  "caption": "Segue o boleto de outubro"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-document/pdf", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-audio

Enviar áudio

Campo audio com link ou base64. Por padrão chega como áudio gravado; mande "waveform": false para chegar como arquivo de música. Vídeo: POST /send-video com phone, video e caption.

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "audio": "https://seusite.com.br/boas-vindas.ogg"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'audio' => 'https://seusite.com.br/boas-vindas.ogg'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "audio": "https://seusite.com.br/boas-vindas.ogg"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "audio": "https://seusite.com.br/boas-vindas.ogg",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "audio": "https://seusite.com.br/boas-vindas.ogg"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""audio"": ""https://seusite.com.br/boas-vindas.ogg""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "audio": "https://seusite.com.br/boas-vindas.ogg"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "audio": "https://seusite.com.br/boas-vindas.ogg"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-audio", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

Enviar link com prévia

CampoTipoObrigatórioDescrição
phonestringSimTelefone ou ID do grupo
messagestringSimTexto; o link é acrescentado no fim se não estiver nele
linkUrlstringSimEndereço do link
titlestringSimTítulo da prévia
linkDescriptionstringNãoDescrição da prévia
imagestringNãoImagem da prévia (link, de preferência JPG)
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Faça seu pedido pelo cardápio online",
  "linkUrl": "https://seusite.com.br/cardapio",
  "title": "Cardápio",
  "linkDescription": "Peça sem pegar fila"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Faça seu pedido pelo cardápio online',
    'linkUrl' => 'https://seusite.com.br/cardapio',
    'title' => 'Cardápio',
    'linkDescription' => 'Peça sem pegar fila'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Faça seu pedido pelo cardápio online",
    "linkUrl": "https://seusite.com.br/cardapio",
    "title": "Cardápio",
    "linkDescription": "Peça sem pegar fila"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Faça seu pedido pelo cardápio online",
        "linkUrl": "https://seusite.com.br/cardapio",
        "title": "Cardápio",
        "linkDescription": "Peça sem pegar fila",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Faça seu pedido pelo cardápio online",
          "linkUrl": "https://seusite.com.br/cardapio",
          "title": "Cardápio",
          "linkDescription": "Peça sem pegar fila"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Faça seu pedido pelo cardápio online"",
  ""linkUrl"": ""https://seusite.com.br/cardapio"",
  ""title"": ""Cardápio"",
  ""linkDescription"": ""Peça sem pegar fila""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Faça seu pedido pelo cardápio online",' +
    '  "linkUrl": "https://seusite.com.br/cardapio",' +
    '  "title": "Cardápio",' +
    '  "linkDescription": "Peça sem pegar fila"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Faça seu pedido pelo cardápio online",
	  "linkUrl": "https://seusite.com.br/cardapio",
	  "title": "Cardápio",
	  "linkDescription": "Peça sem pegar fila"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-link", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-location

Enviar localização

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "title": "Nossa loja",
  "address": "Av. Beira Mar, 100 — Aracaju/SE",
  "latitude": "-10.9472",
  "longitude": "-37.0731"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'title' => 'Nossa loja',
    'address' => 'Av. Beira Mar, 100 — Aracaju/SE',
    'latitude' => '-10.9472',
    'longitude' => '-37.0731'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "title": "Nossa loja",
    "address": "Av. Beira Mar, 100 — Aracaju/SE",
    "latitude": "-10.9472",
    "longitude": "-37.0731"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "title": "Nossa loja",
        "address": "Av. Beira Mar, 100 — Aracaju/SE",
        "latitude": "-10.9472",
        "longitude": "-37.0731",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "title": "Nossa loja",
          "address": "Av. Beira Mar, 100 — Aracaju/SE",
          "latitude": "-10.9472",
          "longitude": "-37.0731"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""title"": ""Nossa loja"",
  ""address"": ""Av. Beira Mar, 100 — Aracaju/SE"",
  ""latitude"": ""-10.9472"",
  ""longitude"": ""-37.0731""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "title": "Nossa loja",' +
    '  "address": "Av. Beira Mar, 100 — Aracaju/SE",' +
    '  "latitude": "-10.9472",' +
    '  "longitude": "-37.0731"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "title": "Nossa loja",
	  "address": "Av. Beira Mar, 100 — Aracaju/SE",
	  "latitude": "-10.9472",
	  "longitude": "-37.0731"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-location", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-contact

Enviar contato

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "contactName": "Financeiro",
  "contactPhone": "5579988887777"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'contactName' => 'Financeiro',
    'contactPhone' => '5579988887777'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "contactName": "Financeiro",
    "contactPhone": "5579988887777"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "contactName": "Financeiro",
        "contactPhone": "5579988887777",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "contactName": "Financeiro",
          "contactPhone": "5579988887777"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""contactName"": ""Financeiro"",
  ""contactPhone"": ""5579988887777""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "contactName": "Financeiro",' +
    '  "contactPhone": "5579988887777"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "contactName": "Financeiro",
	  "contactPhone": "5579988887777"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-contact", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-reaction

Reagir a uma mensagem

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "reaction": "👍",
  "messageId": "3EB0C4F17A9B2D51E8F0"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'reaction' => '👍',
    'messageId' => '3EB0C4F17A9B2D51E8F0'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "reaction": "👍",
    "messageId": "3EB0C4F17A9B2D51E8F0"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "reaction": "👍",
        "messageId": "3EB0C4F17A9B2D51E8F0",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "reaction": "👍",
          "messageId": "3EB0C4F17A9B2D51E8F0"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""reaction"": ""👍"",
  ""messageId"": ""3EB0C4F17A9B2D51E8F0""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "reaction": "👍",' +
    '  "messageId": "3EB0C4F17A9B2D51E8F0"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "reaction": "👍",
	  "messageId": "3EB0C4F17A9B2D51E8F0"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-reaction", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /read-message

Marcar como lida (tiques azuis)

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "messageId": "3EB0C4F17A9B2D51E8F0"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'messageId' => '3EB0C4F17A9B2D51E8F0'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "messageId": "3EB0C4F17A9B2D51E8F0"
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "messageId": "3EB0C4F17A9B2D51E8F0",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "messageId": "3EB0C4F17A9B2D51E8F0"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""messageId"": ""3EB0C4F17A9B2D51E8F0""
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "messageId": "3EB0C4F17A9B2D51E8F0"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "messageId": "3EB0C4F17A9B2D51E8F0"
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/read-message", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

DELETE /messages?messageId=&phone=&owner=true

Apagar uma mensagem

owner=true para mensagens enviadas por você. Por padrão apaga para todos; deleteForMe=true apaga só no seu aparelho. Responde {"value": true}.

Interativas

POST /send-poll

Enviar enquete

CampoTipoObrigatórioDescrição
phonestringSimTelefone ou ID do grupo
messagestringSimPergunta
polllistaSimDe 2 a 12 opções: [{"name": "Açaí"}, {"name": "Cupuaçu"}]
pollMaxOptionsnúmeroNão1 = cada pessoa escolhe uma; vazio = várias
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Qual sabor você quer na promoção?",
  "poll": [
    {
      "name": "Açaí"
    },
    {
      "name": "Cupuaçu"
    }
  ],
  "pollMaxOptions": 1
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Qual sabor você quer na promoção?',
    'poll' => [
      [
        'name' => 'Açaí'
      ],
      [
        'name' => 'Cupuaçu'
      ]
    ],
    'pollMaxOptions' => 1
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Qual sabor você quer na promoção?",
    "poll": [
      {
        "name": "Açaí"
      },
      {
        "name": "Cupuaçu"
      }
    ],
    "pollMaxOptions": 1
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Qual sabor você quer na promoção?",
        "poll": [
            {
                "name": "Açaí",
            },
            {
                "name": "Cupuaçu",
            },
        ],
        "pollMaxOptions": 1,
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Qual sabor você quer na promoção?",
          "poll": [
            {
              "name": "Açaí"
            },
            {
              "name": "Cupuaçu"
            }
          ],
          "pollMaxOptions": 1
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Qual sabor você quer na promoção?"",
  ""poll"": [
    {
      ""name"": ""Açaí""
    },
    {
      ""name"": ""Cupuaçu""
    }
  ],
  ""pollMaxOptions"": 1
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Qual sabor você quer na promoção?",' +
    '  "poll": [' +
    '    {' +
    '      "name": "Açaí"' +
    '    },' +
    '    {' +
    '      "name": "Cupuaçu"' +
    '    }' +
    '  ],' +
    '  "pollMaxOptions": 1' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Qual sabor você quer na promoção?",
	  "poll": [
	    {
	      "name": "Açaí"
	    },
	    {
	      "name": "Cupuaçu"
	    }
	  ],
	  "pollMaxOptions": 1
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-poll", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

Cada voto chega no webhook de mensagens recebidas com o campo pollVote.

POST /send-button-list

Enviar botões

O WhatsApp bloqueia botões e listas nativos em conexões que não são a API oficial. Estas rotas aceitam o corpo no formato padrão de botões e listas e enviam um menu numerado (1️⃣ Sim, 2️⃣ Não). Quando o cliente responde o número ou o texto da opção em até 24 horas, o webhook traz buttonsResponseMessage ou listResponseMessage, no formato padrão.
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Confirma o pedido #1042?",
  "buttonList": {
    "buttons": [
      {
        "id": "sim",
        "label": "Sim, confirmar"
      },
      {
        "id": "nao",
        "label": "Não, cancelar"
      }
    ]
  }
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Confirma o pedido #1042?',
    'buttonList' => [
      'buttons' => [
        [
          'id' => 'sim',
          'label' => 'Sim, confirmar'
        ],
        [
          'id' => 'nao',
          'label' => 'Não, cancelar'
        ]
      ]
    ]
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Confirma o pedido #1042?",
    "buttonList": {
      "buttons": [
        {
          "id": "sim",
          "label": "Sim, confirmar"
        },
        {
          "id": "nao",
          "label": "Não, cancelar"
        }
      ]
    }
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Confirma o pedido #1042?",
        "buttonList": {
            "buttons": [
                {
                    "id": "sim",
                    "label": "Sim, confirmar",
                },
                {
                    "id": "nao",
                    "label": "Não, cancelar",
                },
            ],
        },
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Confirma o pedido #1042?",
          "buttonList": {
            "buttons": [
              {
                "id": "sim",
                "label": "Sim, confirmar"
              },
              {
                "id": "nao",
                "label": "Não, cancelar"
              }
            ]
          }
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Confirma o pedido #1042?"",
  ""buttonList"": {
    ""buttons"": [
      {
        ""id"": ""sim"",
        ""label"": ""Sim, confirmar""
      },
      {
        ""id"": ""nao"",
        ""label"": ""Não, cancelar""
      }
    ]
  }
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Confirma o pedido #1042?",' +
    '  "buttonList": {' +
    '    "buttons": [' +
    '      {' +
    '        "id": "sim",' +
    '        "label": "Sim, confirmar"' +
    '      },' +
    '      {' +
    '        "id": "nao",' +
    '        "label": "Não, cancelar"' +
    '      }' +
    '    ]' +
    '  }' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Confirma o pedido #1042?",
	  "buttonList": {
	    "buttons": [
	      {
	        "id": "sim",
	        "label": "Sim, confirmar"
	      },
	      {
	        "id": "nao",
	        "label": "Não, cancelar"
	      }
	    ]
	  }
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-list", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

O cliente recebe:

Confirma o pedido #1042?

1️⃣ Sim, confirmar
2️⃣ Não, cancelar

Responda com o número da opção.

POST /send-option-list

Enviar lista de opções

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "O que você quer fazer?",
  "optionList": {
    "title": "Atendimento",
    "buttonLabel": "Ver opções",
    "options": [
      {
        "id": "pedido",
        "title": "Fazer pedido",
        "description": "Cardápio e entrega"
      },
      {
        "id": "boleto",
        "title": "Segunda via do boleto"
      }
    ]
  }
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'O que você quer fazer?',
    'optionList' => [
      'title' => 'Atendimento',
      'buttonLabel' => 'Ver opções',
      'options' => [
        [
          'id' => 'pedido',
          'title' => 'Fazer pedido',
          'description' => 'Cardápio e entrega'
        ],
        [
          'id' => 'boleto',
          'title' => 'Segunda via do boleto'
        ]
      ]
    ]
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "O que você quer fazer?",
    "optionList": {
      "title": "Atendimento",
      "buttonLabel": "Ver opções",
      "options": [
        {
          "id": "pedido",
          "title": "Fazer pedido",
          "description": "Cardápio e entrega"
        },
        {
          "id": "boleto",
          "title": "Segunda via do boleto"
        }
      ]
    }
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "O que você quer fazer?",
        "optionList": {
            "title": "Atendimento",
            "buttonLabel": "Ver opções",
            "options": [
                {
                    "id": "pedido",
                    "title": "Fazer pedido",
                    "description": "Cardápio e entrega",
                },
                {
                    "id": "boleto",
                    "title": "Segunda via do boleto",
                },
            ],
        },
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "O que você quer fazer?",
          "optionList": {
            "title": "Atendimento",
            "buttonLabel": "Ver opções",
            "options": [
              {
                "id": "pedido",
                "title": "Fazer pedido",
                "description": "Cardápio e entrega"
              },
              {
                "id": "boleto",
                "title": "Segunda via do boleto"
              }
            ]
          }
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""O que você quer fazer?"",
  ""optionList"": {
    ""title"": ""Atendimento"",
    ""buttonLabel"": ""Ver opções"",
    ""options"": [
      {
        ""id"": ""pedido"",
        ""title"": ""Fazer pedido"",
        ""description"": ""Cardápio e entrega""
      },
      {
        ""id"": ""boleto"",
        ""title"": ""Segunda via do boleto""
      }
    ]
  }
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "O que você quer fazer?",' +
    '  "optionList": {' +
    '    "title": "Atendimento",' +
    '    "buttonLabel": "Ver opções",' +
    '    "options": [' +
    '      {' +
    '        "id": "pedido",' +
    '        "title": "Fazer pedido",' +
    '        "description": "Cardápio e entrega"' +
    '      },' +
    '      {' +
    '        "id": "boleto",' +
    '        "title": "Segunda via do boleto"' +
    '      }' +
    '    ]' +
    '  }' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "O que você quer fazer?",
	  "optionList": {
	    "title": "Atendimento",
	    "buttonLabel": "Ver opções",
	    "options": [
	      {
	        "id": "pedido",
	        "title": "Fazer pedido",
	        "description": "Cardápio e entrega"
	      },
	      {
	        "id": "boleto",
	        "title": "Segunda via do boleto"
	      }
	    ]
	  }
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-option-list", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /send-button-actions

Enviar botões de ação

Botões REPLY viram opções numeradas; URL e CALL viram linhas com o link ou o telefone.

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "5579999998888",
  "message": "Como prefere falar com a gente?",
  "buttonActions": [
    {
      "type": "REPLY",
      "id": "atendente",
      "label": "Falar com atendente"
    },
    {
      "type": "URL",
      "label": "Ver o site",
      "url": "https://seusite.com.br"
    },
    {
      "type": "CALL",
      "label": "Ligar",
      "phone": "557930001000"
    }
  ]
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'phone' => '5579999998888',
    'message' => 'Como prefere falar com a gente?',
    'buttonActions' => [
      [
        'type' => 'REPLY',
        'id' => 'atendente',
        'label' => 'Falar com atendente'
      ],
      [
        'type' => 'URL',
        'label' => 'Ver o site',
        'url' => 'https://seusite.com.br'
      ],
      [
        'type' => 'CALL',
        'label' => 'Ligar',
        'phone' => '557930001000'
      ]
    ]
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "phone": "5579999998888",
    "message": "Como prefere falar com a gente?",
    "buttonActions": [
      {
        "type": "REPLY",
        "id": "atendente",
        "label": "Falar com atendente"
      },
      {
        "type": "URL",
        "label": "Ver o site",
        "url": "https://seusite.com.br"
      },
      {
        "type": "CALL",
        "label": "Ligar",
        "phone": "557930001000"
      }
    ]
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "phone": "5579999998888",
        "message": "Como prefere falar com a gente?",
        "buttonActions": [
            {
                "type": "REPLY",
                "id": "atendente",
                "label": "Falar com atendente",
            },
            {
                "type": "URL",
                "label": "Ver o site",
                "url": "https://seusite.com.br",
            },
            {
                "type": "CALL",
                "label": "Ligar",
                "phone": "557930001000",
            },
        ],
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "phone": "5579999998888",
          "message": "Como prefere falar com a gente?",
          "buttonActions": [
            {
              "type": "REPLY",
              "id": "atendente",
              "label": "Falar com atendente"
            },
            {
              "type": "URL",
              "label": "Ver o site",
              "url": "https://seusite.com.br"
            },
            {
              "type": "CALL",
              "label": "Ligar",
              "phone": "557930001000"
            }
          ]
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""phone"": ""5579999998888"",
  ""message"": ""Como prefere falar com a gente?"",
  ""buttonActions"": [
    {
      ""type"": ""REPLY"",
      ""id"": ""atendente"",
      ""label"": ""Falar com atendente""
    },
    {
      ""type"": ""URL"",
      ""label"": ""Ver o site"",
      ""url"": ""https://seusite.com.br""
    },
    {
      ""type"": ""CALL"",
      ""label"": ""Ligar"",
      ""phone"": ""557930001000""
    }
  ]
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "phone": "5579999998888",' +
    '  "message": "Como prefere falar com a gente?",' +
    '  "buttonActions": [' +
    '    {' +
    '      "type": "REPLY",' +
    '      "id": "atendente",' +
    '      "label": "Falar com atendente"' +
    '    },' +
    '    {' +
    '      "type": "URL",' +
    '      "label": "Ver o site",' +
    '      "url": "https://seusite.com.br"' +
    '    },' +
    '    {' +
    '      "type": "CALL",' +
    '      "label": "Ligar",' +
    '      "phone": "557930001000"' +
    '    }' +
    '  ]' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "phone": "5579999998888",
	  "message": "Como prefere falar com a gente?",
	  "buttonActions": [
	    {
	      "type": "REPLY",
	      "id": "atendente",
	      "label": "Falar com atendente"
	    },
	    {
	      "type": "URL",
	      "label": "Ver o site",
	      "url": "https://seusite.com.br"
	    },
	    {
	      "type": "CALL",
	      "label": "Ligar",
	      "phone": "557930001000"
	    }
	  ]
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/send-button-actions", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

Grupos

POST /create-group

Criar grupo

CampoTipoObrigatórioDescrição
groupNamestringSimNome do grupo
phoneslistaSimTelefones dos participantes
autoInvitebooleanoSimManda o link de convite para quem não puder ser adicionado direto
curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupName": "Equipe de entregas",
  "phones": [
    "5579999998888",
    "5579988887777"
  ],
  "autoInvite": true
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'groupName' => 'Equipe de entregas',
    'phones' => [
      '5579999998888',
      '5579988887777'
    ],
    'autoInvite' => true
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "groupName": "Equipe de entregas",
    "phones": [
      "5579999998888",
      "5579988887777"
    ],
    "autoInvite": true
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "groupName": "Equipe de entregas",
        "phones": [
            "5579999998888",
            "5579988887777",
        ],
        "autoInvite": True,
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "groupName": "Equipe de entregas",
          "phones": [
            "5579999998888",
            "5579988887777"
          ],
          "autoInvite": true
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""groupName"": ""Equipe de entregas"",
  ""phones"": [
    ""5579999998888"",
    ""5579988887777""
  ],
  ""autoInvite"": true
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "groupName": "Equipe de entregas",' +
    '  "phones": [' +
    '    "5579999998888",' +
    '    "5579988887777"' +
    '  ],' +
    '  "autoInvite": true' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "groupName": "Equipe de entregas",
	  "phones": [
	    "5579999998888",
	    "5579988887777"
	  ],
	  "autoInvite": true
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/create-group", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}
{
  "phone": "120363019502650977-group",
  "phonesNotAdded": [],
  "invitationLink": "https://chat.whatsapp.com/GONwbGGDkLe8BifUWwLgct"
}

POST /add-participant

Participantes e administradores

Mesmo corpo para /add-participant, /remove-participant, /add-admin e /remove-admin. Respondem {"value": true}.

curl -X POST "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupId": "120363019502650977-group",
  "phones": [
    "5579977776666"
  ],
  "autoInvite": true
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'groupId' => '120363019502650977-group',
    'phones' => [
      '5579977776666'
    ],
    'autoInvite' => true
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant', {
  method: 'POST',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "groupId": "120363019502650977-group",
    "phones": [
      "5579977776666"
    ],
    "autoInvite": true
  }),
}).then(r => r.json());
import requests

resposta = requests.post(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "groupId": "120363019502650977-group",
        "phones": [
            "5579977776666",
        ],
        "autoInvite": True,
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
        {
          "groupId": "120363019502650977-group",
          "phones": [
            "5579977776666"
          ],
          "autoInvite": true
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""groupId"": ""120363019502650977-group"",
  ""phones"": [
    ""5579977776666""
  ],
  ""autoInvite"": true
}", Encoding.UTF8, "application/json");
var resposta = await http.PostAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "groupId": "120363019502650977-group",' +
    '  "phones": [' +
    '    "5579977776666"' +
    '  ],' +
    '  "autoInvite": true' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Post(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "groupId": "120363019502650977-group",
	  "phones": [
	    "5579977776666"
	  ],
	  "autoInvite": true
	}`)
	pedido, _ := http.NewRequest("POST", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/add-participant", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

POST /update-group-name

Nome, descrição e foto

RotaCorpo
POST /update-group-name{"groupId": "...-group", "groupName": "Novo nome"}
POST /update-group-description{"groupId": "...-group", "groupDescription": "Regras do grupo"}
POST /update-group-photo{"groupId": "...-group", "groupPhoto": "https://.../logo.jpg"}

GET /group-metadata/{groupId}

Dados do grupo

{
  "phone": "120363019502650977-group",
  "subject": "Equipe de entregas",
  "description": "Avisos da equipe",
  "owner": "5579999998888",
  "creation": 1761850000000,
  "invitationLink": "https://chat.whatsapp.com/...",
  "participants": [
    { "phone": "5579999998888", "isAdmin": true, "isSuperAdmin": true },
    { "phone": "5579988887777", "isAdmin": false, "isSuperAdmin": false }
  ]
}

GET /group-invitation-link/{groupId} devolve {"phone", "invitationLink"} (é preciso ser admin).

GET /groups?page=1&pageSize=50

Listar grupos e sair

Lista os grupos em que o número participa. Para sair: POST /leave-group com {"groupId": "...-group"}.

Webhooks

O webhook é o endereço do seu sistema que recebe os eventos. Configure pelo painel ou pela API. A URL precisa ser HTTPS e responder 200 em até 15 segundos; se falhar, tentamos mais duas vezes.

Rota (PUT)Evento
/update-every-webhooksTodos os eventos na mesma URL
/update-webhook-receivedMensagens recebidas, votos e respostas de menu
/update-webhook-received-deliveryRecebidas e também as enviadas pelo celular
/update-webhook-deliveryMensagem enviada pela API
/update-webhook-message-statusEntregue, lida, ouvida
/update-webhook-connectedO número conectou
/update-webhook-disconnectedO número desconectou
/update-notify-sent-by-me{"notifySentByMe": true} liga o aviso das mensagens que o atendente manda pelo celular
curl -X PUT "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks" \
  -H "Client-Token: SEU_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "value": "https://seusistema.com.br/webhook-whatsapp"
}'
$ch = curl_init('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST  => 'PUT',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER     => ['Client-Token: SEU_CLIENT_TOKEN', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS     => json_encode([
    'value' => 'https://seusistema.com.br/webhook-whatsapp'
  ]),
]);
$resposta = json_decode(curl_exec($ch), true);
const resposta = await fetch('https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks', {
  method: 'PUT',
  headers: { 'Client-Token': 'SEU_CLIENT_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "value": "https://seusistema.com.br/webhook-whatsapp"
  }),
}).then(r => r.json());
import requests

resposta = requests.put(
    "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks",
    headers={"Client-Token": "SEU_CLIENT_TOKEN"},
    json={
        "value": "https://seusistema.com.br/webhook-whatsapp",
    },
    timeout=60,
)
print(resposta.status_code, resposta.json())
// Java 15 ou mais novo (java.net.http, sem bibliotecas)
import java.net.URI;
import java.net.http.*;

HttpClient http = HttpClient.newHttpClient();
HttpRequest pedido = HttpRequest.newBuilder(URI.create("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks"))
    .header("Client-Token", "SEU_CLIENT_TOKEN")
    .header("Content-Type", "application/json")
    .method("PUT", HttpRequest.BodyPublishers.ofString("""
        {
          "value": "https://seusistema.com.br/webhook-whatsapp"
        }
        """))
    .build();
HttpResponse<String> resposta = http.send(pedido, HttpResponse.BodyHandlers.ofString());
System.out.println(resposta.statusCode() + " " + resposta.body());
// .NET 6 ou mais novo
using System.Net.Http;
using System.Text;

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Client-Token", "SEU_CLIENT_TOKEN");
var corpo = new StringContent(@"{
  ""value"": ""https://seusistema.com.br/webhook-whatsapp""
}", Encoding.UTF8, "application/json");
var resposta = await http.PutAsync("https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks", corpo);
Console.WriteLine($"{(int)resposta.StatusCode} {await resposta.Content.ReadAsStringAsync()}");
// Delphi XE7+ com Indy (precisa de libeay32.dll e ssleay32.dll junto do .exe)
// Mais simples: use a unit pronta ZapApi.pas (veja Bibliotecas prontas)
uses System.SysUtils, System.Classes, IdHTTP, IdSSLOpenSSL;

const
  URL = 'https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks';
var
  Http: TIdHTTP;
  Ssl: TIdSSLIOHandlerSocketOpenSSL;
  Corpo: TStringStream;
  Resposta: string;
begin
  Http := TIdHTTP.Create(nil);
  Ssl := TIdSSLIOHandlerSocketOpenSSL.Create(Http);
  Ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
  Http.IOHandler := Ssl;
  Http.Request.CustomHeaders.Values['Client-Token'] := 'SEU_CLIENT_TOKEN';
  Http.Request.ContentType := 'application/json';
  Http.Request.CharSet := 'utf-8';
  Corpo := TStringStream.Create(
    '{' +
    '  "value": "https://seusistema.com.br/webhook-whatsapp"' +
    '}', TEncoding.UTF8);
  try
    Resposta := Http.Put(URL, Corpo);
    ShowMessage(Resposta);
  finally
    Corpo.Free;
    Http.Free;
  end;
end;
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	corpo := strings.NewReader(`{
	  "value": "https://seusistema.com.br/webhook-whatsapp"
	}`)
	pedido, _ := http.NewRequest("PUT", "https://api.pluguizap.com.br/instances/{ID}/token/{TOKEN}/update-every-webhooks", corpo)
	pedido.Header.Set("Client-Token", "SEU_CLIENT_TOKEN")
	pedido.Header.Set("Content-Type", "application/json")
	resposta, err := http.DefaultClient.Do(pedido)
	if err != nil {
		panic(err)
	}
	defer resposta.Body.Close()
	texto, _ := io.ReadAll(resposta.Body)
	fmt.Println(resposta.StatusCode, string(texto))
}

Mensagem recebida

{
  "type": "ReceivedCallback",
  "instanceId": "45010D969C0AE26EF17739F5A12C584B",
  "messageId": "3EB0A1B2C3D4E5F6",
  "phone": "5579999998888",
  "fromMe": false,
  "momment": 1761850000000,
  "status": "RECEIVED",
  "chatName": "Maria",
  "senderName": "Maria",
  "photo": "https://pps.whatsapp.net/v/t61.24694-24/...",
  "senderPhoto": "https://pps.whatsapp.net/v/t61.24694-24/...",
  "isGroup": false,
  "participantPhone": null,
  "text": { "message": "Quero fazer um pedido" }
}

photo é a foto do contato (ou do grupo) e senderPhoto a de quem mandou; nos grupos, as duas são diferentes. Vêm null quando não há foto ou a privacidade do contato esconde.

No lugar de text pode vir um destes objetos:

ObjetoCampos
imageimageUrl, mimeType, caption
documentdocumentUrl, fileName, mimeType, caption
audioaudioUrl, mimeType, ptt (gravado na hora), seconds
videovideoUrl, mimeType, caption, seconds
stickerstickerUrl, mimeType
locationlatitude, longitude, address
contactdisplayName, vCard, phones
pollquestion, options, pollMaxOptions
pollVotepollMessageId, options (as escolhidas)
buttonsResponseMessagebuttonId, message
listResponseMessageselectedRowId, title, message
reactionvalue, referencedMessage.messageId

Os links das mídias valem por 48 horas: baixe e guarde o arquivo se precisar dele depois.

Entrega (mensagem enviada pela API)

{
  "type": "DeliveryCallback",
  "instanceId": "45010D969C0AE26EF17739F5A12C584B",
  "phone": "5579999998888",
  "zaapId": "3999984263738042930CD6ECDE9VDWSA",
  "messageId": "3EB0C4F17A9B2D51E8F0",
  "momment": 1761850001000
}

Status da mensagem

{
  "type": "MessageStatusCallback",
  "instanceId": "45010D969C0AE26EF17739F5A12C584B",
  "status": "READ",
  "ids": ["3EB0C4F17A9B2D51E8F0"],
  "phone": "5579999998888",
  "momment": 1761850042000,
  "isGroup": false
}

status: SENT (saiu), RECEIVED (entregue), READ (lida), PLAYED (áudio ouvido).

Conectou e desconectou

{ "type": "ConnectedCallback", "connected": true, "phone": "5579999998888", "instanceId": "...", "momment": 1761850000000 }

{ "type": "DisconnectedCallback", "disconnected": true, "error": "Device has been disconnected", "instanceId": "...", "momment": 1761850000000 }

Receber o webhook no seu sistema

O seu endpoint recebe um POST com o JSON do evento. Confira o cabeçalho X-Webhook-Secret (o segredo da instância, no painel), responda 200 rápido e ignore fromMe: true para o bot não responder a si mesmo. No painel, a aba Webhook de cada instância mostra cada aviso enviado, o que o seu sistema respondeu e permite reenviar.

<?php
// webhook.php
const SEGREDO = 'SEGREDO_DO_WEBHOOK';
if (!hash_equals(SEGREDO, $_SERVER['HTTP_X_WEBHOOK_SECRET'] ?? '')) { http_response_code(401); exit; }

$e = json_decode(file_get_contents('php://input'), true);
http_response_code(200);

if (($e['type'] ?? '') === 'ReceivedCallback' && empty($e['fromMe'])) {
    $telefone = $e['phone'];
    $texto    = $e['text']['message'] ?? '';
    $opcao    = $e['buttonsResponseMessage']['buttonId'] ?? null;
    // grave no banco / responda com a classe ZapApi
}
// Node 18+, sem dependências
import http from 'node:http';
const SEGREDO = 'SEGREDO_DO_WEBHOOK';

http.createServer((req, res) => {
  let corpo = '';
  req.on('data', (c) => (corpo += c));
  req.on('end', () => {
    if (req.headers['x-webhook-secret'] !== SEGREDO) { res.writeHead(401); return res.end(); }
    res.writeHead(200).end();                  // responda antes de processar
    const e = JSON.parse(corpo);
    if (e.type === 'ReceivedCallback' && !e.fromMe) {
      console.log(e.phone, e.text?.message, e.buttonsResponseMessage?.buttonId);
    }
  });
}).listen(8080);
# pip install flask
import hmac
from flask import Flask, request

SEGREDO = "SEGREDO_DO_WEBHOOK"
app = Flask(__name__)

@app.post("/webhook")
def webhook():
    if not hmac.compare_digest(request.headers.get("X-Webhook-Secret", ""), SEGREDO):
        return "", 401
    e = request.get_json(force=True)
    if e.get("type") == "ReceivedCallback" and not e.get("fromMe"):
        telefone = e["phone"]
        texto = (e.get("text") or {}).get("message", "")
        opcao = (e.get("buttonsResponseMessage") or {}).get("buttonId")
        # processe aqui (ou mande para uma fila, se for demorar)
    return "", 200
// Java 11+, sem dependências (servidor HTTP embutido do JDK)
import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

public class Webhook {
    static final String SEGREDO = "SEGREDO_DO_WEBHOOK";
    public static void main(String[] a) throws Exception {
        HttpServer s = HttpServer.create(new InetSocketAddress(8080), 0);
        s.createContext("/webhook", ex -> {
            String corpo = new String(ex.getRequestBody().readAllBytes(), StandardCharsets.UTF_8);
            boolean ok = SEGREDO.equals(ex.getRequestHeaders().getFirst("X-Webhook-Secret"));
            ex.sendResponseHeaders(ok ? 200 : 401, -1);
            ex.close();
            if (ok && corpo.contains("\"ReceivedCallback\"") && !corpo.contains("\"fromMe\":true")) {
                System.out.println(corpo);   // leia com Jackson/Gson e processe
            }
        });
        s.start();
    }
}
// .NET 6+ (minimal API): dotnet new web
using System.Text.Json;

const string Segredo = "SEGREDO_DO_WEBHOOK";
var app = WebApplication.CreateBuilder(args).Build();

app.MapPost("/webhook", async (HttpRequest req) =>
{
    if (req.Headers["X-Webhook-Secret"] != Segredo) return Results.Unauthorized();
    var e = await JsonSerializer.DeserializeAsync<JsonElement>(req.Body);
    if (e.GetProperty("type").GetString() == "ReceivedCallback" && !e.GetProperty("fromMe").GetBoolean())
    {
        var telefone = e.GetProperty("phone").GetString();
        var texto = e.TryGetProperty("text", out var t) ? t.GetProperty("message").GetString() : "";
        // processe aqui
    }
    return Results.Ok();
});
app.Run();
// Sistema desktop não recebe webhook direto (precisa de endereço público).
// O caminho mais simples: use o webhook.php (aba PHP) no seu servidor para gravar
// cada mensagem numa tabela, e o Delphi lê essa tabela num TTimer.
//
// Se o seu sistema já tem servidor REST com Horse (Delphi 10 ou mais novo):
uses Horse, System.JSON;

THorse.Post('/webhook',
  procedure(Req: THorseRequest; Res: THorseResponse)
  var
    E: TJSONObject;
  begin
    if Req.Headers['X-Webhook-Secret'] <> 'SEGREDO_DO_WEBHOOK' then
    begin
      Res.Status(401);
      Exit;
    end;
    E := TJSONObject.ParseJSONValue(Req.Body) as TJSONObject;
    try
      if (E.GetValue<string>('type') = 'ReceivedCallback') and not E.GetValue<Boolean>('fromMe') then
        GravarMensagem(E.GetValue<string>('phone'), E.GetValue<string>('text.message', ''));
    finally
      E.Free;
    end;
    Res.Status(200);
  end);
package main

import (
	"encoding/json"
	"net/http"
)

const segredo = "SEGREDO_DO_WEBHOOK"

func main() {
	http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("X-Webhook-Secret") != segredo {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}
		var e struct {
			Type   string `json:"type"`
			Phone  string `json:"phone"`
			FromMe bool   `json:"fromMe"`
			Text   struct{ Message string `json:"message"` } `json:"text"`
		}
		json.NewDecoder(r.Body).Decode(&e)
		w.WriteHeader(http.StatusOK)
		if e.Type == "ReceivedCallback" && !e.FromMe {
			go processar(e.Phone, e.Text.Message)
		}
	})
	http.ListenAndServe(":8080", nil)
}

Bibliotecas prontas

Um arquivo só, sem dependências, com os mesmos métodos em cada linguagem: status, QR Code, texto, imagem, documento, arquivo do disco, enquete, botões, localização, "tem WhatsApp?" e webhook. Para qualquer outra rota, use o método genérico (req).

Baixar ZapApi.php PHP 7.4+, só a extensão curl.

require 'ZapApi.php';
$zap = new ZapApi('ID', 'TOKEN', 'CLIENT_TOKEN');

$zap->texto('79999998888', 'Seu pedido saiu para entrega!');
$zap->arquivoLocal('79999998888', __DIR__ . '/boletos/1042.pdf', 'Segue o boleto');
$zap->enquete('79999998888', 'Qual sabor?', ['Açaí', 'Cupuaçu']);
$zap->botoes('79999998888', 'Confirma?', ['Sim', 'Não']);
$zap->webhookTodos('https://seusistema.com.br/webhook-whatsapp');

Baixar zapapi.mjs Node 18+, sem dependências.

import { ZapApi } from './zapapi.mjs';
const zap = new ZapApi('ID', 'TOKEN', 'CLIENT_TOKEN');

await zap.texto('79999998888', 'Seu pedido saiu para entrega!');
await zap.arquivo('79999998888', './boletos/1042.pdf', 'Segue o boleto');
await zap.enquete('79999998888', 'Qual sabor?', ['Açaí', 'Cupuaçu']);
console.log(await zap.temWhatsapp('79999998888'));

Baixar zapapi.py Python 3.8+, só a biblioteca padrão.

from zapapi import ZapApi
zap = ZapApi("ID", "TOKEN", "CLIENT_TOKEN")

zap.texto("79999998888", "Seu pedido saiu para entrega!")
zap.arquivo("79999998888", "boletos/1042.pdf", legenda="Segue o boleto")
zap.enquete("79999998888", "Qual sabor?", ["Açaí", "Cupuaçu"])
print(zap.tem_whatsapp("79999998888"))

Baixar ZapApi.java Java 11+, sem dependências.

ZapApi zap = new ZapApi("ID", "TOKEN", "CLIENT_TOKEN");

ZapApi.Resposta r = zap.texto("79999998888", "Seu pedido saiu para entrega!");
if (r.ok()) System.out.println(r.campo("messageId")); else System.out.println(r.erro());

zap.arquivo("79999998888", Path.of("boletos/1042.pdf"), "Segue o boleto");
zap.enquete("79999998888", "Qual sabor?", List.of("Açaí", "Cupuaçu"));

Baixar ZapApi.cs .NET 6+, sem pacotes extras.

var zap = new ZapApi("ID", "TOKEN", "CLIENT_TOKEN");

var r = await zap.TextoAsync("79999998888", "Seu pedido saiu para entrega!");
Console.WriteLine(r.Ok ? r.Campo("messageId") : r.Erro);

await zap.ArquivoAsync("79999998888", @"C:\Boletos\1042.pdf", "Segue o boleto");
await zap.EnqueteAsync("79999998888", "Qual sabor?", "Açaí", "Cupuaçu");

Baixar ZapApi.pas Delphi XE7+ com Indy. Tutorial completo.

uses ZapApi;

var
  Zap: TZapApi;
  R: TZapResposta;
begin
  Zap := TZapApi.Create('ID', 'TOKEN', 'CLIENT_TOKEN');
  try
    R := Zap.EnviarTexto('79999998888', 'Seu pedido saiu para entrega!');
    if not R.Ok then ShowMessage(R.Erro);
    Zap.EnviarArquivo('79999998888', 'C:\Boletos\1042.pdf', 'Segue o boleto');
  finally
    Zap.Free;
  end;
end;

A biblioteca para Go não existe ainda: os exemplos em Go de cada rota usam só a biblioteca padrão e funcionam copiando e colando.

Boas práticas

  • Use um número só para a empresa, com algumas semanas de uso normal antes de automatizar.
  • Mande mensagens para quem é seu cliente ou falou com você. Listas compradas e disparo em massa levam o WhatsApp a bloquear o número, e esse uso é proibido nos termos.
  • Personalize as mensagens com nome, pedido ou valor. Textos idênticos para muita gente parecem spam.
  • Ofereça sempre um jeito de falar com uma pessoa.
  • Responda o webhook com 200 rápido e processe depois, numa fila do seu sistema.
Fale com a gente