PEPINO ZAPdocs
Comece aqui

Autenticação

Como criar a conta, gerar e revogar API keys (self-service), os modos teste/produção (host sandbox./api. + prefixo pzk_test_/pzk_live_ que casam), o header Authorization, o fallback ?token= para SSE e todos os erros (401, 402, 403, 429).

Ver como Markdown

Toda requisição à API do PEPINO ZAP é autenticada por uma API key, escopada a um Projeto. A key identifica quem está chamando e a qual Projeto pertence: todas as instâncias, conversas e mensagens criadas ou listadas com uma key pertencem ao Projeto dela. Não há login/senha nas chamadas de API — só a key, enviada em cada requisição.

A geração de keys é self-service: você cria e revoga quantas quiser pelo painel, sem depender da autorização de um operador. Esta página cobre o fluxo completo, ponta a ponta:

  1. Criar a conta e confirmar o e-mail.
  2. Escolher o modo (teste ou produção) e gerar a key.
  3. Enviar a key nas requisições (header Authorization).
  4. O caso especial do SSE de QR Code (fallback ?token=).
  5. Todos os erros que a autenticação pode retornar (401, 402, 403, 429) e como resolver cada um.

Resumo em uma frase: o host decide o modo (sandbox.* = teste, api.* = produção) e a key tem que casar com ele (pzk_test_ no sandbox, pzk_live_ na produção). Key no host errado retorna 401.

Criando a conta e gerando keys

A conta e as keys nascem no painel. O fluxo abaixo é feito uma vez; depois você só gera/revoga keys conforme precisar.

  1. Cadastre-se (empresa, CNPJ, e-mail e senha) em app.pepinozap.com.br. O cadastro exige confirmação de e-mail — você recebe um link logo após o envio do formulário.
  2. Confirme o e-mail pelo link enviado. O login só é liberado depois da confirmação — antes disso, tentar entrar não funciona.
  3. Faça login no painel e vá em Integrações → API Keys. No topo de Integrações há um toggle Teste / Produção — escolha o modo desejado antes de gerar a key.
  4. Clique em gerar, dê um nome à key (ele só serve para você identificá-la na lista — não aparece para ninguém) e, opcionalmente, defina uma validade.

A key crua aparece uma única vez, no momento da criação. Guarde-a em local seguro (um gerenciador de segredos, uma variável de ambiente do seu servidor). Não há como recuperá-la depois — o painel só guarda um hash e um prefixo de exibição. Se você perder a key, revogue-a e crie outra.

O modo da key é o do toggle no momento em que ela foi gerada e fica gravado nela para sempre:

  • toggle em Teste → key começa com pzk_test_;
  • toggle em Produção → key começa com pzk_live_.

O nome da key é obrigatório. Gerar sem nome retorna 400 com a mensagem "nome obrigatório (identifica a key na listagem)". Escolha algo que diga onde a key é usada (ex.: backend-producao, integracao-erp) — isso facilita revogar a certa depois.

Anatomia de uma API key

Uma key crua tem a forma pzk_<modo>_<segredo>, por exemplo:

pzk_test_k4m2qz7r3v8n6t1p9s5w0xab
└──┬───┘ └──────────┬───────────┘
 prefixo          segredo (aleatório)
  • Prefixo (pzk_test_ ou pzk_live_): indica o modo. É por ele que a API decide, logo de cara, se a key combina com o host.
  • Segredo: parte aleatória de alta entropia. É o que você não deve expor. O painel mostra apenas um prefixo de exibição (o prefixo do modo + os 6 primeiros caracteres do segredo) para você reconhecer a key na lista sem revelá-la inteira.

Modos: teste e produção

Uma única conta, com dois modos — no mesmo espírito do test/live do Stripe. Não há conta nem ambiente separado: é a mesma conta, os mesmos logins. O que muda é o modo da requisição, e o modo é definido pelo host da API. A key tem que casar com o host, mas não é ela que decide o modo.

