SIVO
Modelo de datos

Conceptos

Modelo de datos

Las entidades principales de SIVO y cómo se relacionan entre sí. Para tu equipo técnico que necesita entender cómo modelar la integración.

Actualizado:
conceptosdata-modelentidades

Esta página describe las entidades principales de SIVO y sus relaciones. Útil para tu equipo de IT, arquitectos de soluciones e integradores que necesitan saber cómo modelar la integración con sus sistemas.

Vista general

┌─────────────────────────────────────────────────────────────────┐
│                          Tenant                                  │
│  ┌───────┐  ┌────────┐  ┌──────┐  ┌──────┐  ┌──────────────┐   │
│  │ Users │  │ Queues │  │ DIDs │  │ IVRs │  │ SIP Trunks    │   │
│  └───┬───┘  └────┬───┘  └───┬──┘  └───┬──┘  └──────┬───────┘   │
│      │           │          │         │             │           │
│      └───────────┴──────────┴─────────┴─────────────┘           │
│                            │                                    │
│                       ┌────▼─────┐                              │
│                       │  Calls   │  (CDR + recordings +         │
│                       │          │   transcripts + events)      │
│                       └──────────┘                              │
└─────────────────────────────────────────────────────────────────┘

Todo cuelga del Tenant — el contenedor principal de aislamiento. Los datos de un tenant no se ven desde otro (ver Multi-tenant).

Entidades principales

Tenant

El tenant es el cliente. Cada org SIVO tiene uno o varios tenants.

CampoTipoSignificado
idUUIDIdentificador único interno
slugstringURL-friendly (ej. acme-corp)
namestringNombre mostrado en la UI
sip_domainstringDominio SIP (acme.sip.sivocenter.com)
planenumstarter / pro / enterprise
regionenumeu / us / custom
created_attimestampFecha de alta

User

Cada persona con acceso a SIVO. Es a la vez agente (atiende llamadas) y usuario del panel.

CampoTipoSignificado
idUUIDIdentificador único
tenant_idUUIDTenant al que pertenece
emailstringLogin + comunicaciones
full_namestringNombre completo
extensionstringExtensión SIP (3-5 dígitos)
roleenumagent / supervisor / admin / viewer
statusenumavailable / on_call / paused / acw / logged_out
languageenumes / en / de / fr / it / pt
mfa_enabledboolSi tiene MFA activado

Queue

Cola ACD. Distribuye llamadas entre agentes según una estrategia.

CampoSignificado
id, name, tenant_idIdentificación
strategyring-all / longest-idle / round-robin / top-down / fewest-calls / random
max_wait_timeSegundos antes de timeout
wrap_up_timeACW automático tras colgar
moh_urlMúsica de espera
announce_positionSi dice al caller “es el número N en cola”
service_level_target% objetivo de atendidas en menos de N seg

Relación con users: muchos-a-muchos vía queue_members:

CampoSignificado
queue_id, user_idIdentificación
tierPrioridad (1 = principal, 2 = backup)
levelSub-prioridad dentro del tier

DID

Direct Inward Dial — un número entrante.

CampoSignificado
id, tenant_idIdentificación
numberE.164 (+34911234567)
trunk_idPor qué trunk entran las llamadas
ivr_flow_idIVR que ejecuta
schedule_idHorario asignado (opcional)
out_of_hours_ivr_flow_idIVR fuera de horario
outbound_caller_idSi se permite como caller ID saliente

IVR Flow

Un flujo de llamada. Múltiples versiones por flow.

CampoSignificado
id, name, tenant_idIdentificación
descriptionDescripción humana

Y por versión (ivr_flow_versions):

CampoSignificado
flow_id, versionIdentificación
is_activeSolo una versión activa por flow
nodesJSON con los nodos (start, menu, queue, etc.)
created_at, created_byAuditoría

SIP Trunk

Conexión con tu operador telefónico.

CampoSignificado
id, name, tenant_idIdentificación
providerzadarma / twilio / bandwidth / custom
hostSIP host del registrador
username, password_encryptedCredenciales (password cifrada AES-256-GCM)
allowed_cidrsArray de IPs/CIDRs permitidos
stateREGED / TRYING / FAIL / NOREG
failover_trunk_idTrunk de failover (opcional)

Schedule

Horarios de atención y festivos.

CampoSignificado
id, name, tenant_idIdentificación
timezoneIANA (Europe/Madrid)
hoursJSON por día con apertura/cierre
holidaysArray de fechas YYYY-MM-DD
exceptionsExcepciones puntuales

Call (CDR)

Una llamada. La entidad de mayor volumen.

