PEPINO ZAPdocs
Referência da API

Visão geral

Convenções da API REST do PEPINO ZAP — base URLs e modos teste/produção, autenticação por API key, formato do campo to (E.164/JID), envelope de erro, envio assíncrono e índice de endpoints.

Ver como Markdown

Esta é a referência da API REST do PEPINO ZAP. Com ela o seu sistema conecta números de WhatsApp (instâncias) e envia mensagens de forma programática. Cada endpoint da referência traz exemplos de requisição em várias linguagens e um playground "Try it" para testar a chamada direto na página.

Esta página de visão geral reúne as convenções comuns a toda a API — as regras que valem para qualquer endpoint: como autenticar, em que ambiente você está (teste ou produção), como escrever o destinatário, como o sucesso e o erro são representados e por que o envio é assíncrono. Leia-a uma vez antes de mergulhar nos endpoints; ela evita a maioria dos tropeços de integração.

Se você ainda não gerou uma API key nem conectou um número, comece pelos guias passo a passo: Autenticação (criar a conta e gerar a key) e Sua primeira instância (conectar um número via QR Code). Esta página é a referência das convenções; aqueles guias são o caminho guiado.

Antes de começar: os três pré-requisitos

Para uma chamada de uso real (criar instância ou enviar mensagem) ser aceita, três coisas precisam estar certas ao mesmo tempo:

  1. API key válida no header Authorization (veja Autenticação). Sem ela: 401.
  2. Host correto para o modo da key — o host sandbox.* é Teste e exige pzk_test_; o host api.* é Produção e exige pzk_live_. Key e host têm que casar. Se não casarem: 401.
  3. Plano ativo no Projeto (só em Produção) — criar instâncias e enviar mensagens exigem assinatura ativa. Sem ela: 402. No modo Teste é grátis (com teto diário).

Leitura (listar/detalhar), pareamento por QR Code e "marcar como lida" só exigem os pré-requisitos 1 e 2 — não dependem de plano.

Base URL e o prefixo /v1

Todas as rotas vivem sob o prefixo /v1. A URL completa de um endpoint é sempre <BASE_URL>/v1/<caminho>. A base URL define em qual modo (Teste ou Produção) você está operando:

ModoBase URLPrefixo da keyCobrança
Teste (sandbox)https://sandbox.pepinozap.com.brpzk_test_grátis, com teto de 100 mensagens/dia por Projeto
Produção (live)https://api.pepinozap.com.brpzk_live_exige plano ativo

É o host que decide o modo: qualquer host que comece com sandbox é Teste; os demais (api.*) são Produção. A API key não decide o modo — ela apenas precisa ser coerente com o host. Por isso uma pzk_test_ chamando api.* (ou uma pzk_live_ chamando sandbox.*) é rejeitada com 401, mesmo sendo uma key real e válida.

# Teste (sandbox) — key pzk_test_
curl https://sandbox.pepinozap.com.br/v1/instances \
  -H "Authorization: Bearer pzk_test_xxxxxxxxxxxxxxxx"

# Produção (live) — key pzk_live_
curl https://api.pepinozap.com.br/v1/instances \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx"

Os dois modos são 100% isolados: instâncias, conversas e webhooks criados em Teste nunca aparecem em Produção e vice-versa. Inclusive um id de instância de um modo, usado no outro modo, retorna 404 (não vaza entre ambientes). Valide a integração inteira em sandbox.* sem custo e, quando estiver pronto, troque a base URL para api.* e a key para pzk_live_ — o resto do código permanece igual.

Autenticação

Toda chamada envia a API key no header Authorization com o esquema Bearer:

Authorization: Bearer <API_KEY>

A key é escopada a um Projeto: todas as instâncias e mensagens criadas ou listadas com ela pertencem a esse Projeto. A geração é self-service no painel (Integrações → API Keys), e a key crua aparece uma única vez na criação. Detalhes de cadastro, do toggle Teste/Produção e de revogação estão em Autenticação.