ModoBase URL da APIPrefixo da keyCobrança
Testehttps://sandbox.pepinozap.com.brpzk_test_grátis, com teto diário
Produçãohttps://api.pepinozap.com.brpzk_live_exige plano ativo

O host decide o modo; a key tem que casar

O modo é resolvido pelo hostname da URL que você chama:

  • host que começa com sandbox (sandbox.pepinozap.com.br) → modo teste;
  • qualquer outro host (api.pepinozap.com.br) → modo produção.

Depois de resolver o modo pelo host, a API confere o prefixo da key: ela precisa ser do mesmo modo. As combinações válidas e inválidas:

HostKeyResultado
sandbox.pepinozap.com.brpzk_test_...OK (modo teste)
api.pepinozap.com.brpzk_live_...OK (modo produção)
sandbox.pepinozap.com.brpzk_live_...401 — key do modo errado
api.pepinozap.com.brpzk_test_...401 — key do modo errado

Quando o prefixo não casa com o host, a resposta é 401 UNAUTHORIZED com a mensagem "chave de API inválida para este ambiente/modo". Esse erro é, na prática, o engano mais comum: usar uma key de teste apontando para api.*, ou vice-versa. Antes de investigar qualquer outra coisa, confirme que o prefixo da key bate com o host.

Isolamento de dados por modo

Os dados são isolados por modo. Instâncias, conversas e webhooks criados em Teste nunca aparecem em Produção, e vice-versa. Consequências práticas:

  • Uma instância criada no sandbox não existe em produção (consultá-la lá dá 404).
  • Listar keys/instâncias retorna apenas as do modo da requisição.
  • No painel, o toggle filtra o que você vê em Integrações. O CRM (Inbox, Funil) é sempre Produção.

Se um GET por id retornar 404 ("instância não encontrada") mesmo você "tendo certeza" de que ela existe, verifique se não está chamando o host do modo errado. Recurso de teste só aparece no sandbox.*; recurso de produção só no api.*.

Teste é grátis; produção exige plano

O modo teste é grátis e self-service: criar instâncias e enviar mensagens não exigem plano ativo — você valida a integração inteira sem assinar nada. Para que o teste grátis não vire "produção de graça", ele tem um teto diário de 100 mensagens por dia, por Projeto (enviadas + recebidas; o dia fecha à meia-noite no fuso de São Paulo). Ao ultrapassar o teto, os envios retornam 429 RATE_LIMITED.

A produção exige uma assinatura ativa no Projeto para as ações de uso real (conectar número, enviar mensagem) — é o 402 detalhado mais abaixo. Resumindo: teste à vontade no sandbox e só pague ao ir para produção.

Gerando keys pela API (self-service)

Além do botão no painel, você pode gerar, listar e revogar keys pela API, sob o grupo /v1/keys. Isso é útil para automatizar a rotação de chaves.

Gerenciar keys exige login de usuário (a sessão do painel, um token de usuário) — uma API key não pode gerar outras. Se você chamar /v1/keys autenticando com uma pzk_..., recebe 403 com "gestão de chaves requer login de usuário". Isso é proposital: limita o estrago caso uma key vaze (ela não consegue se "auto-multiplicar"). Os exemplos desta seção assumem o token de usuário do painel no Authorization.

Obtendo o token de usuário — POST /v1/auth/login

No navegador, a sessão do painel vive em cookies httpOnly (o token não é exposto ao JavaScript). Para automatizar a rotação de keys do seu backend, chame o login server-to-server pedindo o token no corpo com o header X-Token-Response: body:

curl -X POST https://api.pepinozap.com.br/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Token-Response: body" \
  -d '{ "email": "voce@empresa.com", "password": "sua-senha" }'

Resposta 200 OK com accessToken (curto) e refreshToken. Use o accessToken como Bearer <TOKEN_DE_USUARIO> nos exemplos abaixo. Sem esse header, o login responde só com a sessão em cookie (o fluxo do painel) — nunca chame o login com credencial de usuário a partir do navegador de uma página pública.

Criar uma key — POST /v1/keys

Corpo da requisição:

