Multi-Tenancy
A plataforma Voki utiliza uma arquitetura multi-tenant com isolamento completo de dados por tenant. Este guia explica como o sistema de tenants funciona e como interagir com a API corretamente.
Conceito
Cada empresa (cliente da Voki) é um tenant independente. O isolamento é garantido por:
- Schema PostgreSQL separado por tenant
- JWT com claim de tenant para autenticação
- Header
X-Tenantem todas as requisições autenticadas
Identificação do Tenant
Cada tenant possui um slug único que o identifica. O slug é definido na criação do tenant e não pode ser alterado.
Exemplos de slugs: avanter, clinica-abc, empresa-xyz
Como Funciona
1. Login
No login, o tenant é informado no corpo da requisição:
curl -X POST https://voki.avanter.com.br/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "usuario@empresa.com",
"password": "senha123",
"tenant": "avanter"
}'O token JWT retornado contém o tenant nos claims:
{
"sub": "user_uuid",
"tenant": "avanter",
"role": "manager",
"exp": 1708387200
}2. Requisições Autenticadas
Após o login, todas as requisições devem incluir:
Authorization: Bearer {token}- Token JWTX-Tenant: {slug}- Slug do tenant
curl -X GET https://voki.avanter.com.br/api/v1/users \
-H "Authorization: Bearer eyJhbGci..." \
-H "X-Tenant: avanter"Importante
O header X-Tenant deve corresponder ao tenant do token JWT. Se houver divergência, a requisição será rejeitada com 401 Unauthorized.
3. Isolamento de Dados
Cada requisição opera exclusivamente nos dados do tenant autenticado:
- Um usuário do tenant
avanternunca acessa dados do tenantclinica-abc - Todas as queries SQL são executadas no schema do tenant
- IDs são únicos dentro de cada tenant, mas podem se repetir entre tenants
Arquitetura Técnica
┌─────────────────────────────────────────────────┐
│ PostgreSQL 16 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ public │ │ avanter │ │ clinica │ │
│ │ (shared) │ │ (tenant) │ │ (tenant) │ │
│ │ │ │ │ │ │ │
│ │ - companies │ │ - users │ │ - users │ │
│ │ - plans │ │ - calls │ │ - calls │ │
│ │ │ │ - customers │ │ - ... │ │
│ └─────────────┘ └─────────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘- Schema
public: Dados compartilhados (empresas, planos, configurações globais) - Schema por tenant: Dados isolados (usuários, chamadas, clientes, gravações, etc.)
Criando um Novo Tenant
Novos tenants são criados via o fluxo de signup:
# 1. Validar documento
curl -X POST https://voki.avanter.com.br/api/signup/validate-document \
-H "Content-Type: application/json" \
-d '{"document": "12.345.678/0001-90", "document_type": "cnpj"}'
# 2. Registrar
curl -X POST https://voki.avanter.com.br/api/signup/register \
-H "Content-Type: application/json" \
-d '{
"company_name": "Nova Empresa",
"document": "12.345.678/0001-90",
"document_type": "cnpj",
"admin_name": "Administrador",
"admin_email": "admin@novaempresa.com",
"admin_password": "senhaSegura123",
"plan": "professional"
}'
# 3. Checkout (Asaas)
curl -X POST https://voki.avanter.com.br/api/signup/checkout \
-H "Content-Type: application/json" \
-d '{
"tenant": "nova-empresa",
"plan": "professional",
"success_url": "https://...",
"cancel_url": "https://..."
}'Boas Práticas
- Armazene o slug do tenant junto com o token no seu cliente
- Inclua sempre o header
X-Tenant- mesmo que o token já contenha o tenant - Não hardcode slugs - obtenha do login ou de configuração
- Trate erros 401 - podem indicar token expirado OU tenant inválido
- Renove tokens antes da expiração usando o refresh token
Limitações por Plano
Cada tenant possui limites baseados no plano contratado:
| Recurso | Starter | Professional | Enterprise |
|---|---|---|---|
| Chamadas simultâneas | 2 | 10 | Ilimitado |
| Usuários | 5 | 50 | Ilimitado |
| Departamentos | 3 | 20 | Ilimitado |
| Gravação | Sim | Sim | Sim |
| Transcrição IA | Não | Sim | Sim |
| Analytics avançado | Não | Sim | Sim |
Consulte o plano atual via GET /api/v1/billing/plan.