Exceção — SSE de QR Code. O único endpoint que não usa o header é o stream de QR Code via Server-Sent Events (GET /v1/instances/{id}/qr), porque o EventSource do navegador não envia headers customizados. Nele a key vai pela query string, ?token=<API_KEY>. Recomenda-se emitir um token efêmero (POST /v1/instances/{id}/qr-token, válido ~2 min) para não expor a key crua na URL. Todos os demais endpoints — inclusive o polling de QR (/qr/poll) — usam o header normalmente. Veja Autenticação → Fallback ?token= e Sua primeira instância → Parear via QR Code.

Formato do campo to

Todos os endpoints de mensagem identificam o destinatário pelo campo to. Ele aceita três formatos, todos equivalentes — use o que for mais conveniente:

FormatoExemploObservação
Apenas dígitos (E.164 sem +)5511999999999Forma mais simples; recomendada.
E.164 com ++5511999999999O + é aceito.
JID completo5511999999999@s.whatsapp.netForma "nativa" do WhatsApp.

O número deve incluir código do país e DDD, sem espaços, traços ou parênteses. Para o Brasil, o código do país é 55.

A API não verifica, no momento do envio, se o número existe no WhatsApp — a validação só confirma que o campo to não está vazio. Um to com número inexistente é aceito e enfileirado (resposta 202), mas a mensagem simplesmente não é entregue, e não há evento de falha por número inválido. Garanta que o to está correto antes de enviar. Para envio a grupos, use o JID de grupo recebido nos webhooks; este guia trata de conversas individuais (1:1).

Convenções de requisição e resposta

  • Método e corpo. Endpoints de escrita usam POST/PATCH/DELETE; os de leitura usam GET. Requisições com corpo JSON exigem o header Content-Type: application/json (a exceção é o upload de mídia por arquivo, que é multipart/form-data).
  • Formato. Pedidos e respostas são JSON (UTF-8), salvo o SSE de QR (text/event-stream) e o upload de mídia (multipart).
  • Códigos de sucesso por tipo de operação:
OperaçãoSucessoCorpo da resposta
Criar instância (POST /v1/instances)201 CreatedA instância criada (objeto completo).
Detalhar / listar / atualizar settings200 OKA instância (ou a lista).
Remover instância (DELETE)204 No ContentSem corpo.
Enviar qualquer tipo de mensagem202 AcceptedConfirmação de enfileiramento (veja abaixo).
  • Confirmação de envio. Os endpoints de envio respondem com um objeto curto que confirma o enfileiramento, não a entrega:
{
  "queued": true,
  "to": "5511999999999"
}

Endpoints de mídia e sticker incluem também o campo type (ex.: "type": "image"). O to ecoado é exatamente o que você enviou.

Envio assíncrono (202) e idempotência

O envio de mensagens é assíncrono. A resposta 202 Accepted confirma apenas que a mensagem foi enfileirada — não que foi entregue nem lida. O processamento real (envio ao WhatsApp) ocorre logo em seguida, em segundo plano. A confirmação de entrega e leitura chega depois pelo evento message.status no webhook.

A instância precisa estar CONNECTED para a mensagem sair. Enviar para uma instância que não está conectada (por exemplo, DISCONNECTED ou aguardando QR) também retorna 202 — mas a mensagem fica em espera e não é entregue, sem gerar evento de falha. Confirme status == CONNECTED (via GET /v1/instances/{id} ou GET /v1/instances/{id}/qr/poll com connected == true) antes de enviar. Instâncias em estado terminal (BANNED/ERROR) são bloqueadas já no envio, com 409 (veja a tabela de erros).

Idempotência. Os endpoints de envio não são idempotentes: cada chamada enfileira um novo envio. Se a sua requisição falhar com erro de rede ou timeout depois de a API ter aceitado o job, repeti-la pode resultar em mensagem duplicada. Para reenviar com segurança, controle a deduplicação no seu lado (por exemplo, só repita quando tiver certeza de que a chamada anterior não retornou 202). Já os erros 402 (plano/créditos), 401, 403, 404, 409 e 429 são respostas de negócio/validação — não os repita em loop: corrija a causa (assinar, recarregar, conectar a instância, corrigir a key) e tente de novo.

