Skip to content

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-Tenant em 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:

bash
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:

json
{
  "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 JWT
  • X-Tenant: {slug} - Slug do tenant
bash
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 avanter nunca acessa dados do tenant clinica-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:

bash
# 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

  1. Armazene o slug do tenant junto com o token no seu cliente
  2. Inclua sempre o header X-Tenant - mesmo que o token já contenha o tenant
  3. Não hardcode slugs - obtenha do login ou de configuração
  4. Trate erros 401 - podem indicar token expirado OU tenant inválido
  5. Renove tokens antes da expiração usando o refresh token

Limitações por Plano

Cada tenant possui limites baseados no plano contratado:

RecursoStarterProfessionalEnterprise
Chamadas simultâneas210Ilimitado
Usuários550Ilimitado
Departamentos320Ilimitado
GravaçãoSimSimSim
Transcrição IANãoSimSim
Analytics avançadoNãoSimSim

Consulte o plano atual via GET /api/v1/billing/plan.

Documentação da API Voki v4.0