> ## Documentation Index
> Fetch the complete documentation index at: https://developer.wabox.me/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Wabox é uma API não-oficial de WhatsApp (aparelho vinculado). Tudo é snake_case; a base é https://api.wabox.me/instances/{instance_id}/token/{token}.
> Envios respondem { id, message_id, wabox_id, status: "queued" } na hora; o resultado real chega no webhook delivery. Envios não são idempotentes: confira GET /queue antes de repetir.
> Sempre verifique X-Wabox-Signature (HMAC-SHA256 de "<t>.<corpo cru>") nos webhooks e deduplique por event_id.
> Botões, listas, carrossel e catálogo são best effort e não renderizam no WhatsApp Web/Desktop. Não existem: chamadas, listas de transmissão, histórico de mensagens, instância mobile.
> Não invente endpoints ou campos: use o OpenAPI em https://api.wabox.me/openapi.json.

# API keys

> Credenciais do workspace com nome e permissões, enviadas em Authorization: Bearer.

Uma API key é um segredo do **workspace** enviado como header HTTP. Cada key tem um **nome** e as **permissões** (scopes) que você escolher, e um workspace pode ter quantas precisar — o normal é uma por integração, para poder revogar só ela.

```bash theme={"system"}
curl https://api.wabox.me/account/instances \
  -H "Authorization: Bearer wbx_key_3f9a1c7e5b2d4f6a8c0e1b3d5f7a9c2e4b6d8f0a1c3ec2e1"
```

O formato é `wbx_key_` seguido de 48 caracteres hexadecimais. As keys servem para duas coisas:

* **[Account API](/account/api)** (`/account/*`): é a única credencial. Cada rota pede uma permissão.
* **Rotas de instância** (`/instances/{instance_id}/token/{token}/*`): camada opcional por cima do token da URL, ligada em **Exigir API key nas rotas de instância**.

O token da instância na URL não muda: ele continua sendo a credencial base das rotas de instância e, por padrão, nenhum header é necessário nelas.

## Permissões

| Scope               | Libera                                                                                                                                  |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `instances:operate` | Vale como a key exigida nas rotas de instância quando o workspace liga **Exigir API key nas rotas de instância**                        |
| `instances:read`    | `GET /account/instances`, `GET /account/instances/{id}`, `GET /account/plan`. As respostas incluem o `token` de cada instância          |
| `instances:write`   | `POST /account/instances`, `PUT /account/instances/{id}`, `POST /account/instances/{id}/rotate-token`, `DELETE /account/instances/{id}` |
| `webhooks:read`     | `GET /account/webhooks` (inclui o `secret`)                                                                                             |
| `webhooks:write`    | `PUT /account/webhooks`, `POST /account/webhooks/secret`                                                                                |

Marque só o que a integração precisa. Um backend que apenas envia mensagens precisa de `instances:operate` (e só se a exigência estiver ligada); um provisionador de instâncias precisa de `instances:read` e `instances:write`. As permissões da Account API só funcionam em [contas com plano](/account/api).

## Como criar

<Steps>
  <Step title="Crie a key">
    No painel, em **Segurança › API keys**, clique em **Nova API key**. Dê um nome que identifique a integração (ex.: "Backend de produção") e marque as permissões. Owners e admins criam, editam e revogam; membros só veem a lista.
  </Step>

  <Step title="Copie o valor">
    A key aparece **uma única vez**, na criação. Só o hash fica guardado: copie para o seu cofre de segredos. Perdeu? Revogue e crie outra.
  </Step>

  <Step title="Envie no header">
    `Authorization: Bearer wbx_key_…` em toda chamada que precisa da key.
  </Step>
</Steps>

A lista mostra, para cada key, uma dica do valor (`wbx_key_3f9a…c2e1`), as permissões e o último uso. Dá para **editar as permissões** de uma key existente sem trocar o valor dela.

## Exigir API key nas rotas de instância

