Integration

Voice Agent Integration

Guide for Twilio phone number purchase and voice agent binding.

Idioma:ESENFRPTDE
Última actualización: Apr 8, 2026twiliovoiceintegration

Guía Frontend: Comprar número Twilio y vincularlo a un Agente de Voz (n8n vs Backend)

Esta guía es para el equipo frontend: implementa en UI el flujo completo de:

  1. Comprar un número de teléfono (Twilio) para el usuario
  2. Elegir el Agente de Voz que atenderá llamadas entrantes en ese número:
    • CLIA Voice Agent (n8n)
    • CLIA Voice Agent (Backend Streaming)

Nota de arquitectura: la “vinculación con agente” se aplica configurando el VoiceUrl del número en Twilio, pero a nivel de producto se presenta como elegir entre dos agentes de voz.


0) Prerrequisitos (Frontend)

  • Tener JWT del usuario (
    text
    Authorization: Bearer ...
    ).
  • Conocer
    text
    userId
    .
  • El usuario debe tener
    text
    subscriptionStatus: "active"
    (incluye Free si está activado) para poder buscar/comprar números.
  • Para compra: el usuario debe tener balance suficiente para el cargo único (default $5).

1) UI recomendada (pantalla “Voice / Phone Number”)

Sección A — Estado actual

Mostrar:

  • Número actual:
    text
    user.twilioNumber
    (si existe)
  • Estado de número:
    text
    user.twilioNumberStatus
    (active/suspended)
  • Saldo:
    text
    voiceBalance
    +
    text
    creditLimit
    (para explicar por qué no puede comprar)
  • Agente de voz seleccionado:
    • si el usuario ya tiene número, el backend persiste
      text
      user.voiceAgentId
      (source of truth).

Sección B — Seleccionar agente de voz

Mostrar un selector con 2 agentes (card o radio):

  1. text
    CLIA Voice Agent (n8n)
  2. text
    CLIA Voice Agent (Backend Streaming)

Cómo obtenerlos:

  • text
    GET /agents/catalog?interactionMode=voice
    (o filtrar por
    text
    agentType=voice-assistant
    y
    text
    interactionMode=voice
    )

Recomendación: filtra por

text
interactionMode === "voice"
para no mezclar chat.

Sección C — Comprar número

Wizard:

  1. Seleccionar país / area code (opcional)
  2. Buscar números disponibles
  3. Elegir número y confirmar compra
  4. Si falta “Emergency Address”, redirigir al paso de configurarlo
  5. Comprar (y configurar webhooks según el agente seleccionado)

2) Buscar números disponibles

Endpoint:

  • text
    GET /users/:userId/twilio/numbers/available?country=US&areaCode=415&limit=10

Headers:

  • text
    Authorization: Bearer <jwt>

UI:

  • Lista con
    text
    phoneNumber
    ,
    text
    locality
    ,
    text
    region
    ,
    text
    capabilities
    .
  • Botón “Seleccionar”.

Errores:

  • 403:
    text
    subscriptionStatus
    no es
    text
    active
    .

3) Emergency Address (E911)

La compra puede fallar si el usuario no tiene Emergency Address configurada.

Endpoints:

  • text
    POST /users/:userId/twilio/emergency-address
  • text
    GET /users/:userId/twilio/emergency-address

UI mínima:

  • Form con
    text
    customerName
    ,
    text
    street
    ,
    text
    city
    ,
    text
    region
    ,
    text
    postalCode
    ,
    text
    isoCountry
  • Mostrar estado
    text
    pending|validated|invalid

Comportamiento recomendado:

  • Antes de comprar, llama
    text
    GET /users/:userId/twilio/emergency-address
    • Si no existe, obliga a completar el form

4) Comprar el número y vincularlo al agente de voz

Endpoint:

  • text
    POST /users/:userId/twilio/purchase

Headers:

  • text
    Authorization: Bearer <jwt>
  • text
    Content-Type: application/json

Body (ejemplo - recomendado usando

text
agentId
):

json
{
  "country": "US",
  "areaCode": "415",
  "phoneNumber": "+14155550123",
  "agentId": "AGENT_ID_DEL_CATALOGO_DE_VOZ"
}

Alternativa legacy (compatibilidad):

text
useStreamingAgent

json
{
  "country": "US",
  "areaCode": "415",
  "phoneNumber": "+14155550123",
  "useStreamingAgent": true
}

Mapping: agente seleccionado → request (recomendado)

  • Si el usuario eligió CLIA Voice Agent (n8n) → enviar
    text
    agentId
    de ese agente
  • Si el usuario eligió CLIA Voice Agent (Backend Streaming) → enviar
    text
    agentId
    de ese agente

Respuesta:

  • text
    phoneNumber
    ,
    text
    sid
    ,
    text
    purchaseCost
    ,
    text
    monthlyCost
    ,
    text
    remainingBalance
    , etc.

Errores comunes:

  • 400
    text
    Emergency address required
    : mostrar CTA “Configurar Emergency Address”.
  • 400
    text
    User already has a Twilio number assigned
    : bloquear compra y mostrar “Liberar número” (si aplica).
  • 402
    text
    Insufficient balance
    : llevar a recarga/billing.

5) Cambiar el Agente de Voz después de comprar

Si el usuario ya tiene número comprado, puede cambiar de agente (reconfigura el VoiceUrl en Twilio):

  • text
    PUT /users/:userId/twilio/agent

Body:

json
{ "agentId": "AGENT_ID_DEL_CATALOGO_DE_VOZ" }

Alternativa legacy:

json
{ "useStreamingAgent": true }

Respuesta incluye:

  • text
    agentType
    :
    text
    "streaming"
    o
    text
    "n8n"
  • text
    voiceWebhookUrl
    : la URL configurada en Twilio
  • text
    agentId
    : el
    text
    Agent._id
    persistido/seleccionado (si está disponible)

UI:

  • Mostrar confirmación “Agente actualizado”.
  • Mostrar
    text
    voiceWebhookUrl
    como información diagnóstica.

6) Prueba rápida (manual)

  1. Comprar número
  2. Seleccionar agente
  3. Llamar al número y verificar:
  • Agente n8n: flujo controlado por workflow
  • Agente backend: flujo
    text
    media-stream-*
    (barge-in disponible)

7) Nota sobre “2 agentes” en catálogo

Para que el frontend pueda mostrar ambos como seleccionables:

  • Ambos deben existir como
    text
    Agent
    de tipo voz en BD (system agents).
  • Si el ambiente no los tiene, correr el seed:
    • text
      npx ts-node src/scripts/seed-system-agents.ts