CampoTipoObrigatórioDescrição
namestringsimIdentifica a key na listagem. Não pode ser vazio.
expiresInDaysnúmeronãoValidade em dias a partir de agora (inteiro >= 1). Sem este campo, a key não expira.

O modo da key gerada (e portanto o prefixo pzk_test_/pzk_live_) segue o modo da requisição — no painel/API de usuário, o toggle Teste/Produção.

curl -X POST https://api.pepinozap.com.br/v1/keys \
  -H "Authorization: Bearer <TOKEN_DE_USUARIO>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "backend-producao", "expiresInDays": 90 }'

Resposta 201 Created — repare no campo key com a key crua (aparece só aqui, uma vez):

{
  "id": "key_abc123",
  "name": "backend-producao",
  "keyPrefix": "pzk_live_k4m2qz",
  "status": "active",
  "lastUsedAt": null,
  "expiresAt": "2026-09-03T12:00:00Z",
  "revokedAt": null,
  "createdAt": "2026-06-05T12:00:00Z",
  "key": "pzk_live_k4m2qz7r3v8n6t1p9s5w0xab"
}
  • key — a key crua completa. Guarde-a agora; ela não volta a aparecer.
  • keyPrefix — o prefixo de exibição (modo + 6 caracteres), seguro de logar/mostrar.
  • statusactive, revoked ou expired, derivado de revokedAt/expiresAt.
  • expiresAtnull se você não enviou expiresInDays.

Criar uma key em produção exige plano ativo (gerar key = habilitar uso via integração). Sem assinatura, POST /v1/keys retorna 402 (PAYMENT_REQUIRED). Em teste, gerar keys é livre. Ver Plano ativo (erro 402).

Listar suas keys — GET /v1/keys

Retorna apenas as keys do modo atual (o toggle Teste/Produção filtra). A key crua não é incluída — só metadados.

curl https://api.pepinozap.com.br/v1/keys \
  -H "Authorization: Bearer <TOKEN_DE_USUARIO>"

Resposta 200 OK:

{
  "items": [
    {
      "id": "key_abc123",
      "name": "backend-producao",
      "keyPrefix": "pzk_live_k4m2qz",
      "status": "active",
      "lastUsedAt": "2026-06-05T13:40:00Z",
      "expiresAt": "2026-09-03T12:00:00Z",
      "revokedAt": null,
      "createdAt": "2026-06-05T12:00:00Z"
    }
  ]
}

O campo lastUsedAt ajuda a identificar keys ociosas (candidatas a revogar). Ele é atualizado de forma assíncrona a cada uso, então pode levar alguns instantes para refletir a última chamada.

Revogar uma key — DELETE /v1/keys/{id}

Revoga imediatamente a key indicada (use o id, não o keyPrefix). A partir daí, qualquer requisição com aquela key retorna 401.

curl -X DELETE https://api.pepinozap.com.br/v1/keys/key_abc123 \
  -H "Authorization: Bearer <TOKEN_DE_USUARIO>"

Sucesso: 204 No Content (sem corpo). Se o id não existir, não for do seu Projeto, ou for de outro modo, a resposta é 404 ("chave não encontrada").

A revogação é definitiva e não tem desfazer. Não dá para "reativar" uma key revogada — gere uma nova. Por isso, ao trocar uma chave em produção, gere a nova e atualize sua aplicação primeiro, e só então revogue a antiga, evitando uma janela sem key válida.

Como enviar a API key

Em todas as chamadas REST, envie a key no header Authorization com o esquema Bearer:

curl https://sandbox.pepinozap.com.br/v1/instances \
  -H "Authorization: Bearer pzk_test_xxxxxxxxxxxxxxxx"

Exemplo com fetch (JavaScript):

const res = await fetch('https://sandbox.pepinozap.com.br/v1/instances', {
  headers: {
    Authorization: 'Bearer pzk_test_xxxxxxxxxxxxxxxx',
  },
});