O token da instância vai na URL, e URLs vazam com facilidade: logs de proxy, histórico de navegador, planilhas, capturas de tela. Com a exigência ligada, toda requisição a qualquer instância do workspace precisa trazer, além do token na URL, uma key com `instances:operate` em um header, que raramente é registrado. Se uma URL vazar, quem a tiver ainda não consegue usar a API.

```bash theme={"system"}
curl https://api.wabox.me/instances/{instance_id}/token/{token}/status \
  -H "Authorization: Bearer wbx_key_3f9a1c7e5b2d4f6a8c0e1b3d5f7a9c2e4b6d8f0a1c3ec2e1"
```

<Steps>
  <Step title="Crie uma key com instances:operate">
    O painel só deixa ligar a exigência se existir pelo menos uma key com essa permissão.
  </Step>

  <Step title="Configure suas integrações">
    Adicione o header `Authorization: Bearer wbx_key_…` em todas as chamadas, de todas as instâncias do workspace. Teste com `GET /status` — com a exigência desligada o header é ignorado, então dá para preparar tudo antes.
  </Step>

  <Step title="Ative a exigência">
    Ligue **Exigir API key nas rotas de instância**. A partir daí, requisições sem o header (ou com uma key inválida) recebem `401 api_key_required`, e com uma key sem `instances:operate`, `403 insufficient_scope`.
  </Step>
</Steps>

<Warning>
  A exigência vale para **todas** as instâncias do workspace ao mesmo tempo, inclusive as usadas por ferramentas no-code. Atualize tudo antes de ligar.
</Warning>

Enquanto a exigência está ligada, a **última** key com `instances:operate` não pode ser revogada nem perder essa permissão: o painel recusa. Desligue a exigência antes, ou crie outra key com a permissão.

No [MCP](/integrations/mcp), a exigência não se aplica a apps autorizados por OAuth. Com o token da instância como bearer ela vale, e a key vai no header `Client-Token` (o `Authorization` já está ocupado pelo token da instância).

## Alias `Client-Token`

Para quem vem da z-api: nas rotas de instância, a key também pode ir no header `Client-Token` em vez de `Authorization: Bearer`, com o mesmo valor. Quem já envia `Client-Token` só troca o valor pelo de uma API key do Wabox com `instances:operate`.

```bash theme={"system"}
curl https://api.wabox.me/instances/{instance_id}/token/{token}/status \
  -H "Client-Token: wbx_key_3f9a1c7e5b2d4f6a8c0e1b3d5f7a9c2e4b6d8f0a1c3ec2e1"
```

* O nome do header não diferencia maiúsculas (`client-token` também funciona).
* O alias vale nas rotas de instância e no `/mcp` com o token da instância como bearer. A Account API (`/account/*`) aceita **só** `Authorization: Bearer`.
* **Client-Tokens gerados antes das API keys** foram migrados automaticamente para uma key chamada **"Client-Token (migrado)"**, com `instances:operate`. O valor antigo continua funcionando no header `Client-Token`, e o estado da exigência (ligada ou desligada) foi mantido. Nada precisa mudar nas integrações existentes; quando quiser, crie keys novas por integração e revogue a migrada.

## Rotação sem downtime

Revogar uma key é imediato e **não afeta as outras**. Como várias keys convivem, a troca não tem janela de indisponibilidade:

1. Crie uma key nova com as mesmas permissões.
2. Atualize a integração para usar a nova e confirme que está funcionando. O **último uso** na lista ajuda a ver se a antiga ainda recebe chamadas.
3. Revogue a antiga.

Veja também [Rotação de token e segredo](/security/credential-rotation).

## Erros

| HTTP | `code`               | Causa                                                                                                                                    |
| ---- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| 401  | `api_key_required`   | Header ausente ou key inválida (revogada, inexistente ou de outro workspace). Nas rotas de instância, só acontece com a exigência ligada |
| 403  | `insufficient_scope` | A key é válida mas não tem a permissão da rota; `details.required_scope` diz qual falta                                                  |

```json theme={"system"}
{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key lacks the \"instances:write\" permission",
    "details": { "required_scope": "instances:write" }
  }
}
```