Envelope de erro

Toda resposta de erro segue um envelope único e estável:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "campos to e body são obrigatórios"
  }
}

O campo code identifica a categoria de forma estável — programe o seu tratamento de erros em cima dele. O campo message é apenas legível por humanos (em português) e pode mudar; não faça parsing nem switch sobre a message, com uma exceção prática anotada na tabela (o 402 de plano vs. créditos).

StatuscodeSignificado
400BAD_REQUESTCorpo JSON inválido ou campo obrigatório faltando/ inválido (ex.: to vazio, type de mídia inválido).
401UNAUTHORIZEDAPI key ausente, inválida, ou do modo errado para o host (pzk_live_ no sandbox, ou vice-versa).
402PAYMENT_REQUIREDSem plano ativo ou sem créditos da API (ver abaixo). Distinga os dois casos pela message. Não repita a chamada — exige ação humana (assinar/recarregar).
403FORBIDDENProjeto inativo ou sem permissão.
404NOT_FOUNDRecurso não encontrado no Projeto da key — inclui o caso de a instância existir, mas pertencer a outro modo (teste/produção) ou a outro Projeto.
409CONFLICTAo criar instância: cota de números do plano atingida. Ao enviar: instância não-operacional (BANNED ou ERROR).
429RATE_LIMITEDApenas no sandbox: teto diário do Projeto atingido (100 mensagens/dia por Projeto, enviadas + recebidas; o contador zera à meia-noite no horário de São Paulo). Em produção não ocorre.
5xxINTERNAL_ERRORFalha inesperada do servidor. Em geral é transitória — pode ser repetida com recuo (backoff).

O 404 é deliberadamente "cego" ao motivo: tentar acessar uma instância de outro modo (ex.: um id de produção usando a base URL de sandbox) ou de outro Projeto retorna 404, e não um 403. Isso evita vazar a existência de recursos entre Projetos e entre ambientes. Se um id que você "tem certeza" que existe dá 404, confira primeiro se a base URL e o prefixo da key batem com o modo em que a instância foi criada.

Pré-requisito: plano ativo (402)

Além da API key, o Projeto precisa de uma assinatura ativa para criar instâncias e enviar mensagens em produção. Sem plano ativo, esses endpoints retornam 402 (PAYMENT_REQUIRED):

{
  "error": {
    "code": "PAYMENT_REQUIRED",
    "message": "É necessário um plano ativo para usar este recurso. Assine em \"Meu plano\"."
  }
}

Endpoints que exigem plano ativo (em produção):

  • POST /v1/instances — criar instância
  • POST /v1/instances/{id}/messages e todos os demais envios (/media, /media-upload, /location, /contact, /sticker, /reaction, /poll)

Endpoints de leitura (listar/detalhar instâncias), o pareamento por QR Code (SSE, polling e emissão de token) e o marcar como lida (/messages/read) continuam liberados mesmo sem plano.

Modo Teste é grátis. Em sandbox.* a assinatura não é exigida — você só esbarra no teto diário (429). Use o sandbox para validar a integração inteira sem custo.

Créditos da API (também 402). Projetos no modo API consomem créditos pré-pagos a cada mensagem enviada pela API key (envios pelo painel/inbox não consomem). Quando o saldo zera, os endpoints de envio retornam o mesmo 402 PAYMENT_REQUIRED, mas com a message indicando créditos insuficientes (ex.: "créditos da API insuficientes — recarregue em Meu plano"). É por isso que, para o 402, a message é o único sinal que distingue os dois casos: falta de plano versus falta de créditos.