Pontos de atenção ao montar o header:

  • O esquema Bearer (com um espaço) é obrigatório. Mandar a key "pelada", sem Bearer, é tratado como ausência de Authorization → 401.
  • A key não vai na URL nem no corpo — só no header (exceção: o SSE de QR, a seguir).
  • Use sempre HTTPS. A key é um segredo de acesso total ao Projeto.

Fallback ?token= (apenas para SSE)

O endpoint de QR Code via stream (GET /v1/instances/{id}/qr) usa Server-Sent Events. O EventSource do navegador não envia headers customizados, então não há como mandar o Authorization nesse caso. Para esse endpoint — e somente para ele — a API aceita a credencial na query string, no parâmetro ?token=.

Há duas formas de preencher o ?token=:

  1. A própria key crua (mais simples). Funciona, mas coloca a key na URL:

    curl -N "https://sandbox.pepinozap.com.br/v1/instances/{id}/qr?token=pzk_test_xxxxxxxxxxxxxxxx"
  2. Um token efêmero de SSE (recomendado para o navegador). Gere com POST /v1/instances/{id}/qr-token e use o token retornado no ?token=. Esse token é curto (validade ~2 min) e escopado a uma única instância (só vale na rota de QR daquela instância), limitando o impacto se vazar em um log ou no Referer.

const id = 'inst_...';
const token = 'pzk_test_xxxxxxxxxxxxxxxx'; // ou o token efêmero de qr-token

const source = new EventSource(
  `https://sandbox.pepinozap.com.br/v1/instances/${id}/qr?token=${token}`,
);

Utilize ?token= exclusivamente no endpoint SSE de QR. Nas demais chamadas, use sempre o header Authorization — a query string aparece em logs de servidor, proxies e no Referer, então expor a key crua ali é arriscado. Para o QR no navegador, prefira o token efêmero de qr-token justamente por isso. O passo a passo do pareamento está em Sua primeira instância.

Erros esperados

Todos os erros da API seguem o mesmo envelope:

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "explicação legível do que aconteceu"
  }
}
  • code — rótulo estável, derivado do status HTTP. Use-o para tratar o erro no seu código (é mais confiável que comparar a message).
  • message — texto legível, em português, que diz o que deu errado.

Os status que a autenticação pode retornar:

StatuscodeQuando ocorre
401UNAUTHORIZEDKey ausente, malformada, inválida, revogada, expirada, ou do modo errado para o host.
402PAYMENT_REQUIREDO Projeto não tem plano ativo (ou créditos da API zerados). Ver Plano ativo.
403FORBIDDENProjeto inativo (key válida, mas o Projeto não está ACTIVE); ou gestão de keys tentada sem login de usuário.
429RATE_LIMITEDApenas no modo teste: teto diário do Projeto atingido (100 mensagens/dia, enviadas + recebidas). Em produção não ocorre.

Detalhando o 401 UNAUTHORIZED

O 401 cobre várias causas. A message distingue cada uma — vale tratá-las separadamente ao depurar:

messageCausaComo resolver
Authorization Bearer ou ?token= ausenteNenhuma credencial foi enviada (faltou o header, ou veio sem Bearer).Envie Authorization: Bearer <key>.
chave de API inválida para este ambiente/modoO prefixo da key não bate com o host (pzk_live_ no sandbox ou pzk_test_ na produção).Use a key do modo correto para o host (ver O host decide o modo).
token ou chave de API inválidoA key não corresponde a nenhuma key existente (digitada errada, truncada, ou inexistente).Confira se copiou a key inteira. Se perdeu a key, gere outra.
chave de API revogadaA key foi revogada (no painel ou via DELETE /v1/keys/{id}).Gere uma key nova.
chave de API expiradaA key passou da validade definida em expiresInDays.Gere uma key nova (sem expiresInDays, ou com prazo maior).

Exemplo de resposta 401:

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "chave de API inválida para este ambiente/modo"
  }
}

Há um 401 específico do painel (login de usuário), não da API key: o code SESSION_SUPERSEDED, emitido quando a mesma conta é aberta em outro dispositivo (a sessão única invalida a anterior). API keys não têm sessão e nunca recebem esse erro — ele só aparece em chamadas autenticadas com o token de usuário do painel. Ao recebê-lo, faça login de novo.

