Pular para o conteúdo principal

Conta, projetos e usuários

O bZapper organiza tudo em três níveis:

Conta (empresa)
├── Usuários (admin / membro) ← faturamento e equipe vivem na conta
├── Contatos (compartilhados) ← visíveis em todos os projetos, filtráveis
└── Projetos
├── Projeto A
│ ├── Números (instâncias) + rotação
│ ├── Inbox (conversas/mensagens)
│ ├── API keys
│ ├── Estatísticas
│ └── Identidade dos números (perfil/"Sobre")
└── Projeto B … (isolado de A)

O que é um projeto?​

Um projeto é um ambiente isolado dentro da sua conta. Diferente de outras ferramentas onde "instância = um número", aqui um projeto agrupa vários números que se revezam entre si (redundância). Cada projeto isola:

  • Números (instâncias) e a rotação entre eles;
  • Inbox — conversas e mensagens;
  • API keys;
  • Estatísticas (consumo);
  • Identidade dos números (perfil/"Sobre").

Use projetos para separar clientes, marcas, ambientes (produção/teste) ou equipes — sem misturar números, conversas nem cobrança.

API keys são por projeto​

Cada API key pertence a exatamente um projeto. A chave já carrega o contexto: toda chamada autenticada por ela opera somente nos números, inbox e estatísticas daquele projeto. Não é preciso enviar mais nada.

# Esta key é do "Projeto A" → só vê os números/inbox do Projeto A.
curl https://api.bzapper.com.br/instances -H "Authorization: Bearer bz_live_doProjetoA..."

Para operar em outro projeto, gere uma key naquele projeto (no painel, troque o projeto no seletor do topo e crie a key em Keys).

Com API key você não manda X-Project-Id

A key já carrega o projeto dela. O header X-Project-Id serve só para a sessão do painel (JWT), onde o projeto ativo vem do seletor — numa chamada autenticada por API key ele é simplesmente ignorado. Para recortar dados por projeto use o parâmetro ?project_id= dos endpoints que o aceitam.

Painel (sessão de usuário)

No painel, o projeto ativo é escolhido no seletor do cabeçalho e enviado em cada requisição no header X-Project-Id. As telas (Números, Inbox, Keys, Estatísticas) refletem o projeto ativo. Trocar o projeto troca todo o contexto.

Rotação de API key​

A chave crua (bz_live_...) aparece uma única vez. Se ela vazou, se um dev saiu do time ou se você simplesmente quer trocar de chave por higiene, não apague e crie outra: rotacione. POST /keys/{id}/rotate cria uma chave nova que herda papel, escopos, projeto e nome da antiga e mantém a antiga funcionando por um período de carência — a sua integração não cai no meio do deploy.

curl -X POST https://api.bzapper.com.br/keys/$KEY_ID/rotate \
-H "Authorization: Bearer $BZ_KEY" \
-H "Content-Type: application/json" \
-d '{ "revoke_in_seconds": 86400 }'

Resposta 200:

{
"api_key": "bz_live_novaChaveCrua...",
"key": { "id": "9b1c…", "name": "produção", "role": "admin", "project_id": "4d2e…" },
"previous_key": { "id": "3f2a…", "expires_at": "2026-07-02T12:00:00Z", "rotated_to": "9b1c…" },
"old_key_expires_at": "2026-07-02T12:00:00Z"
}
api_key é mostrado uma única vez

O campo api_key da resposta é a chave crua nova — ela não é recuperável depois. Guarde no seu cofre de segredos antes de fechar a requisição.

A carência (revoke_in_seconds)​

revoke_in_seconds é por quanto tempo a chave antiga continua valendo:

ValorEfeito
omitido86400 (24 horas) — o padrão
0revoga a antiga na hora (só faça isso se você troca a chave em todos os lugares ao mesmo tempo)
até 2592000máximo de 30 dias

Passado o prazo, a chave antiga responde 401 key_expired — um código distinto de key_revoked, para você saber no log que foi uma rotação que venceu, não uma revogação.

O procedimento seguro (sem downtime)​

  1. Rotacione com uma carência que caiba na sua janela de deploy (24 h é folgado). Guarde o api_key novo no cofre.
  2. Suba a chave nova onde a integração roda (variáveis de ambiente, secret manager) e faça o deploy. As duas chaves valem ao mesmo tempo — nenhuma requisição falha.
  3. Confira que ninguém mais usa a antiga: GET /keys mostra o last_used_at de cada chave. Se ele parou de andar, a migração terminou.
  4. Deixe a antiga vencer sozinha no fim da carência — ou apresse com DELETE /keys/{id} se já confirmou o passo 3.