A resolução de ambos (assinar ou recarregar) é em Meu plano, no painel — é um gate de negócio que exige ação humana, não repita a chamada. Projetos de cortesia (isentos, marcados pelo time PEPINO) nunca recebem este erro. Detalhes em Autenticação → Plano ativo.

Como navegar a referência

Os endpoints abaixo agrupam-se em quatro áreas. Cada link leva à página do endpoint, com todos os campos, exemplos por linguagem e o playground "Try it".

Instâncias

Conectar e gerenciar os números de WhatsApp do Projeto.

OperaçãoMétodo e caminhoReferência
Listar instânciasGET /v1/instanceslistInstances
Criar instânciaPOST /v1/instancescreateInstance
Detalhar instânciaGET /v1/instances/{id}getInstance
Atualizar configuraçõesPATCH /v1/instances/{id}/settingsupdateInstanceSettings
Remover instânciaDELETE /v1/instances/{id}deleteInstance
Parear via QR Code (SSE)GET /v1/instances/{id}/qrstreamInstanceQR
Parear via QR Code (polling)GET /v1/instances/{id}/qr/pollpollInstanceQR
Token efêmero para o SSE de QRPOST /v1/instances/{id}/qr-tokencreateQrToken

O ciclo de vida da instância e o pareamento estão detalhados em Sua primeira instância.

Mensagens

Todos os envios são por POST /v1/instances/{id}/messages/..., respondem 202 e são assíncronos.

TipoCaminhoReferência
TextoPOST .../messagessendTextMessage
Mídia (por URL)POST .../messages/mediasendMediaMessage
Mídia (upload de arquivo)POST .../messages/media-uploadsendMediaUpload
LocalizaçãoPOST .../messages/locationsendLocationMessage
ContatoPOST .../messages/contactsendContactMessage
StickerPOST .../messages/stickersendStickerMessage
ReaçãoPOST .../messages/reactionsendReactionMessage
EnquetePOST .../messages/pollsendPollMessage
Marcar como lidaPOST .../messages/readmarkMessagesRead

Notas úteis: em mídia, o campo type aceita image, video, audio ou document, e um áudio com ptt: true vira nota de voz; em reação, emoji vazio remove a reação; em enquete, options deve ter de 2 a 12 alternativas. Os campos exatos de cada tipo estão na página da referência correspondente.

Webhooks

O integrador recebe eventos (mensagem recebida, status de envio e status da instância) em uma URL própria, cadastrada via API (self-service):

OperaçãoMétodo e caminhoReferência
Cadastrar webhookPOST /v1/webhookscreateWebhook
Listar webhooksGET /v1/webhookslistWebhooks
Remover webhookDELETE /v1/webhooks/{id}deleteWebhook

O formato do payload, a assinatura HMAC e a lista de eventos estão em Webhooks. Para receber eventos em tempo real por conexão persistente em vez de HTTP, veja também o WebSocket.

Inbox (CRM)

Consultar as conversas e mensagens armazenadas pela plataforma e gerir o atendimento (status, atribuição):

OperaçãoMétodo e caminhoReferência
Listar conversasGET /v1/inbox/conversationslistInboxConversations
Detalhar conversaGET /v1/inbox/conversations/{id}getInboxConversation
Listar mensagens da conversaGET /v1/inbox/conversations/{id}/messageslistInboxMessages
Mudar status (encerrar/reabrir)POST /v1/inbox/conversations/{id}/statussetConversationStatus
Atribuir a um atendentePOST /v1/inbox/conversations/{id}/assignassignConversation

Gestão (CRM)

As ferramentas de gestão do atendimento. O modelo de dados e o passo a passo de cada uma estão no guia CRM e gestão:

ÁreaO que fazReferência
RelatóriosMétricas agregadas do atendimentogetReportsSummary · guia
EtiquetasClassificar e filtrar conversaslistLabels · guia
JustificativasMotivos de encerramentolistCloseReasons
FluxosConstrutor de chatbot por númerolistFlows · guia
FunilFunil cujas etapas são regras sobre a conversalistFunnels · guia

Próximos passos

On this page