Documentação da API
API REST sob https://api.zapinapi.duckdns.org/v1, JSON, autenticada por Authorization: Bearer. Eventos chegam ao seu sistema por webhook assinado com HMAC. Referência gerada do contrato OpenAPI (ZapinApi v1).
Situação do serviço: página de status.
Início rápido
Quer usar o WhatsApp dentro do ChatGPT ou de outra IA? Comece por Conectar sua IA. Para integrar seu próprio sistema pela API, siga os passos abaixo. Os botões abrem a tela correspondente; se precisar entrar, o site leva você de volta ao painel depois do login.
1. Crie sua conta e confirme o e-mail
Cadastre-se e abra o link de confirmação recebido por e-mail. Se já tiver conta, entre no painel. Confira a organização no cabeçalho; criar instâncias exige owner ou admin com e-mail confirmado.
Criar minha conta2. Confira seu teste grátis ou assinatura
Em Assinatura, clique em Iniciar teste grátis, se disponível, ou escolha um plano. Se já tiver acesso ativo, continue. Sem assinatura, criar a primeira instância também inicia o teste disponível automaticamente.
Ver teste e assinatura3. Crie sua instância
Uma instância representa uma conexão com um número de WhatsApp. Em Instâncias, preencha Nome com Atendimento e clique em Criar instância. Se Atendimento já existir, abra essa instância. Anote seu ID público (inst_…), que identifica a conexão e não é um token. Para integrar seu sistema pela API, copie também o token exibido agora, antes de sair da tela; para MCP, você usará OAuth.
Abrir criação de instância4. Conecte seu WhatsApp
Após criar, o painel mostra o QR Code. No celular: WhatsApp → Dispositivos conectados → Conectar dispositivo. Leia o código e espere Conectada (connected). Para uma instância existente, abra seus detalhes e a seção Conexão. Se o QR expirar, use Gerar novo QR Code; se estiver desconectada, use Conectar.
Abrir minhas instâncias5. Use o token da instância no seu sistema
O token exibido ao criar a instância começa com wai_… e aparece uma única vez. Guarde-o como senha. Primeiro consulte o estado no exemplo abaixo; envie uma mensagem apenas para um destinatário autorizado. Se precisar de uma chave da organização, siga a seção Autenticação.
Entender chaves e tokens6. Receba eventos no seu sistema
Abra sua instância → Webhook, configure a URL pública do seu receptor e os eventos. Valide a assinatura HMAC de cada entrega com o segredo exibido ao configurar.
Ver configuração de webhook
export TOKEN=wai_... # token da instância
export INSTANCE_ID=inst_... # ID público da instância
# Estado (connected quando o QR Code foi lido)
curl "https://api.zapinapi.duckdns.org/v1/instances/$INSTANCE_ID/status" -H "Authorization: Bearer $TOKEN"
# Enviar texto
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/$INSTANCE_ID/messages/text" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"to": "5511999999999", "text": "Olá!"}'Para automatizar a criação de instâncias, use uma API key (crie em Painel → Integração):
# Com uma API key da organização (escopo instances:manage)
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Atendimento"}'
# 201 {"id":"inst_…","status":"disconnected","token":"wai_…", ...} ← token só aqui
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/$INSTANCE_ID/connect" -H "Authorization: Bearer $API_KEY"
curl "https://api.zapinapi.duckdns.org/v1/instances/$INSTANCE_ID/qrcode" -H "Authorization: Bearer $API_KEY" -o qr.png| Estado | Significado |
|---|---|
| disconnected | Sem conexão (recém-criada, desconectada a pedido ou QR Code esgotado). connect inicia a conexão. |
| connecting | Conectando. |
| qr_required | Aguardando a leitura do QR Code no celular (WhatsApp → Dispositivos conectados). |
| connected | Pronta para enviar e receber. |
| banned | O WhatsApp bloqueou o número temporariamente; aguarde antes de reconectar. |
| logged_out | O aparelho foi desvinculado (logout ou pelo celular); é preciso ler o QR Code de novo. |
Autenticação
Você não precisa criar as duas credenciais: para operar um único número, use o token da instância; para automatizar a organização, crie uma API key com os escopos necessários. Para conectar uma IA pelo MCP, use OAuth.
1. Token de acesso de uma instância (wai_…)
O token é criado junto com a instância e aparece uma única vez. Copie-o para o seu sistema, em armazenamento de segredos, e use Authorization: Bearer. Ele só acessa aquela instância. Se perdeu o token, abra os detalhes → ID e token → Rotacionar token…; confirme apenas quando puder atualizar sua integração, pois o anterior deixa de funcionar na hora.
Abrir instâncias e tokens2. Chave API da organização (wa_live_…)
Em Integração → Criar API key, preencha Nome com ERP produção. Marque apenas os escopos necessários (por exemplo, instances:manage para criar e listar instâncias), defina a validade se desejar e clique em Criar chave. Copie a chave exibida uma única vez e guarde-a no seu sistema. Criar chaves exige owner ou admin com e-mail confirmado.
Abrir criação de API key
| Credencial | Formato | Para quê |
|---|---|---|
| Token da instância | wai_<id>_… | Integrações que operam um número: envio, conversas, contatos, grupos, webhook e estado daquela instância. Outra instância responde 404. |
| API key da organização | wa_live_… | Automação da conta: criar e apagar instâncias, ler assinatura. Escopos: messages:send, messages:read, groups:write, contacts:read, instances:manage, billing:read. Aceita também X-Api-Key. |
| Sessão do painel | JWT (10 min) | Usada pelo painel. API keys e equipe só podem ser geridas com ela. |
Credenciais aparecem uma única vez (ao criar ou rotacionar). No banco ficam só como hash. Escopo ausente responde 403 insufficient_scope.
Webhooks
Configure por instância a URL (https pública), os eventos (nenhum = todos) e receba um segredo whsec_… exibido uma vez. Cada evento é um POST com corpo JSON e os cabeçalhos:
| Cabeçalho | Valor |
|---|---|
| X-Webhook-Id | eventId (estável entre tentativas) |
| Idempotency-Key | eventId |
| X-Webhook-Timestamp | segundos Unix desta tentativa |
| X-Webhook-Signature | sha256= + hex(HMAC-SHA256(segredo, timestamp + "." + corpo cru)) |
| X-Instance-Id | ID público da instância |
| X-Webhook-Event / X-Webhook-Attempt | nome do evento / número da tentativa (informativos) |
{
"eventId": "8f0d1c9e-5d0b-4a43-9a52-1f7d2f3c6b11",
"event": "message.received",
"instanceId": "inst_3b7f0c2a9d8e4f6a8b1c2d3e4f5a6b7c",
"sequence": 42,
"timestamp": "2026-10-21T05:17:45.123Z",
"data": {
"messageId": "3EB0C4F1A2B3", "chatId": "5511988887777", "from": "5511988887777",
"fromMe": false, "isGroup": false, "pushName": "Ana", "type": "text", "text": "Olá!",
"timestamp": "2026-10-21T05:17:44Z"
}
}| Evento | Quando |
|---|---|
| message.received / message.sent | mensagem recebida ou enviada (texto, mídia, localização, contato, enquete) |
| message.status | entregue, lida ou reproduzida |
| message.reaction | reação a uma mensagem |
| poll.vote | voto em enquete |
| button.reply / list.reply | resposta a botões ou lista |
| group.participants.updated | participante adicionado, removido, promovido ou rebaixado |
| group.updated / group.joined | dados do grupo alterados ou entrada da conta em grupo |
| chat.presence / contact.presence | digitando, gravando, pausa e contato online/offline |
| chat.settings.updated / contact.updated | fixação, silêncio, arquivo ou nome de contato alterado |
| message.undecryptable | falha de descriptografia ou mensagem indisponível; não reenvie automaticamente |
| instance.connected / instance.disconnected / instance.qrcode | mudança de estado e QR Code novo (o QR em si só por GET …/qrcode) |
- Sem webhook configurado, consulte os mesmos eventos por GET /v1/instances/{id}/events?after=0&limit=100 ou pela ferramenta list_instance_events. Filtro opcional event (ex.: chat.presence), até 500 itens, ordem crescente de sequence. Passe nextCursor na próxima consulta; página vazia preserva o cursor. Leitura não cria entregas e segue a retenção do histórico; ausência de evento não prova ausência de envio.
- Cada evento é um POST JSON para a URL configurada (https pública). O seu servidor tem 10 segundos para responder.
- Só HTTP 2xx confirma a entrega. 3xx (redirecionamentos não são seguidos), 4xx, 5xx, timeout e erro de rede contam como falha e voltam a ser tentados com intervalo crescente (até 5 minutos entre tentativas).
- Depois de 10 falhas seguidas a entrega fica no estado dead e não é mais tentada sozinha. Reenvie pelo painel (seção de entregas da instância) ou por POST /v1/instances/{id}/deliveries/{eventId}/retry.
- A entrega é pelo menos uma vez: o mesmo evento pode chegar mais de uma vez. Deduplique pelo eventId (também no cabeçalho X-Webhook-Id e em Idempotency-Key), que é estável entre tentativas.
- A ordem de chegada não é garantida. Use sequence (crescente por instância) para ordenar.
- Estados de uma entrega: pending (aguardando tentativa), processing (em tentativa), delivered (2xx recebido) e dead (tentativas esgotadas). Consulte por GET /v1/instances/{id}/deliveries?status=dead.
- Rotacionar o segredo (PUT …/webhook com rotateSecret: true) vale a partir da próxima tentativa, sem período de convivência. O segredo whsec_… aparece uma única vez na resposta.
- A URL do webhook não pode apontar para rede privada, loopback ou endereços de metadados de nuvem.
Payload de cada evento
message.received / message.sent: Mensagem recebida (ou enviada por esta instância, inclusive pelo celular). Texto, mídia, localização, contato e enquete.
{
"messageId": "3EB0C4F1A2B3", "chatId": "5511988887777", "from": "5511988887777",
"fromMe": false, "isGroup": false, "pushName": "Ana", "type": "text", "text": "Olá!",
"timestamp": "2026-10-21T05:17:44Z"
}
// mídia: "type": "image|audio|video|document|sticker", "caption"?,
// "media": {"mimeType", "fileName"?, "fileLength", "seconds"?, "ptt"?}
// localização: "type": "location", "location": {"latitude", "longitude", "name"?, "address"?}
// contato: "type": "contact", "contacts": [{"displayName", "vcard"}]
// enquete: "type": "poll", "poll": {"name", "options", "selectableCount"}
// convite: "type": "group_invite", "groupInvite": {"groupId", "groupName", "code", "expiration"}
// formatos ainda sem campos normalizados: "type": "unknown" (identificadores e data preservados)
// também: "quotedMessageId"?, "viewOnce"?, "status": "sent" (só em message.sent)
// grupo: "isGroup": true e "chatId" = id do grupo (…@g.us); "from" = telefone do autormessage.status: Mensagem enviada foi entregue, lida ou reproduzida (áudio/vídeo).
{
"messageIds": ["3EB0C4F1A2B3"], "chatId": "5511988887777",
"status": "delivered", "isGroup": false, "timestamp": "2026-10-21T05:18:02Z"
}
// "status": "delivered" | "read" | "played"; em grupo vem "participant"message.reaction: Alguém reagiu a uma mensagem (removed: true = reação removida).
{
"messageId": "3EB0REACT1", "chatId": "5511988887777", "from": "5511988887777",
"fromMe": false, "isGroup": false, "targetMessageId": "3EB0C4F1A2B3",
"emoji": "👍", "removed": false, "timestamp": "2026-10-21T05:19:10Z"
}poll.vote: Voto (ou mudança de voto) numa enquete enviada por esta instância.
{
"messageId": "3EB0VOTE01", "chatId": "5511988887777", "from": "5511988887777",
"fromMe": false, "isGroup": false, "pollMessageId": "3EB0POLL01",
"selectedOptions": ["Manhã"], "selectedOptionHashes": ["<sha256 hex>"], "timestamp": "2026-10-21T05:20:00Z"
}button.reply / list.reply: Resposta a botões de resposta ou escolha de uma linha de lista.
{
"messageId": "3EB0REPLY1", "chatId": "5511988887777", "from": "5511988887777",
"fromMe": false, "isGroup": false, "buttonId": "sim", "buttonText": "Sim",
"quotedMessageId": "3EB0BTN01", "timestamp": "2026-10-21T05:21:00Z"
}
// list.reply: "rowId", "title" e "description" no lugar de "buttonId" e "buttonText"group.participants.updated: Participante adicionado, removido, promovido ou rebaixado num grupo (um evento por ação).
{
"groupId": "120363012345678901@g.us", "action": "add",
"participants": ["5511977776666"], "author": "5511988887777", "timestamp": "2026-10-21T05:22:00Z"
}chat.presence / contact.presence: Digitando, gravando ou pausa em conversa; contato online/offline. Para receber digitando, envie presence com state=online. Para online/offline, assine POST contacts/{phone}/presence/subscribe; sujeito à privacidade do contato e à duração da conexão.
{ "chatId": "5511988887777", "from": "5511988887777", "isGroup": false, "state": "typing", "timestamp": "2026-10-28T12:00:00Z" }
// state: typing | recording | paused
// contact.presence: { "from": "5511988887777@s.whatsapp.net", "online": true, "lastSeen"?: "...", "timestamp": "..." }group.updated / group.joined: Mudança de nome, descrição, configurações, convite ou exclusão de grupo; entrada da conta em um grupo.
{ "groupId": "120363012345678901@g.us", "author": "5511988887777", "changes": { "name": "Equipe", "locked": true }, "timestamp": "2026-10-28T12:00:00Z" }
// changes: name, description, locked, announce, ephemeral, disappearingTimer, inviteLinkChanged, deleted,
// pictureId, pictureRemoved, joinApprovalRequired, linkedGroupId, unlinkedGroupId, suspended, otherChanges
// group.joined: { "groupId": "...@g.us", "name": "Equipe", "reason": "invite", "timestamp": "..." }chat.settings.updated / contact.updated: Estado da conversa ou nome de contato mudou após a sincronização inicial. A leitura de settings é o último estado sincronizado; não confirma que o celular já exibiu a alteração.
{ "chatId": "5511988887777@s.whatsapp.net", "pinned": true, "timestamp": "2026-10-28T12:00:00Z" }
// outros campos: archived, muted e muteEndTimestamp (Unix ms; -1 = para sempre)
// contact.updated: { "jid": "...@s.whatsapp.net", "fullName": "Maria Silva", "firstName": "Maria", "timestamp": "..." }message.undecryptable: A mensagem não pôde ser descriptografada ou não está disponível para este aparelho. A recuperação de protocolo é automática quando possível; isso não autoriza reenviar a mensagem original.
{ "messageId": "3EB0C4F1A2B3", "chatId": "5511988887777", "from": "5511988887777", "unavailable": false, "timestamp": "2026-10-28T12:00:00Z" }instance.connected / instance.disconnected / instance.qrcode: Mudança de estado da instância e QR Code novo disponível. O QR em si só por GET …/qrcode.
{ "state": "connected", "reason": "paired", "since": "2026-10-21T05:10:00Z" }
// instance.qrcode: { "state": "qr_required", "reason": "...", "since": "...", "qrGeneration": 2 }Boas práticas no receptor
- Valide a assinatura HMAC sobre o corpo cru, antes de interpretar o JSON, e recuse timestamps com mais de 5 minutos de diferença.
- Responda 2xx rápido (bem antes de 10 s): grave o evento numa fila ou tabela e processe depois.
- Seja idempotente no consumidor: guarde os eventId já processados e ignore repetições.
- Guarde o segredo whsec_… como senha (variável de ambiente ou cofre), nunca no código nem em log.
- Monitore entregas em dead no painel e reenvie depois de corrigir o receptor.
- Use timeouts nas chamadas que o seu receptor fizer a outros sistemas, para não estourar os 10 s.
Valide a assinatura sobre o corpo cru (antes de interpretar o JSON) e recuse timestamps com mais de 5 minutos de diferença:
import { createHmac, timingSafeEqual } from "crypto";
// rawBody: o corpo exatamente como recebido (string/Buffer), antes de JSON.parse
export function verify(secret, headers, rawBody) {
const ts = headers["x-webhook-timestamp"];
const sig = headers["x-webhook-signature"] ?? "";
if (!/^\d+$/.test(ts ?? "") || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // replay
const expected = "sha256=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
return expected.length === sig.length && timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}using System.Security.Cryptography;
using System.Text;
static bool Verify(string secret, string timestamp, string signature, byte[] rawBody)
{
if (!long.TryParse(timestamp, out var ts) ||
Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - ts) > 300) return false; // replay
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var prefix = Encoding.UTF8.GetBytes(timestamp + ".");
var data = new byte[prefix.Length + rawBody.Length];
prefix.CopyTo(data, 0);
rawBody.CopyTo(data, prefix.Length);
var expected = Encoding.ASCII.GetBytes("sha256=" + Convert.ToHexString(hmac.ComputeHash(data)).ToLowerInvariant());
return CryptographicOperations.FixedTimeEquals(expected, Encoding.ASCII.GetBytes(signature ?? ""));
}Erros
Todo erro é application/problem+json com type, title, status, detail e code. Trate pelo code; o texto pode mudar.
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
{
"type": "https://docs.whatsapp-api.invalid/errors/instance_limit_reached",
"title": "Payment Required",
"status": 402,
"detail": "Limite de instâncias do plano atingido.",
"code": "instance_limit_reached"
}| Status | code | Significado | O que fazer |
|---|---|---|---|
| 400 | invalid_body | Corpo JSON inválido ou campo com tipo errado. | Corrija o corpo antes de repetir. |
| 400 | text_required / text_too_long | Texto ausente ou longo demais. | Envie text com conteúdo dentro do limite. |
| 400 | invalid_recipient / invalid_mention | Telefone de destino ou menção inválidos. | Use o número com DDI e DDD, só dígitos (ex.: 5511999999999). |
| 400 | media_required / invalid_base64 / media_empty | Mídia ausente, base64 inválido ou arquivo vazio. | Envie url ou base64 válido. |
| 400 | media_url_forbidden | URL de mídia aponta para rede privada ou não pública. | Use uma URL https pública. |
| 400 | invalid_webhook_url / invalid_webhook_events | URL de webhook não é https pública ou evento desconhecido. | Corrija a URL ou a lista de eventos. |
| 400 | invalid_options / invalid_sections / invalid_buttons / invalid_pix | Estrutura de mensagem interativa inválida. | Confira os limites (2–12 opções, 1–10 linhas, 1–3 botões). |
| 400 | invalid_idempotency_key / invalid_period / invalid_name | Parâmetro inválido. | Corrija o parâmetro indicado no detail. |
| 401 | unauthorized | Credencial ausente, inválida, revogada ou expirada. | Confira o token; para o agente, reconecte (nova autorização). |
| 402 | subscription_required / subscription_suspended | Sem assinatura ativa, teste encerrado ou conta suspensa. | Assine ou regularize em /app/assinatura. |
| 402 | instance_limit_reached | A assinatura não comporta mais instâncias. | Aumente a quantidade contratada ou apague uma instância. |
| 403 | insufficient_scope | A credencial não tem o escopo exigido. | Use uma credencial com o escopo; o agente reconecta concedendo a permissão. |
| 403 | insufficient_role | Seu papel na organização não permite a operação (ex.: member lendo QR Code). | Peça a um owner ou admin. |
| 403 | pro_feature_required | Recurso PRO (enquete, lista, botões, Pix) num plano sem PRO. Traz upgradeUrl. | Faça o upgrade pelo link upgradeUrl. |
| 403 | email_not_confirmed | E-mail da conta ainda não confirmado. | Confirme o e-mail pelo link recebido (reenvio no painel). |
| 403 | instance_token_not_allowed | Token de instância usado fora das rotas da própria instância. | Use uma API key ou a sessão do painel. |
| 403 | group_permission_denied / not_in_group | A instância não é admin do grupo ou não participa dele. | Use um grupo em que a instância seja admin. |
| 404 | instance_not_found | Instância inexistente, de outra organização ou fora da autorização do agente (resposta idêntica). | Confira o ID inst_…; para o agente, inclua a instância na autorização. |
| 404 | delivery_not_found / message_not_found / group_not_found | Recurso inexistente. | Confira o identificador. |
| 409 | instance_not_connected | A instância não está connected. | Conecte e leia o QR Code no painel. |
| 409 | idempotency_request_in_progress | Pedido com a mesma Idempotency-Key ainda em andamento. | Aguarde e consulte antes de repetir. |
| 409 | delivery_not_retryable | Entrega já confirmada ou em tentativa. | Nada a fazer; consulte a entrega. |
| 404 | qr_not_available | Não há QR disponível. | Com instances:manage já concedido, consulte get_instance_status (state e paired). Se connected ou paired=true, não inicie pareamento desnecessário. Com paired=false e pareamento autorizado, use connect_instance uma vez. Sem escopo, permissão de QR ou renderização, use o painel; nunca desvincule nem repita em loop. |
| 410 | qr_expired | QR Code expirou. | Com instances:manage já concedido, consulte state e paired. Se ainda precisar parear e houver autorização, use connect_instance uma vez; sem escopo, permissão ou renderização de QR, use o painel. Não use logout nem inicie loops. |
| 413 | media_too_large / body_too_large | Mídia ou corpo acima do limite. | Reduza o arquivo ou use URL. |
| 422 | idempotency_key_reused | Mesma Idempotency-Key com outro pedido. | Gere uma chave nova por mensagem. |
| 422 | unsupported_media_type / media_fetch_failed | Tipo de mídia não aceito ou URL não pôde ser baixada. | Confira o formato e a URL. |
| 422 | not_forwardable | Mensagem não pode ser encaminhada (enquete ou interativa). | Envie uma mensagem nova. |
| 429 | rate_limited | Acima do limite de requisições por minuto. | Espere os segundos de Retry-After antes de repetir. |
| 429 | whatsapp_rate_limited | O WhatsApp limitou o envio deste número. | Reduza o ritmo; não insista. |
| 502 | send_rejected / fallback_failed / upload_failed | O WhatsApp recusou o envio ou o upload. | Confira destino e conteúdo; não repita em laço. |
| 502 | invalid_upstream_response | Resposta inválida do serviço; desfecho pode ser incerto. | Consulte antes de repetir um envio. |
| 503 | node_unavailable / no_node_available | Serviço da instância indisponível no momento. | Tente novamente em instantes. |
| 504 | node_timeout / whatsapp_timeout | Tempo esgotado: a mensagem pode ter saído. | Repita só com a MESMA Idempotency-Key; nunca com uma nova. |
Paginação
Listas usam cursor: limit e after na consulta, nextCursor na resposta. Passe o nextCursor como after até ele vir null (ou 0 em conversas e entregas). Entregas aceitam também status (pending|processing|delivered|dead).
GET /v1/instances?limit=50
→ {"items":[…], "nextCursor":"inst_…"}
GET /v1/instances?limit=50&after=inst_…
→ {"items":[…], "nextCursor":null} # fimIdempotência
Envie Idempotency-Key (até 255 caracteres; um UUID por mensagem) em todo POST …/messages/* e DELETE …/messages/{messageId}. Por 24 h, repetir a mesma chave com o mesmo pedido devolve a mesma resposta com Idempotent-Replayed: true, sem novo envio. Corpo diferente: 422 idempotency_key_reused; ainda em andamento: 409 idempotency_request_in_progress. Respostas 4xx liberam a chave.
Um 504 é desfecho incerto (a mensagem pode ter saído): repita com a mesma chave, nunca com uma nova.
Limites
| Plano | Requisições | Instâncias |
|---|---|---|
| Teste grátis | 60 req/min | 1 instância |
| LITE | 60 req/min | conforme a quantidade contratada |
| PRO | 120 req/min | conforme a quantidade contratada |
| Escala | 300 req/min | sob contrato |
- O limite é por organização. Acima dele:
429 rate_limitedcomRetry-After(segundos). - Assinatura sem pagamento, suspensa ou sem vaga:
402. Recursos PRO (enquete, lista, botões, Pix) num plano sem PRO:403 pro_feature_requiredcomupgradeUrl. - O QR Code se renova sozinho (60 s o primeiro, 20 s os seguintes, 6 códigos); esgotados, a instância fica
disconnectedcomreason=qr_expirede um novoconnectrecomeça. - Uso responsável: nada de spam ou disparo em massa. O WhatsApp pode banir o número.
Limites de mídia
| Item | Regra |
|---|---|
| Baixar mídia recebida | GET messages/{messageId}/media?chat=... devolve base64, mimetype, fileName e fileLength. Usa apenas mensagens no cache recente (até 1000 por instância, 24 h); reinício perde o cache. maxBytes é 512 KiB por padrão, até 16 MiB. Resposta grande pode ultrapassar o limite do aplicativo de IA. Mídia vencida no WhatsApp pode estar indisponível. |
| Status experimental | POST statuses/text, statuses/image e statuses/video publicam para o público definido pela privacidade de Status da conta, sem destinatário to. Confirme o público antes de publicar. Pode falhar com agendas grandes. Sucesso técnico não comprova visualização; nunca repita automaticamente após timeout. |
| Convites e estado da conta | POST groups/invite/lookup e groups/invite/join recebem code no corpo. Para convite recebido como mensagem, informe também groupId, inviter (o autor da mensagem) e expiration (Unix segundos). PUT contacts/{phone} sincroniza fullName/firstName. GET chats/{phone}/settings consulta found, pinned, archived, muted, mutedForever e mutedUntil (null quando não há prazo). PUT chats/{phone}/pin, /mute e /archive recebem enabled; mute aceita durationSeconds de 0 a 315360000 (0/ausente = para sempre). Arquivar também desafixa. |
| Mídia por URL ou base64 | Envie exatamente um de url (https pública, baixada sem seguir redirecionamentos) ou base64 (cru ou data:<mime>;base64,…). |
| Documento, áudio e vídeo | Até 64 MiB por arquivo (em base64, cerca de 86 MiB de texto). |
| Imagem e figurinha | Até 16 MiB por arquivo por padrão; imagem em JPEG ou PNG, figurinha em WebP. A configuração do serviço pode reduzir os limites de mídia. |
| Nota de voz | audio com ptt: true exige OGG/Opus. |
| Corpo da requisição | Até 96 MiB na API REST. Pelas ferramentas MCP do agente o corpo é limitado a 1 MiB: prefira mídia por URL. |
| Base64 no MCP | Até 1.000.000 caracteres e sempre dentro do teto de 1 MiB do JSON completo. Para arquivos maiores, use URL pública acessível durante a chamada (inclusive URL assinada do armazenamento do integrador). Sem upload temporário adicional. |
| Anexos do aplicativo | O agente só acessa anexos que o aplicativo hospedeiro disponibilizar como arquivo ou URL utilizável. Anexar no chat não garante acesso pelo plugin. Os limites de anexo do aplicativo são independentes. |
| Texto e legenda | Até 65536 bytes UTF-8. vCard até 16384 bytes; texto Pix até 4096 bytes; miniatura de vídeo JPEG até 256 KiB decodificados. Bytes não equivalem a caracteres. |
Campos por tipo de mensagem
| Tipo | Campos |
|---|---|
| text | to, text, mentions?: [telefone], replyTo?: {messageId, participant?, fromMe?} |
| image / audio / video / document / sticker | to, url ou base64 (exatamente um), mimetype?, fileName? (documento), caption?, ptt? (áudio OGG/Opus), seconds?, gifPlayback? (vídeo), thumbnail? (vídeo, JPEG base64), replyTo? |
| location | to, latitude, longitude, name?, address?, url?, replyTo? |
| contact | to + {name, phone, organization?, email?} ou to + vcard, ou to + contacts: [até 50] |
| reply | to, text, messageId, participant? (obrigatório em grupo), fromMe?, mentions? |
| react | to, messageId, reaction (emoji; vazio remove), participant?, fromMe? |
| forward | to, messageId (mensagem recente da instância) |
| poll (PRO) | to, question, options: [2 a 12, únicas], selectableCount? (1 padrão; 0 = qualquer número) |
| list (PRO) | to, text, title?, footer?, buttonText?, sections: [{title?, rows: [{id?, title, description?}]}] (1 a 10 linhas) |
| buttons (PRO) | to, text, title?, footer?, buttons: [{type: url, text, url} ou {type: call, text, phone} ou {type: copy, text, code}] (1 a 3) |
| reply-buttons (PRO) | to, text, title?, footer?, buttons: [{id?, text}] (1 a 3) |
| pix (PRO) | to, amount (centavos), merchantName, pixKey?, pixKeyType? (CPF, CNPJ, EMAIL, PHONE ou EVP), brCode?, text?, footer?, referenceId? |
| DELETE messages/{messageId} | to, participant? (remetente quando admin apaga mensagem de outro) |
| POST read | to, messageIds: [1 a 100], participant? (obrigatório em grupo) |
| POST presence | state: typing, recording ou paused com to; ou state: online ou offline |
Receitas
Enviar uma mensagem e receber o webhook com verificação da assinatura, por linguagem:
// Node.js 18+ (fetch nativo). TOKEN=wai_... INSTANCE_ID=inst_...
const r = await fetch(`https://api.zapinapi.duckdns.org/v1/instances/${process.env.INSTANCE_ID}/messages/text`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({ to: "5511999999999", text: "Olá!" }),
});
if (!r.ok) throw new Error(`HTTP ${r.status}: ${(await r.json()).code}`);
console.log(await r.json()); // { messageId, timestamp, ... }// Node.js 18+ com Express: o corpo cru é necessário para a assinatura.
import express from "express";
import { createHmac, timingSafeEqual } from "crypto";
const app = express();
const seen = new Set(); // em produção, uma tabela com os eventId processados
app.post("/webhooks/whatsapp", express.raw({ type: "application/json" }), (req, res) => {
const ts = req.get("X-Webhook-Timestamp") ?? "";
const sig = req.get("X-Webhook-Signature") ?? "";
if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);
const expected = "sha256=" + createHmac("sha256", process.env.WEBHOOK_SECRET).update(ts + "." + req.body).digest("hex");
if (expected.length !== sig.length || !timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) return res.sendStatus(401);
const event = JSON.parse(req.body);
res.sendStatus(200); // responda rápido; processe depois
if (seen.has(event.eventId)) return;
seen.add(event.eventId);
// enfileire event para processamento
});
app.listen(3000);# pip install requests
import os, uuid, requests
r = requests.post(
f"https://api.zapinapi.duckdns.org/v1/instances/{os.environ['INSTANCE_ID']}/messages/text",
headers={
"Authorization": f"Bearer {os.environ['TOKEN']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={"to": "5511999999999", "text": "Olá!"},
timeout=30,
)
r.raise_for_status()
print(r.json())# pip install flask
import hashlib, hmac, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["WEBHOOK_SECRET"].encode()
@app.post("/webhooks/whatsapp")
def webhook():
ts = request.headers.get("X-Webhook-Timestamp", "")
sig = request.headers.get("X-Webhook-Signature", "")
raw = request.get_data() # corpo cru
if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
abort(401)
expected = "sha256=" + hmac.new(SECRET, ts.encode() + b"." + raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig):
abort(401)
event = request.get_json()
# deduplique por event["eventId"] e enfileire
return "", 200<?php
$ch = curl_init("https://api.zapinapi.duckdns.org/v1/instances/" . getenv("INSTANCE_ID") . "/messages/text");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("TOKEN"),
"Content-Type: application/json",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => json_encode(["to" => "5511999999999", "text" => "Olá!"]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status >= 300) throw new Exception("HTTP $status: $body");
echo $body;<?php
$raw = file_get_contents("php://input"); // corpo cru
$ts = $_SERVER["HTTP_X_WEBHOOK_TIMESTAMP"] ?? "";
$sig = $_SERVER["HTTP_X_WEBHOOK_SIGNATURE"] ?? "";
if (!ctype_digit($ts) || abs(time() - (int)$ts) > 300) { http_response_code(401); exit; }
$expected = "sha256=" . hash_hmac("sha256", $ts . "." . $raw, getenv("WEBHOOK_SECRET"));
if (!hash_equals($expected, $sig)) { http_response_code(401); exit; }
$event = json_decode($raw, true);
// deduplique por $event["eventId"] e enfileire
http_response_code(200);// .NET 8
using System.Net.Http.Json;
using var http = new HttpClient { BaseAddress = new Uri("https://api.zapinapi.duckdns.org") };
http.DefaultRequestHeaders.Authorization = new("Bearer", Environment.GetEnvironmentVariable("TOKEN"));
var request = new HttpRequestMessage(HttpMethod.Post,
$"/v1/instances/{Environment.GetEnvironmentVariable("INSTANCE_ID")}/messages/text")
{
Content = JsonContent.Create(new { to = "5511999999999", text = "Olá!" }),
};
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());// Minimal API (.NET 8): lê o corpo cru antes de desserializar.
using System.Security.Cryptography;
using System.Text;
var secret = Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("WEBHOOK_SECRET")!);
var app = WebApplication.Create(args);
app.MapPost("/webhooks/whatsapp", async (HttpRequest req) =>
{
using var ms = new MemoryStream();
await req.Body.CopyToAsync(ms);
var raw = ms.ToArray();
var ts = req.Headers["X-Webhook-Timestamp"].ToString();
var sig = req.Headers["X-Webhook-Signature"].ToString();
if (!long.TryParse(ts, out var t) || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t) > 300) return Results.Unauthorized();
var data = Encoding.UTF8.GetBytes(ts + ".").Concat(raw).ToArray();
var expected = "sha256=" + Convert.ToHexString(HMACSHA256.HashData(secret, data)).ToLowerInvariant();
if (!CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(expected), Encoding.ASCII.GetBytes(sig))) return Results.Unauthorized();
// deduplique pelo eventId e enfileire
return Results.Ok();
});
app.Run();// Java 11+ (java.net.http)
import java.net.URI;
import java.net.http.*;
import java.util.UUID;
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.zapinapi.duckdns.org/v1/instances/" + System.getenv("INSTANCE_ID") + "/messages/text"))
.header("Authorization", "Bearer " + System.getenv("TOKEN"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.POST(HttpRequest.BodyPublishers.ofString("{\"to\":\"5511999999999\",\"text\":\"Olá!\"}"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 300) throw new RuntimeException(response.body());
System.out.println(response.body());// Verificação HMAC (use no controller que recebe o POST; rawBody = bytes do corpo cru).
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
static boolean verify(String secret, String ts, String signature, byte[] rawBody) throws Exception {
if (ts == null || !ts.matches("\\d+") || Math.abs(System.currentTimeMillis() / 1000 - Long.parseLong(ts)) > 300) return false;
var mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
mac.update((ts + ".").getBytes(StandardCharsets.UTF_8));
var expected = "sha256=" + HexFormat.of().formatHex(mac.doFinal(rawBody));
return MessageDigest.isEqual(expected.getBytes(StandardCharsets.US_ASCII),
(signature == null ? "" : signature).getBytes(StandardCharsets.US_ASCII));
}Diagnóstico
A mensagem não chega
- Consulte GET /v1/instances/{id}/status: o estado precisa ser connected. Se não for, conecte e leia o QR Code no painel.
- Confira o número de destino: só dígitos, com DDI e DDD (ex.: 5511999999999). GET …/contacts/{phone}/exists diz se o número tem WhatsApp.
- Veja a resposta do envio: 2xx traz messageId; 409 instance_not_connected, 502 send_rejected e 429 whatsapp_rate_limited explicam a recusa.
- Acompanhe o evento message.status (delivered/read) no webhook para saber se chegou ao aparelho.
- 504 é desfecho incerto: repita só com a mesma Idempotency-Key.
O webhook não recebe
- Confira GET /v1/instances/{id}/webhook: URL https pública e eventos (lista vazia = todos).
- Liste GET …/deliveries?status=dead e consulte uma entrega: o código HTTP e o erro da última tentativa mostram o que o seu servidor respondeu.
- Seu servidor precisa responder 2xx em até 10 s. Redirecionamentos não são seguidos; certificados inválidos falham.
- Se a assinatura falha no seu lado, confira que valida o corpo cru e usa o segredo atual (rotateSecret troca o segredo na hora).
- Corrigido o receptor, reenvie as entregas em dead pelo painel ou por POST …/deliveries/{eventId}/retry.
401
- Credencial ausente, expirada ou revogada. Para o agente: reconecte para abrir a tela de autorização de novo.
402
- Assinatura ou teste inativo, conta suspensa ou limite de instâncias. Regularize em /app/assinatura.
403
- insufficient_scope: falta permissão; reconecte o agente concedendo-a.
- pro_feature_required: recurso PRO; use o upgradeUrl da resposta.
- insufficient_role: peça a um owner ou admin.
- email_not_confirmed: confirme o e-mail da conta.
404
- A instância não existe ou não foi incluída na autorização do agente. Confira o ID inst_… e a autorização em /app/integracao.
429
- Limite por minuto do plano. Espere os segundos de Retry-After; não repita em laço.
Jornada no site
- Criar conta: Em /cadastro, e confirmar o e-mail pelo link recebido. Sem e-mail confirmado não se cria instância.
- Ativar o teste grátis ou assinar: O teste grátis tem 7 dias, 1 instância e recursos PRO, sem cartão. Planos em /precos levam a /app/assinatura.
- Criar a instância: Em /app/instancias. O agente pode criar se tiver a permissão de gerenciar instâncias.
- Parear o WhatsApp: Ler o QR Code em /app/instancias/{id} com o celular (WhatsApp → Dispositivos conectados). Recomendado fazer no painel.
- Entregar as instruções à IA: Em /docs/mcp (Conecte sua IA), copie as instruções e entregue à IA que você usa. A skill (zip) e o llms.txt são opcionais.
- Conectar o agente: Se o aplicativo aceitar MCP remoto, no primeiro uso de uma ação o navegador abre a tela de autorização: escolha organização, instâncias e permissões. Comece por uma leitura compatível com as permissões concedidas (listar instâncias exige gerenciar instâncias).
- Pedir a integração: Ex.: "configure o webhook para https://meusistema/webhook e gere o receptor". O segredo aparece uma única vez.
- Testar: O agente envia uma mensagem de teste autorizada e informa messageId. Confira a mensagem no destinatário. A seção Entregas da instância mostra eventos entregues ao receptor do webhook, não entrega ou leitura no WhatsApp.
- Acompanhar e revogar: Em /app/integracao, seção Agentes conectados: veja e revogue qualquer agente, com efeito imediato.
Privacidade
- O histórico de mensagens e eventos das instâncias fica guardado por 30 dias por padrão e depois é apagado automaticamente.
- O conteúdo das mensagens pertence a você ou aos titulares; você é o controlador dos dados das suas conversas e nós tratamos em seu nome.
- Ao conectar um agente de IA, você direciona conteúdo de conversas ao agente que escolheu, sob sua responsabilidade. Conceda só as instâncias e permissões necessárias e revogue quando não precisar mais.
- Conta suspensa por falta de pagamento: dados retidos por até 30 dias (carência de 5 dias antes da suspensão). Conta cancelada: dados purgados em até 30 dias.
- Exportar ou excluir os dados da conta: pelo painel (Conta) ou pelo e-mail do encarregado. A exportação dos dados das instâncias também pode ser pedida.
- Segredos (tokens, chaves e segredo do webhook) são guardados só como hash quando possível e aparecem uma única vez.
Detalhes na política de privacidade.
Conectar sua IA (MCP)
Copie as instruções prontas e entregue à IA que você usa: elas apontam esta documentação, o servidor MCP e a autorização pelo navegador. Com o aplicativo conectado, a IA configura a integração com o seu consentimento; sem conexão, ela usa a documentação para orientar e escrever o código. Conectar sua IA.
Referência
Clique numa rota para ver parâmetros, exemplo e respostas. {id} é o ID público da instância (inst_…).
Instâncias
Criar, conectar por QR Code, consultar estado, rotacionar token e apagar.
GET/v1/instances/{id}/statusEstado da instancia em tempo real
Escopo exigido de API key ou token de instancia: `instances:manage`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/status" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/qrcodeQR Code de pareamento (image/png, ou JSON com ?format=base64)
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role), pois o QR Code vincula um aparelho.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/qrcode" \
-H "Authorization: Bearer $TOKEN"- 200 OK (image/png)
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/connectConectar (gera QR se nao pareada)
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role).
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/connect" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/disconnectDesconectar mantendo a sessao
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role).
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/disconnect" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/logoutDesvincular o aparelho e apagar a sessao
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role).
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/logout" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instancesListar instancias (after/nextCursor)
Autenticação: API key (instances:manage) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| after | query | string | |
| limit | query | integer int32 |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/instancesCriar instancia (inicia o teste gratis na primeira; token exibido uma vez)
Autenticação: API key (instances:manage) ou sessão do painel
Corpo (JSON): name: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Minha integração"}'- 201 Created
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/summaryResumo das instancias da organizacao (contagem por estado e suspensas)
Autenticação: API key (instances:manage) ou sessão do painel
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/summary" \
-H "Authorization: Bearer $TOKEN"- 200 OK
GET/v1/instances/{id}Consultar instancia
Autenticação: API key (instances:manage) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
DELETE/v1/instances/{id}Apagar instancia (desconecta, libera a vaga e apaga os dados da instancia)
Autenticação: API key (instances:manage) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID" \
-H "Authorization: Bearer $TOKEN"- 204 No Content
POST/v1/instances/{id}/tokenRotacionar o token da instancia (o anterior deixa de valer; o novo aparece uma vez)
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/token" \
-H "Authorization: Bearer $TOKEN"- 201 Created
Mensagens
Envio (aceita Idempotency-Key), apagar, marcar como lida e presença.
GET/v1/instances/{id}/message-attemptsConsultar tentativa pela chave de idempotencia, sem novo envio
Escopo exigido de API key ou token de instancia: `messages:read`. Consulta somente o registro vigente de idempotencia (janela padrao de 24 h), sem novo envio. completed significa resposta HTTP guardada, nao entrega. outcome=confirmed exige sucesso e messageId; 5xx, em andamento ou resposta indisponivel permanecem uncertain. Registro ausente/expirado retorna 404 message_attempt_not_found e nao comprova falha. Nao retorna texto nem destinatario.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| idempotencyKey * | query | string | Chave exata do pedido original (1 a 255 caracteres). |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/message-attempts" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/textTexto
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/text" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","text":"Olá! Seu pedido saiu para entrega."}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/statuses/textPublicar Status de texto (experimental)
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto. Status experimental, sujeito a falhas com agendas grandes. Publica para o publico definido pela privacidade de Status da conta; nao recebe destinatario to. Confirme o publico antes de publicar.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/statuses/text" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"text":"Novidades da loja","backgroundArgb":4278672980,"font":0}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/statuses/imagePublicar Status de imagem (experimental)
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto. Status experimental, sujeito a falhas com agendas grandes. Publica para o publico definido pela privacidade de Status da conta; nao recebe destinatario to. Confirme o publico antes de publicar.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/statuses/image" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemplo.com.br/foto.jpg","caption":"Novidades"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/statuses/videoPublicar Status de video (experimental)
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto. Status experimental, sujeito a falhas com agendas grandes. Publica para o publico definido pela privacidade de Status da conta; nao recebe destinatario to. Confirme o publico antes de publicar.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/statuses/video" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemplo.com.br/video.mp4","seconds":15}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/imageImagem (URL ou base64)
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/image" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","url":"https://exemplo.com.br/foto.jpg","caption":"Comprovante"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/audioAudio ou nota de voz
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/audio" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","url":"https://exemplo.com.br/audio.ogg","ptt":true}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/videoVideo
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/video" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","url":"https://exemplo.com.br/video.mp4","caption":"Tutorial"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/documentDocumento
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/document" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","url":"https://exemplo.com.br/boleto.pdf","fileName":"boleto.pdf"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/stickerFigurinha
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/sticker" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","url":"https://exemplo.com.br/figurinha.webp"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/locationLocalizacao
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/location" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","latitude":-23.5614,"longitude":-46.6559,"name":"Loja Paulista"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/contactContato (vCard)
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/contact" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","name":"Suporte","phone":"5511988887777"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/replyResponder citando
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/reply" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","text":"Combinado!","messageId":"3EB0C4F1A2B3"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/reactReagir
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/react" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","messageId":"3EB0C4F1A2B3","reaction":"👍"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/forwardEncaminhar
Escopo exigido de API key ou token de instancia: `messages:send`. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/forward" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","messageId":"3EB0C4F1A2B3"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/pollEnquete (PRO)PRO
Escopo exigido de API key ou token de instancia: `messages:send`. Recurso PRO: plano sem PRO recebe 403 pro_feature_required com upgradeUrl. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/poll" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","question":"Melhor horário?","options":["Manhã","Tarde"],"selectableCount":1}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/listLista/menu (PRO)PRO
Escopo exigido de API key ou token de instancia: `messages:send`. Recurso PRO: plano sem PRO recebe 403 pro_feature_required com upgradeUrl. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/list" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","text":"Escolha uma opção","buttonText":"Ver opções","sections":[{"title":"Atendimento","rows":[{"id":"2via","title":"2ª via do boleto"},{"id":"humano","title":"Falar com atendente"}]}]}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/messages/pixCobranca Pix (PRO)PRO
Escopo exigido de API key ou token de instancia: `messages:send`. Recurso PRO: plano sem PRO recebe 403 pro_feature_required com upgradeUrl. Sucesso inclui messageId, timestamp, type e fallback quando aplicavel. Confirma envio tecnico, nao entrega/leitura. Recibos posteriores chegam pelos eventos disponiveis; nunca repita automaticamente um envio de desfecho incerto.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/pix" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","amount":12990,"merchantName":"Minha Loja","pixKey":"financeiro@exemplo.com.br","pixKeyType":"EMAIL"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
DELETE/v1/instances/{id}/messages/{messageId}Apagar para todos
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| Idempotency-Key | header | string | Ate 255 caracteres. Mesma chave + mesmo pedido em 24 h devolve a mesma resposta (Idempotent-Replayed: true); pedido diferente → 422. |
| messageId * | path | string |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/$MESSAGEID" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/readMarcar como lidas
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/read" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":"5511999999999","messageIds":["3EB0C4F1A2B3"]}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/messages/{messageId}/mediaBaixar midia de mensagem recente em base64 (ate 16 MiB)
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| messageId * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/messages/$MESSAGEID/media" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/presencePresenca (digitando, gravando, online)
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/presence" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"typing","to":"5511999999999"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
Webhook e entregas
Configuração do webhook, log de entregas e reenvio (inclusive as em estado dead).
GET/v1/instances/{id}/webhookConfiguracao do webhook (sem o segredo)
Escopo exigido de API key ou token de instancia: `instances:manage`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/webhook" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/webhookConfigurar o webhook; o segredo aparece uma vez
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role).
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/webhook" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://seu-sistema.com.br/webhooks/whatsapp","events":["message.received","message.status"],"rotateSecret":false}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/deliveriesLog de entregas (after/nextCursor)
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/deliveries" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/eventsEventos recebidos sem depender de webhook (after/nextCursor, event, limit)
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/events" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/deliveries/{eventId}Uma entrega
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| eventId * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/deliveries/$EVENTID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/deliveries/{eventId}/retryReenviar entrega (inclusive em estado dead)
Escopo exigido de API key ou token de instancia: `instances:manage`. Sessao do painel: exige papel owner ou admin (member recebe 403 insufficient_role).
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| eventId * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/deliveries/$EVENTID/retry" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
Conversas
Histórico recebido e enviado, paginado por cursor.
GET/v1/instances/{id}/chatsConversas (after/nextCursor)
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/chats/{phone}/settingsEstado sincronizado da conversa
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats/$PHONE/settings" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/chats/{phone}/pinFixar ou desafixar conversa
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats/$PHONE/pin" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled":true}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/chats/{phone}/muteSilenciar ou reativar conversa
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats/$PHONE/mute" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled":true,"durationSeconds":3600}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/chats/{phone}/archiveArquivar ou desarquivar conversa
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats/$PHONE/archive" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled":true}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/chats/{phone}/messagesMensagens de uma conversa (after/nextCursor)
Escopo exigido de API key ou token de instancia: `messages:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/chats/$PHONE/messages" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
Contatos
Contatos, verificação de número e bloqueio.
GET/v1/instances/{id}/contactsContatos
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/contacts/{phone}Contato na agenda sincronizada; found=false nao informa se o numero tem WhatsApp
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/contacts/{phone}Atualizar nome na agenda do WhatsApp
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"fullName":"Maria Silva","firstName":"Maria"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/contacts/{phone}/presence/subscribeAssinar eventos de presenca do contato
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE/presence/subscribe" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/contacts/{phone}/existsNumero tem WhatsApp?
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE/exists" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/contacts/{phone}/pictureFoto do contato
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE/picture" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/contacts/{phone}/blockBloquear
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE/block" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/contacts/{phone}/unblockDesbloquear
Escopo exigido de API key ou token de instancia: `messages:send`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| phone * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/contacts/$PHONE/unblock" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
Grupos
Criar e administrar grupos.
GET/v1/instances/{id}/groupsGrupos
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groupsCriar grupo
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Clientes VIP","participants":["5511999999999"]}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groups/invite/lookupConsultar grupo por convite (codigo no corpo)
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/invite/lookup" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"code":"https://chat.whatsapp.com/CODIGO_DO_CONVITE"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groups/invite/joinEntrar em grupo por link ou mensagem de convite
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/invite/join" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"code":"CODIGO_DO_CONVITE"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/groups/{gid}Um grupo com participantes
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/groups/{gid}/subjectAssunto
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/subject" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"subject":"Clientes VIP 2026"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/groups/{gid}/descriptionDescricao
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/description" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"description":"Avisos e promoções"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/groups/{gid}/pictureFoto do grupo
Escopo exigido de API key ou token de instancia: `contacts:read`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/picture" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/groups/{gid}/pictureTrocar a foto
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/picture" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemplo.com.br/logo.png"}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
PUT/v1/instances/{id}/groups/{gid}/settingsConfiguracoes (announce, locked)
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X PUT "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/settings" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"announce":true,"locked":false}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groups/{gid}/participantsParticipantes (add, remove, promote, demote)
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/participants" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"add","participants":["5511999999999"]}'- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
GET/v1/instances/{id}/groups/{gid}/invite-linkLink de convite (?reset=true gera outro)
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/invite-link" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groups/{gid}/invite-link/resetGerar outro link de convite
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/invite-link/reset" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
POST/v1/instances/{id}/groups/{gid}/leaveSair do grupo
Escopo exigido de API key ou token de instancia: `groups:write`.
Autenticação: API key, token da instância (wai_…) ou sessão do painel
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string | |
| gid * | path | string |
curl -X POST "https://api.zapinapi.duckdns.org/v1/instances/inst_SEU_ID/groups/$GID/leave" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 402 Payment Required · problem+json
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 429 Too Many Requests · problem+json
- 503 Service Unavailable · problem+json
API keys
Chaves da organização (exigem sessão do painel).
GET/v1/api-keysGET /v1/api-keys
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/api-keys" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/api-keysPOST /v1/api-keys
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): name: string, scopes: string[], expiresInDays: integer int32
curl -X POST "https://api.zapinapi.duckdns.org/v1/api-keys" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Minha integração","scopes":["messages:send"],"expiresInDays":90}'- 200 OK
DELETE/v1/api-keys/{id}DELETE /v1/api-keys/{id}
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/api-keys/inst_SEU_ID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/api-keys/{id}/rotatePOST /v1/api-keys/{id}/rotate
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
Corpo (JSON): gracePeriodHours: integer int32
curl -X POST "https://api.zapinapi.duckdns.org/v1/api-keys/inst_SEU_ID/rotate" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"gracePeriodHours":24}'- 200 OK
Assinatura e faturas
Planos, assinatura e faturas (API key com billing:read para leitura).
GET/v1/plansGET /v1/plans
Autenticação: Pública
curl -X GET "https://api.zapinapi.duckdns.org/v1/plans"- 200 OK
GET/v1/subscriptions/currentGET /v1/subscriptions/current
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/subscriptions/current" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/subscriptions/trialPOST /v1/subscriptions/trial
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X POST "https://api.zapinapi.duckdns.org/v1/subscriptions/trial" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/subscriptionsPOST /v1/subscriptions
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): plan: string, quantity: integer int32, name: string, cpfCnpj: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/subscriptions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"plan":"...","quantity":1,"name":"Minha integração","cpfCnpj":"..."}'- 200 OK
PATCH/v1/subscriptionsPATCH /v1/subscriptions
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): plan: string, quantity: integer int32
curl -X PATCH "https://api.zapinapi.duckdns.org/v1/subscriptions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"plan":"...","quantity":1}'- 200 OK
DELETE/v1/subscriptionsDELETE /v1/subscriptions
Cancela a assinatura (no fim do periodo pago, se houver). reason opcional: price, missing_feature, technical_issues, support, no_longer_needed, switched_provider ou other.
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| reason | query | string |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/subscriptions" \
-H "Authorization: Bearer $TOKEN"- 200 OK
GET/v1/invoicesGET /v1/invoices
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/invoices" \
-H "Authorization: Bearer $TOKEN"- 200 OK
GET/v1/invoices/{id}/pixGET /v1/invoices/{id}/pix
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
curl -X GET "https://api.zapinapi.duckdns.org/v1/invoices/inst_SEU_ID/pix" \
-H "Authorization: Bearer $TOKEN"- 200 OK
Organização e equipe
Organização ativa, membros e convites.
GET/v1/organizationGET /v1/organization
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/organization" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/invitations/acceptPOST /v1/invitations/accept
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): token: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/invitations/accept" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"token":"..."}'- 200 OK
POST/v1/auth/switch-organizationPOST /v1/auth/switch-organization
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): organizationId: string uuid, refreshToken: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/switch-organization" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"organizationId":"...","refreshToken":"..."}'- 200 OK
GET/v1/organizations/{id}/membersGET /v1/organizations/{id}/members
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
curl -X GET "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/members" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/organizations/{id}/membersPOST /v1/organizations/{id}/members
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
Corpo (JSON): email: string, role: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/members" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"voce@exemplo.com.br","role":"..."}'- 200 OK
DELETE/v1/organizations/{id}/members/{userId}Remover membro (ou sair da organizacao)
Owner/admin removem outros membros (admin nao remove owner); qualquer membro pode sair. As sessoes do removido nesta organizacao e as API keys que ele criou sao revogadas. Tokens de instancia (wai_) que ele recebeu (criou a instancia ou rotacionou por ultimo) NAO sao rotacionados: a resposta lista essas instancias (public id) para owner/admin rotacionarem com POST /v1/instances/{id}/token.
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid | |
| userId * | path | string uuid |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/members/$USERID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 403 Forbidden · problem+json
- 404 Not Found · problem+json
- 409 Conflict · problem+json
DELETE/v1/organizations/{id}/invitations/{invitationId}DELETE /v1/organizations/{id}/invitations/{invitationId}
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid | |
| invitationId * | path | string uuid |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/invitations/$INVITATIONID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/organizations/{id}/exportPedir exportacao dos dados da organizacao (LGPD; link de uso unico por 24 h)
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid |
curl -X POST "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/export" \
-H "Authorization: Bearer $TOKEN"- 202 Accepted
- 403 Forbidden · problem+json
- 409 Conflict · problem+json
GET/v1/organizations/{id}/exports/{exportId}Estado de uma exportacao (sem o link)
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| id * | path | string uuid | |
| exportId * | path | string uuid |
curl -X GET "https://api.zapinapi.duckdns.org/v1/organizations/inst_SEU_ID/exports/$EXPORTID" \
-H "Authorization: Bearer $TOKEN"- 200 OK
Conta
Usuário, sessões ativas e exclusão de conta.
GET/v1/meGET /v1/me
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/me" \
-H "Authorization: Bearer $TOKEN"- 200 OK
DELETE/v1/meExcluir a conta (LGPD)
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): confirmEmail: string, password: string
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/me" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"confirmEmail":"voce@exemplo.com.br","password":"sua-senha-forte"}'- 204 No Content
- 409 Conflict · problem+json
POST/v1/me/passwordPOST /v1/me/password
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
Corpo (JSON): currentPassword: string, newPassword: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/me/password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"currentPassword":"sua-senha-forte","newPassword":"sua-senha-forte"}'- 200 OK
GET/v1/usageConsumo autorizado por instancia e mes: MCP exige messages:read; API key exige billing:read. from/to = AAAA-MM, padrao mes atual. Inclui registros de instancias excluidas (deleted=true) retidos no consumo; nao sao instancias atuais.
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| from | query | string | |
| to | query | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/usage" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 400 Bad Request · problem+json
- 401 Unauthorized · problem+json
- 403 Forbidden · problem+json
GET/v1/me/sessionsSessoes ativas (dispositivos conectados)
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/me/sessions" \
-H "Authorization: Bearer $TOKEN"- 200 OK
DELETE/v1/me/sessions/{familyId}Encerrar uma sessao
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| familyId * | path | string uuid |
curl -X DELETE "https://api.zapinapi.duckdns.org/v1/me/sessions/$FAMILYID" \
-H "Authorization: Bearer $TOKEN"- 204 No Content
Autenticação
Cadastro, login, renovação e recuperação de senha (usadas pelo painel).
POST/v1/auth/registerPOST /v1/auth/register
Autenticação: Pública
Corpo (JSON): email: string, password: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/register" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"voce@exemplo.com.br","password":"sua-senha-forte"}'- 200 OK
POST/v1/auth/loginPOST /v1/auth/login
Autenticação: Pública
Corpo (JSON): email: string, password: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/login" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"voce@exemplo.com.br","password":"sua-senha-forte"}'- 200 OK
POST/v1/auth/refreshPOST /v1/auth/refresh
Autenticação: Pública
Corpo (JSON): refreshToken: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/refresh" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"refreshToken":"..."}'- 200 OK
POST/v1/auth/logoutPOST /v1/auth/logout
Autenticação: Pública
Corpo (JSON): refreshToken: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/logout" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"refreshToken":"..."}'- 200 OK
POST/v1/auth/logout-allPOST /v1/auth/logout-all
Autenticação: Pública
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/logout-all" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/auth/email/confirmPOST /v1/auth/email/confirm
Autenticação: Pública
Corpo (JSON): token: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/email/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"token":"..."}'- 200 OK
POST/v1/auth/email/resendPOST /v1/auth/email/resend
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/email/resend" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/auth/password/forgotPOST /v1/auth/password/forgot
Autenticação: Pública
Corpo (JSON): email: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/password/forgot" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"voce@exemplo.com.br"}'- 200 OK
POST/v1/auth/password/resetPOST /v1/auth/password/reset
Autenticação: Pública
Corpo (JSON): token: string, newPassword: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/password/reset" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"token":"...","newPassword":"sua-senha-forte"}'- 200 OK
GET/v1/auth/oauth/{provider}/startGET /v1/auth/oauth/{provider}/start
Autenticação: Pública
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| provider * | path | string | |
| redirect_uri | query | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/auth/oauth/$PROVIDER/start" \
-H "Authorization: Bearer $TOKEN"- 200 OK
GET/v1/auth/oauth/{provider}/callbackGET /v1/auth/oauth/{provider}/callback
Autenticação: Pública
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| provider * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/auth/oauth/$PROVIDER/callback" \
-H "Authorization: Bearer $TOKEN"- 200 OK
POST/v1/auth/oauth/{provider}/exchangePOST /v1/auth/oauth/{provider}/exchange
Autenticação: Pública
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| provider * | path | string |
Corpo (JSON): code: string, state: string, codeVerifier: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/oauth/$PROVIDER/exchange" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"code":"...","state":"...","codeVerifier":"..."}'- 200 OK
POST/v1/auth/oauth/link/confirmPOST /v1/auth/oauth/link/confirm
Autenticação: Pública
Corpo (JSON): token: string
curl -X POST "https://api.zapinapi.duckdns.org/v1/auth/oauth/link/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"token":"..."}'- 200 OK
Sistema
Saúde e chaves públicas de verificação do JWT.
GET/healthGET /health
Autenticação: Pública
curl -X GET "https://api.zapinapi.duckdns.org/health"- 200 OK
GET/.well-known/jwks.jsonGET /.well-known/jwks.json
Autenticação: Pública
curl -X GET "https://api.zapinapi.duckdns.org/.well-known/jwks.json"- 200 OK
GET/v1/mcp/identityUsuario conectado: e-mail de quem autorizou esta conexao
Consulta somente o e-mail do proprio usuario autenticado. Sem parametros, sem acesso a outros usuarios e sem exigir permissoes de mensagens. API key e token de instancia nao identificam um usuario conectado. O token do agente continua valido somente no MCP.
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
curl -X GET "https://api.zapinapi.duckdns.org/v1/mcp/identity" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 401 Unauthorized · problem+json
- 403 Forbidden · problem+json
GET/v1/exports/{token}Baixar a exportacao (o token do link e a credencial; uso unico)
Autenticação: Bearer (sessão do painel ou API key, conforme o escopo)
| Parâmetro | Onde | Tipo | Descrição |
|---|---|---|---|
| token * | path | string |
curl -X GET "https://api.zapinapi.duckdns.org/v1/exports/$TOKEN" \
-H "Authorization: Bearer $TOKEN"- 200 OK
- 202 Accepted
- 404 Not Found · problem+json
- 410 Gone · problem+json