# Introdução (/docs)





O PEPINO ZAP é uma **API REST** que permite conectar números de WhatsApp ao seu sistema e enviar e receber mensagens de forma programática. Você cria **instâncias**, pareia cada uma a um aparelho via **QR Code** e, a partir daí, envia mensagens de texto e mídia por requisições HTTP e recebe os eventos de entrada e de status por **webhook** ou **WebSocket**. Além do transporte, a plataforma é o **system of record** das suas conversas — ela **guarda o histórico** (mensagens + mídia hospedada; você lê pela API, sem banco próprio) e expõe uma camada de **Inbox/CRM** (etiquetas, atribuição a atendentes, funil, relatórios) pela mesma key.

Esta página é o seu mapa mental antes de ir para os guias: o que a API faz, como os recursos se organizam (Organização → Projeto → Instância), a diferença entre os modos **teste** e **produção**, como autenticar e quais pré-requisitos liberam o uso real. Se você é novo por aqui, leia até o fim — cada conceito é retomado nos guias com exemplos prontos para copiar.

<Callout type="info">
  **Integrando com auxílio de IA?** Baixe toda a documentação — guias e a especificação OpenAPI
  completa — em um [único arquivo Markdown](/llms-full.md). É autocontido: cole o conteúdo em uma IA
  e ela tem tudo o que precisa para montar a integração, sem você copiar página por página.
</Callout>

## O que você consegue fazer [#o-que-você-consegue-fazer]

Com uma única API key você cobre todo o ciclo de uma conversa de WhatsApp — do envio à gestão do atendimento:

1. **Conectar um número** — crie uma instância e pareie-a com um aparelho lendo um QR Code (como o "Aparelhos conectados" do WhatsApp).
2. **Enviar mensagens** — texto, mídia (imagem, vídeo, áudio, documento), localização, contato, sticker, reação e enquete, por chamadas HTTP.
3. **Receber mensagens e status** — mensagens de entrada e confirmações de entrega/leitura chegam por **webhook** (entrega garantida, com retry) ou **WebSocket** (tempo real, sem endpoint público).
4. **Ler o histórico** — conversas, mensagens e mídia ficam persistidas na nossa infraestrutura; você **lista e pagina pela API** (`GET /v1/inbox/conversations` e `.../conversations/{id}/messages`, com cursor) quando precisar — sem manter banco próprio.
5. **Gerir o atendimento (CRM)** — além do transporte, a plataforma expõe um **Inbox** completo pela mesma key: **etiquetas**, **atribuição** a atendentes, **status** e **motivos de encerramento**, **funil de vendas** e **relatórios** de gestão.

Como a plataforma é o *system of record* das suas conversas, **você não precisa manter banco de dados nem storage de mídia próprios** só para o WhatsApp — ler do histórico pela API é suficiente para a maioria das integrações. Os metadados de atendimento (etiquetas, atribuição, funil) também vivem aqui. Detalhes em [Persistência e histórico](/docs/get-started/persistencia) e na [Referência da API](/docs/api) (seções **Inbox** e **Gestão**).

## Modelo de recursos [#modelo-de-recursos]

Os recursos seguem uma hierarquia de três níveis. Para integrar, na prática você trabalha sempre no nível do **Projeto** — é a ele que sua API key está amarrada.

| Recurso         | O que é                                                                                                                   | Escopo                         |
| --------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| **Organização** | A conta da sua empresa na plataforma. É o nível em que vive o cadastro e a cobrança.                                      | Contém um ou mais Projetos.    |
| **Projeto**     | A unidade de **isolamento** da integração. Agrupa suas instâncias, seus webhooks, suas conversas e a assinatura/créditos. | Contém uma ou mais Instâncias. |
| **Instância**   | Um **número de WhatsApp** conectado, pareado a um aparelho via QR Code.                                                   | Pertence a um único Projeto.   |

A **API key é escopada a um único Projeto**: toda instância, mensagem ou webhook que você cria, lista ou remove com a key pertence ao Projeto dela. A Organização é o container de conta/cobrança acima dos Projetos — ela existe, mas **não aparece nas respostas da API** (os objetos retornam `projectId`, não a organização); você não precisa manipulá-la para integrar.

<Callout type="info">
  Quer **isolar ambientes ou clientes** (ex.: um Projeto por cliente final, ou um Projeto para
  staging)? Crie Projetos separados e use a key de cada um. Como o Projeto é a fronteira de
  isolamento, dados de um nunca vazam para o outro.
</Callout>