CampoSignificado
idUUID
tenant_idTenant
directioninbound / outbound / internal
caller_id_number, caller_id_nameOrigen
destinationDestino
did_idDID por el que entró (si inbound)
agent_idAgente que atendió (nullable)
queue_idCola por la que pasó (nullable)
ivr_flow_idIVR que se ejecutó (nullable)
statusanswered / no_answer / busy / failed / abandoned
started_at, answered_at, ended_atTimestamps
duration_sec, billsecDuración total y de conversación
hangup_causeNORMAL_CLEARING, CALL_REJECTED, etc.
recording_idSi está grabada
transcript_idSi está transcrita
mos_scoreCalidad audio (1-5)
salesforce_voicecall_idSi se empujó a SF

Recording

CampoSignificado
id, call_id, tenant_idIdentificación
storage_urlURL pre-firmada
formatwav / mp3 / ogg
duration_sec, size_bytesTamaño
expires_atCuándo se borra (sellado por política)
providersivo_managed / s3 / gcs / azure / minio

Transcript

CampoSignificado
id, call_id, tenant_idIdentificación
providerdeepgram / elevenlabs / whisper
languageISO 639-1 (es, en)
segmentsJSON con turnos: [{speaker, start, end, text}, ...]
expires_atSellado al crear

Audit Log

Inmutable.

CampoSignificado
id, timestampIdentificación
tenant_id, actor_user_idActor
actor_ip, actor_uaOrigen
actioncreate / update / delete / access / login
resource_type, resource_idObjeto afectado
diffJSONB con antes/después
cross_tenantSi fue acción superadmin

Identidades — IDs externos

Para integraciones, SIVO usa estos IDs estables que puedes guardar en tus sistemas:

SistemaID a guardar
Salesforce VoiceCallvendor_call_key (UUID generado por SIVO)
Webhooks tuyosevent_id (UUID por evento)
Tu CRMcall_id de SIVO
Tu sistema de ticketscall_id o transcript_id

Todos son UUIDs, estables, nunca reutilizados.

Variables de sesión IVR

Variables disponibles en cualquier nodo del flow:

VariableValor
caller_id_numberOrigen E.164
caller_id_nameNombre si el operador lo envía
didDID por el que entró
nowTimestamp UTC actual
languageIdioma esperado
attemptN-ésimo intento si hubo retry

Más las custom que defines en nodos input, webhook, function, ai_agent.

Relaciones cruzadas

Una llamada con todo enlazado

Call
 ├── tenant_id        → Tenant
 ├── did_id           → DID            → IVR Flow → Versions → Nodes
 ├── agent_id         → User           → Queue Members → Queues
 ├── queue_id         → Queue
 ├── recording_id     → Recording      → expires según Recording Policy
 ├── transcript_id    → Transcript     → expires según Transcription Policy
 ├── salesforce_voicecall_id → SF VoiceCall + Conversation + ConversationEntries
 └── audit_logs entries asociadas

Eventos emitidos

Cada cambio relevante emite un event consumible vía webhook:

call.created  call.answered  call.transferred  call.ended  call.recorded
queue.entered  queue.abandoned
agent.status_changed  agent.paused
ivr.completed  ai_agent.completed
transcript.segment  transcript.completed
salesforce.voicecall_pushed

Schema completo en Webhooks.

Lo que NO almacena SIVO

Para evitar confusión:

  • Contactos / Leads / Cases: viven en tu CRM (Salesforce, HubSpot, propio). SIVO solo enlaza por caller_id_number.
  • Oportunidades / facturas: tampoco. SIVO es centralita, no CRM.
  • Datos sensibles del caller (DNI, IBAN, etc.): si tu IVR los captura, los pasa a tu sistema vía webhook. SIVO no los guarda salvo en transcripciones (con retención configurable).

API REST

Cada entidad tiene su CRUD en la API:

GET    /api/{resource}
POST   /api/{resource}
GET    /api/{resource}/{id}
PUT    /api/{resource}/{id}
DELETE /api/{resource}/{id}

Documentado en /api con OpenAPI completo.

Buenas prácticas

  1. Usa el UUID de SIVO como source-of-truth para identificar llamadas en tu CRM. No uses el número de teléfono — un caller puede llamar desde varios.
  2. Suscríbete a webhooks específicos (call.ended, transcript.completed) en lugar de hacer poll de la API.
  3. Captura variables en el IVR que necesites para tu BI. Mejor capturar de más que tener que reconstruir.
  4. Documenta tu mapping: qué variable IVR equivale a qué campo en tu CRM. Útil cuando tu equipo crece.
  5. Audita el data-model anual: SIVO añade campos nuevos con cada release. Revisa el changelog para aprovecharlos.