O 403 FORBIDDEN

O 403 significa que a credencial é válida, mas a ação não é permitida no estado atual:

  • Projeto inativo — a key é reconhecida, mas o Projeto dela não está com status ACTIVE (suspenso, por exemplo). message: "projeto não está ativo". A regularização é feita pelo time PEPINO; entre em contato.
  • Gestão de keys sem login de usuário — você tentou /v1/keys autenticando com uma API key em vez do token de usuário. message: "gestão de chaves requer login de usuário". Use a sessão do painel.

Exemplo de resposta 403:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "projeto não está ativo"
  }
}

Plano ativo (erro 402)

Ter uma API key válida não basta para operar em produção. As ações de uso real — conectar um número e enviar mensagens — exigem uma assinatura ativa no Projeto (modelo "pague antes, use depois"). Como a key é escopada a um Projeto, a regra vale igualmente para o painel e para a integração via API. No modo teste, esse erro nunca ocorre (teste é grátis).

Só a assinatura com status active libera. Qualquer outro estado (sem assinatura, pending, paused, past_due, canceled) resulta em 402.

Endpoints que retornam 402 sem plano ativo (em produção):

  • POST /v1/instances — criar instância;
  • POST /v1/instances/{id}/messages e os demais envios sob /v1/instances/{id}/messages/ (/media, /media-upload, /location, /contact, /sticker, /reaction, /poll);
  • POST /v1/keys — gerar API key (habilitar uso via integração).

Endpoints de leitura (listar/detalhar instâncias e keys), o pareamento por QR Code e marcar como lida continuam liberados mesmo sem plano ativo — você consegue inspecionar o estado, mas não produzir tráfego.

Exemplo de resposta 402:

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

Como resolver: assine um plano em Meu plano, no painel. Assim que a assinatura fica active, as chamadas voltam a funcionar sem alterar uma linha de código — não é preciso gerar nova key. Projetos de cortesia, marcados como isentos pelo time PEPINO, nunca recebem este erro.

Créditos da API insuficientes

Além da falta de plano, o 402 também aparece por créditos zerados. Projetos no modo API consomem créditos pré-pagos a cada mensagem enviada pela API (envios feitos pelo painel não consomem créditos). Quando o saldo zera, os endpoints de envio passam a retornar 402 com code PAYMENT_REQUIRED, e a message indica créditos insuficientes.

A resolução é recarregar créditos em Meu plano. Distinga os dois casos 402 pela message: falta de plano ativo (texto sobre assinar) versus falta de créditos (texto sobre recarregar) — a ação a tomar é diferente em cada um.

Add-on de campanhas (disparo em massa)

As rotas de campanhas (/v1/campaigns, criação/disparo) têm uma exigência extra: além do plano ativo, o Projeto precisa do add-on "Disparo em massa". Sem ele, criar/disparar campanha retorna 402 com a mensagem orientando a ativar o add-on em Meu plano. Leitura de campanhas é livre, e no modo teste o add-on não é exigido. (Detalhes na documentação de campanhas.)

Boas práticas de segurança

  • Trate a key como senha. Quem tiver a key tem acesso total ao Projeto. Não a coloque em repositórios, front-end, prints ou tickets de suporte.
  • Use variáveis de ambiente / cofre de segredos no servidor — nunca hardcode a key no código.
  • Uma key por integração. Dê nomes claros (ex.: backend-prod, worker-fila). Assim, se uma vazar, você revoga só ela sem derrubar as outras.
  • Defina validade (expiresInDays) em keys de vida curta (scripts, testes pontuais) para que expirem sozinhas.
  • Rotacione com janela de transição: gere a nova key, atualize a aplicação, confirme que funciona e só então revogue a antiga.
  • Comece pelo modo teste. Valide a integração inteira no sandbox.* com uma pzk_test_ antes de gerar a pzk_live_ e ligar a produção.

Próximos passos

On this page