Não inverta a ordem: rotacionar depois do deploy derruba a integração entre os dois momentos.

No painel, a tela Keys tem o botão Rotacionar com a carência em três opções (1 dia, 1 semana ou agora) — a chave nova é revelada uma única vez, com o aviso de quando a antiga para de valer.

GET /keys durante a rotação​

A listagem ganha dois campos que contam a história de cada chave:

CampoO que diz
expires_atquando a chave rotacionada para de funcionar. null quando ela nunca foi rotacionada
rotated_too id da chave que a substituiu — o rastro de quem veio depois

Quem pode, e o que dá erro​

Rotação é só de admin (uma key agent ou um usuário membro recebe 403 admin_required). Chave inexistente é 404; chave que já foi revogada ou que já venceu responde 409 com key_already_revoked / key_already_expired — não há nada para rotacionar.

Chaves de parceiro rotacionam por outra rota

Uma chave emitida a um software parceiro pelo bZapper Connect não rotaciona aqui: use POST /partner/connections/{id}/rotate-key. Veja a referência do Connect.

Nas SDKs oficiais​

// Node / TypeScript
const { api_key, old_key_expires_at } = await bz.rotateKey(keyId, { revoke_in_seconds: 3600 });
# Python
rotated = bz.rotate_key(key_id, revoke_in_seconds=3600)
print(rotated["api_key"]) # guarde agora; não é mostrado de novo
// PHP
$rotated = $bz->rotateKey($keyId, 3600);
// Go
grace := 3600
rot, err := bz.RotateKey(ctx, keyID, bzapper.RotateKeyParams{RevokeInSeconds: &grace})
// Java
ApiKeyRotated rotated = bz.rotateKey(keyId, 3600);
// .NET (C#)
var rotated = await bz.RotateMyKeyAsync(keyId, new RotateApiKey { RevokeInSeconds = 3600 });
# Ruby
rotated = bz.accounts.rotate_my_key(key_id, revoke_in_seconds: 3600)

Contatos são da conta (compartilhados)​

A base de contatos é da conta — o mesmo cliente é reconhecido em qualquer projeto. Você pode filtrar os contatos por projeto:

GET /contacts                      # todos os contatos da conta
GET /contacts?project_id=<id> # só quem teve conversa naquele projeto
GET /contacts?project_id=current # só do projeto da sua key/sessão

Usuários e papéis​

Usuários pertencem à conta e enxergam todos os projetos. Há dois papéis:

PapelPode
Administradortudo: faturamento, consumo da conta, gerenciar usuários e projetos
Membrotudo, exceto faturamento e a página da conta

Um admin convida usuários em Conta → Equipe (por e-mail; o convidado recebe um link para definir a senha). A conta sempre mantém ao menos um administrador.

Faturamento da conta (plano Pro)​

O faturamento é da conta (não do projeto): a conta tem um plano (Free ou Pro) e uma moeda, e os recursos de todos os projetos contam contra os limites da conta. O Free é grátis para sempre; o Pro é uma assinatura mensal recorrente (mensagens ilimitadas + um pacote de recursos), com add-ons para ampliar. Detalhes em Cobrança.

A página Cobrança (admin) mostra o plano, as faturas, os cartões (com cartão principal + recorrência) e o consumo agregado por projeto (números, enviadas, recebidas, total).

GET /me/entitlements   # limites efetivos da conta (plano, add-ons, franquias, consumo)
GET /me/subscription # estado do plano (status, vencimento, recorrência, moeda)
GET /me/invoices # histórico de faturas da conta
GET /account/usage # admin: { account: {…}, projects: [{ name, numbers, total, … }] }

Resumo​

  • Conta = empresa (usuários, faturamento/plano, contatos).
  • Projeto = ambiente isolado (números, inbox, keys, stats, identidade).
  • API key = sempre de um projeto; troque com rotação (POST /keys/{id}/rotate), nunca apagando e recriando.
  • Contatos = compartilhados, filtráveis por projeto.
  • Plano = Free ou Pro (recorrente + add-ons); faturamento vive na conta.
  • Membros veem tudo menos faturamento.