A geração de keys é **self-service**: você se cadastra, confirma o e-mail e gera a key no painel. A key crua é exibida **uma única vez** no momento da criação — guarde-a em local seguro, pois não há como recuperá-la depois (se perder, revogue e gere outra). O passo a passo está em [Autenticação](/docs/get-started/authentication).

### Glossário rápido [#glossário-rápido]

Termos que aparecem em toda a documentação:

| Termo                     | Significado                                                                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Instância**             | Um número de WhatsApp conectado dentro do seu Projeto. Você envia mensagens "por uma instância".                                                  |
| **`status` da instância** | Em que ponto da conexão a instância está: `DISCONNECTED`, `CONNECTING`, `QR_PENDING`, `CONNECTED`, `BANNED`, `ERROR`. Só envie em `CONNECTED`.    |
| **QR Code**               | A imagem que você renderiza para o usuário escanear no app do WhatsApp (Aparelhos conectados) e parear o número.                                  |
| **JID**                   | O identificador interno do WhatsApp para um destino, no formato `5511999999999@s.whatsapp.net`. O campo `to` aceita ele ou só os dígitos (E.164). |
| **Webhook / WebSocket**   | Os dois caminhos para **receber** eventos (mensagens de entrada e status). Webhook chama o seu endpoint; WebSocket é uma conexão que você abre.   |
| **Créditos da API**       | Saldo pré-pago consumido a cada mensagem enviada **pela API** (envios pelo painel não consomem).                                                  |

## Modos: teste e produção [#modos-teste-e-produção]

Uma **única conta**, com dois **modos** — igual ao test/live do Stripe. O modo é determinado pela &#x2A;*base URL (host)** da API: hosts que começam com `sandbox.` operam em **teste**; `api.` opera em **produção**. Os dados são **totalmente isolados** entre os modos — instâncias, conversas e webhooks de teste nunca aparecem em produção, e vice-versa.

| Modo         | Base URL                           | Prefixo da API key | Cobrança                |
| ------------ | ---------------------------------- | ------------------ | ----------------------- |
| **Teste**    | `https://sandbox.pepinozap.com.br` | `pzk_test_`        | Grátis, com teto diário |
| **Produção** | `https://api.pepinozap.com.br`     | `pzk_live_`        | Exige plano ativo       |

**É o host que decide o modo, não a key** — mas a key tem que **casar com o host**. Uma key de produção (`pzk_live_`) usada no host de teste (`sandbox.*`), ou o contrário, é rejeitada com `401`. Use sempre a key do mesmo modo da base URL.

```bash
# pzk_live_ no host de teste → 401 (key do modo errado)
curl https://sandbox.pepinozap.com.br/v1/instances \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx"
```

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

