Multi-Tenancy
La plataforma Voki utiliza una arquitectura multi-tenant con aislamiento completo de datos por tenant. Esta guía explica cómo funciona el sistema de tenants y cómo interactuar con la API correctamente.
Concepto
Cada empresa (cliente de Voki) es un tenant independiente. El aislamiento se garantiza mediante:
- Esquema PostgreSQL separado por tenant
- JWT con claim de tenant para autenticación
- Header
X-Tenanten todas las solicitudes autenticadas
Identificación del Tenant
Cada tenant posee un slug único que lo identifica. El slug se define en la creación del tenant y no puede modificarse.
Ejemplos de slugs: avanter, clinica-abc, empresa-xyz
Cómo Funciona
1. Login
En el login, el tenant se informa en el cuerpo de la solicitud:
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"
}'El token JWT devuelto contiene el tenant en los claims:
{
"sub": "user_uuid",
"tenant": "avanter",
"role": "manager",
"exp": 1708387200
}2. Solicitudes Autenticadas
Después del login, todas las solicitudes deben incluir:
Authorization: Bearer {token}- Token JWTX-Tenant: {slug}- Slug del tenant
curl -X GET https://voki.avanter.com.br/api/v1/users \
-H "Authorization: Bearer eyJhbGci..." \
-H "X-Tenant: avanter"Importante
El header X-Tenant debe corresponder al tenant del token JWT. Si hay divergencia, la solicitud será rechazada con 401 Unauthorized.
3. Aislamiento de Datos
Cada solicitud opera exclusivamente en los datos del tenant autenticado:
- Un usuario del tenant
avanternunca accede a datos del tenantclinica-abc - Todas las queries SQL se ejecutan en el esquema del tenant
- Los IDs son únicos dentro de cada tenant, pero pueden repetirse entre tenants
Arquitectura Técnica
┌─────────────────────────────────────────────────┐
│ PostgreSQL 16 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ public │ │ avanter │ │ clinica │ │
│ │ (shared) │ │ (tenant) │ │ (tenant) │ │
│ │ │ │ │ │ │ │
│ │ - companies │ │ - users │ │ - users │ │
│ │ - plans │ │ - calls │ │ - calls │ │
│ │ │ │ - customers │ │ - ... │ │
│ └─────────────┘ └─────────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘- Esquema
public: Datos compartidos (empresas, planes, configuraciones globales) - Esquema por tenant: Datos aislados (usuarios, llamadas, clientes, grabaciones, etc.)
Creación de un Nuevo Tenant
Los nuevos tenants se crean a través del flujo 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://..."
}'Buenas Prácticas
- Almacene el slug del tenant junto con el token en su cliente
- Incluya siempre el header
X-Tenant- aunque el token ya contenga el tenant - No codifique slugs en el código - obténgalos del login o de la configuración
- Maneje los errores 401 - pueden indicar token expirado O tenant inválido
- Renueve los tokens antes de la expiración usando el refresh token
Limitaciones por Plan
Cada tenant posee límites basados en el plan contratado:
| Recurso | Starter | Professional | Enterprise |
|---|---|---|---|
| Llamadas simultáneas | 2 | 10 | Ilimitado |
| Usuarios | 5 | 50 | Ilimitado |
| Departamentos | 3 | 20 | Ilimitado |
| Grabación | Sí | Sí | Sí |
| Transcripción IA | No | Sí | Sí |
| Analytics avanzado | No | Sí | Sí |
Consulte el plan actual vía GET /api/v1/billing/plan.