<Callout type="info">
  **Use o modo Teste para construir.** Em teste, criar instâncias e enviar mensagens **não exige
  plano** — você valida a integração inteira de graça. Para evitar que o teste vire "produção de
  graça", há um **teto de 100 mensagens/dia por Projeto** (enviadas + recebidas; acima disso,
  `429`). Quando estiver pronto para volume real, troque a base URL para `api.*` e a key para
  `pzk_live_`, e assine um plano. Veja [Modos: teste e
  produção](/docs/get-started/authentication#modos-teste-e-producao).
</Callout>

## Autenticação em uma frase [#autenticação-em-uma-frase]

Envie a API key no header `Authorization` com o esquema `Bearer` em **todas** as chamadas REST:

```bash
curl https://api.pepinozap.com.br/v1/instances \
  -H "Authorization: Bearer pzk_live_xxxxxxxxxxxxxxxx"
```

As **únicas exceções** são os transportes que o navegador abre sem poder definir headers — o **stream SSE de QR Code** (`GET /v1/instances/{id}/qr`) e o **WebSocket de eventos** (`/v1/ws`). Nesses dois casos, a key vai na query string como `?token=<API_KEY>`. Em qualquer outro endpoint, use sempre o header `Authorization`. O detalhamento (inclusive o token efêmero de 2 minutos para não expor a key na URL do SSE) está em [Autenticação](/docs/get-started/authentication).

## Pré-requisitos para operar (402 e 429) [#pré-requisitos-para-operar-402-e-429]

Ter uma API key válida **não basta** para enviar de verdade. As ações de **uso real** — conectar um número e enviar mensagens — passam por gates de negócio; as ações de **leitura** e o **pareamento por QR Code** ficam sempre liberadas.

| Ação                                                                           | Pré-requisito                                                                       |
| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| Criar instância (`POST /v1/instances`)                                         | Plano ativo (em produção)                                                           |
| Enviar mensagem (texto, mídia, localização, contato, sticker, reação, enquete) | Plano ativo (em produção); em projetos modo API, também consome 1 crédito por envio |
| Listar / detalhar instância, parear via QR, marcar como lida                   | Nenhum — sempre liberado                                                            |

* **`402` `PAYMENT_REQUIRED`** — em **produção**, o Projeto não tem **assinatura ativa**, ou um Projeto no modo API ficou **sem créditos**. Distinga os dois casos pela `message`. Resolução: assinar ou recarregar em **Meu plano**, no painel. Em **teste**, esses gates são liberados (não ocorre `402`).
* **`429` `RATE_LIMITED`** — **apenas em teste**: o teto de 100 mensagens/dia por Projeto foi atingido. Em produção não ocorre.

<Callout type="warn">
  `402` é um **gate de negócio**, não um erro transitório — **não repita a chamada** em loop. A ação
  só volta a funcionar após assinar ou recarregar; o seu código não muda. Detalhes e exemplos de
  payload em [Plano ativo (erro 402)](/docs/get-started/authentication#plano-ativo-erro-402).
</Callout>

## Como começar [#como-começar]

Siga os guias nesta ordem — eles formam o caminho mínimo de ponta a ponta:

1. **[Quick start](/docs/get-started/quick-start)** — o fluxo completo num só lugar: obter a key, criar uma instância, parear via QR Code e enviar a primeira mensagem.
2. **[Autenticação](/docs/get-started/authentication)** — gerar e usar a API key no header `Authorization: Bearer`, os modos teste/produção e o fallback `?token=`.
3. **[Sua primeira instância](/docs/get-started/first-instance)** — o ciclo de status de `DISCONNECTED` até `CONNECTED`, o pareamento por QR (polling, recomendado, e SSE) e as configurações da instância.

<Callout type="warn">
  **Envie só quando a instância estiver `CONNECTED`.** Enviar para uma instância
  ainda não conectada &#x2A;*também retorna `202`** (`{ "queued": true }`), mas a
  mensagem **não sai** e **não há evento de falha**. Antes de enviar, confirme
  `GET /v1/instances/{id}` (`status === "CONNECTED"`) ou o `qr/poll`
  (`connected === true`).
</Callout>

## Referência rápida de erros [#referência-rápida-de-erros]

Toda resposta de erro segue o mesmo envelope. Use o campo `code` (estável) no seu tratamento de erros, não a `message` (apenas legível).

```json
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Body inválido"
  }
}
```

| Status | `code`             | Quando ocorre                                                                                   |
| ------ | ------------------ | ----------------------------------------------------------------------------------------------- |
| `400`  | `BAD_REQUEST`      | Corpo inválido ou campo obrigatório faltando.                                                   |
| `401`  | `UNAUTHORIZED`     | Key ausente, inválida, revogada, expirada **ou** do modo errado para o host.                    |
| `402`  | `PAYMENT_REQUIRED` | Sem plano ativo **ou** sem créditos da API (só em produção).                                    |
| `403`  | `FORBIDDEN`        | Projeto inativo ou sem permissão.                                                               |
| `404`  | `NOT_FOUND`        | Recurso não encontrado no Projeto/modo da key.                                                  |
| `409`  | `CONFLICT`         | Ao criar instância: cota de números do plano atingida. Ao enviar: instância `BANNED`/`ERROR`.   |
| `429`  | `RATE_LIMITED`     | **Apenas em teste:** teto diário do Projeto atingido (100 mensagens/dia, enviadas + recebidas). |

## Próximos passos [#próximos-passos]

* **[Referência da API](/docs/api)** — endpoints de instâncias e mensagens (texto, mídia, localização, contato, sticker, reação, enquete), configurações da instância, payloads de requisição e resposta, e erros esperados.
* **[Inbox e Gestão (CRM)](/docs/api)** — ler conversas e mensagens persistidas (system of record) com mídia hospedada, e gerir o atendimento: etiquetas, atribuição, status/motivos, funil e relatórios — tudo pela mesma key.
* **[Persistência e histórico](/docs/get-started/persistencia)** — como a plataforma guarda suas conversas e como ler o histórico pelo Inbox sem manter banco próprio.
* **[Webhooks](/docs/webhooks)** — os dez eventos (mensagem, instância, chamada, grupo, contato e etiqueta), envelope de entrega e verificação de assinatura.
* **[WebSocket](/docs/webhooks/websocket)** — os mesmos eventos em tempo real por conexão persistente, sem endpoint público.
