Skip to content

Rutas entrantes ​

Generado desde DialerDigital/core commit 0fc18008b3c8 — especificación openapi/dialer-v1.yaml v0.134.0. No se edita a mano; consulta Cómo se construye esta referencia. Descargar la especificación OpenAPI.

English version

Traducción en curso

Esta referencia se genera desde la especificación OpenAPI. Las cadenas que todavía no tienen traducción aparecen en inglés.

Enrutamiento de DID entrantes + aprovisionamiento del SBC.

Endpoints ​

MétodoRutaResumen
GET/v1/inbound-routesListar las rutas entrantes
POST/v1/inbound-routesCrear una ruta entrante
GET/v1/inbound-routes/{id}Obtener una ruta entrante
PATCH/v1/inbound-routes/{id}Actualizar una ruta entrante (e164 inmutable)
POST/v1/inbound-routes/{id}/provisionEmpujar la ruta al borde SIP
POST/v1/inbound-routes/{id}/disableDeshabilitar una ruta entrante

Listar las rutas entrantes ​

http
GET /v1/inbound-routes

Respuestas

200 ​

Las rutas entrantes del tenant.

CampoTipoObligatorioDescripción
inbound_routesarreglo de InboundRoutesí
inbound_routes[].idstring (uuid)no
inbound_routes[].tenant_idstring (uuid)no
inbound_routes[].e164stringnoInmutable tras la creación.
inbound_routes[].dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta el menú IVR entrante que nombra dest_ref (core#1319). Una ruta guardada antes de core#1311 sin menú se sigue rechazando al conectar con CALL_REJECTED. optout es el número de baja (core#1316): el número que llama se añade a la lista de no llamar propia del tenant al conectar y FreeSWITCH confirma y cuelga; una ruta así siempre lee dest_ref: null, recording: false, ai_enabled: false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
inbound_routes[].dest_refstring | nullno
inbound_routes[].queue_idstring,null (uuid)noLa cola de una ruta queue (core#1347); null en cualquier otro tipo, y en una ruta queue guardada sin ella.
inbound_routes[].ai_agent_idstring,null (uuid)noEl agente de IA de una ruta ai_agent (core#1547); null en cualquier otro tipo.
inbound_routes[].hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530), o null cuando contesta a todas horas. Un mensaje closed se lee de vuelta como el texto que se envió.
inbound_routes[].recordingbooleanno
inbound_routes[].ai_enabledbooleannotrue si y solo si dest_type es ai_agent (derivado, ADR #200); false en cualquier otro tipo. Una escritura que nombre lo contrario da 400 (ADR #148). Las rutas que tenían true antes de que se rechazara el indicador se apagaron con una migración de datos.
inbound_routes[].statusactive · disabledno
inbound_routes[].notesstring | nullno
inbound_routes[].created_atstring (date-time)no
inbound_routes[].updated_atstring (date-time)no

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Crear una ruta entrante ​

http
POST /v1/inbound-routes

e164 es inmutable tras la creación; el router inyecta tenant_id.

Cuerpo de la petición (JSON, obligatorio)

CampoTipoObligatorioDescripción
e164stringsíE.164 (inmutable tras la creación). Debe ser un número de ESTA cuenta (uno registrado con /v1/dids, o un número house asignado a ella, core#2414): un número que es de otra cuenta o que nadie registró da 422 unprocessable (e164 not a number of this account). Un PATCH que devuelve una ruta a active se juzga igual; una ruta que ya existe nunca se vuelve a juzgar.
dest_typeagent · queue · ivr · optout · ai_agentsíivr ejecuta uno de los menús IVR entrantes del tenant (core#1319): dest_ref es OBLIGATORIO y debe ser el id de un menú publicado con /v1/inbound-ivr-menus en esta cuenta y no retirado, o la escritura da 400 invalid. Cada llamada oye la versión del menú vigente cuando se conecta; FreeSWITCH la contesta tras el veredicto del plan, core reproduce los avisos de voz, y la tecla (o, tras dos ventanas de silencio, el default del menú) la envía a una cola, un agente, la baja o un colgado. optout es el número de baja (core#1316, 47 CFR 64.1200(b)(3)): el número que llama se añade a la lista de no llamar propia del tenant cuando la llamada se conecta, antes de que conteste nada y sea cual sea el plan del tenant; con un plan activo, FreeSWITCH reproduce entonces una confirmación compuesta por la plataforma que nombra al vendedor del tenant (o un tono) y cuelga, con un plan apagado la llamada se rechaza sin contestar. Un llamante sin número utilizable (oculto o no válido) se rechaza y no se registra nada. Una ruta optout es desnuda: un dest_ref no nulo, recording: true o ai_enabled: true en la misma escritura se rechazan con 400 invalid; si se omiten, se fijan en ninguno/false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
dest_refstring (uuid)noObligatorio para agent (el id del agente) y para ivr (el id de un menú IVR entrante publicado y no retirado de esta cuenta, si no 400 invalid); un valor no nulo se rechaza en una ruta optout. Un valor que no es un UUID canónico se rechaza con 400 invalid (dest_ref must be a UUID, core#1338).
queue_idstring (uuid)noLa cola de una ruta queue (core#1347) o la cola de respaldo de una ruta ai_agent (core#1547): una cola ACTIVA de esta cuenta creada con /v1/inbound-queues; una retirada, de otra cuenta, inexistente o un id mal formado da 400 invalid. OBLIGATORIA en una ruta ai_agent (core#1547): la cola a la que recurre la llamada, sujeta a la misma regla. Se rechaza en cualquier otro dest_type. Opcional en una ruta queue: sin ella una ruta queue se acepta, como antes, y rechaza sus llamadas al conectar. Un PATCH que mueve la ruta a otro tipo sin nombrarla la elimina.
ai_agent_idstring (uuid)noOBLIGATORIO en una ruta ai_agent (core#1547, ADR #200): el id de un agente de IA live de esta cuenta, creado con /v1/ai/agents; uno en borrador, en pausa o retirado, de otra cuenta, inexistente o un id mal formado da 400 invalid. Se rechaza en cualquier otro dest_type; un PATCH que mueve la ruta a otro tipo sin nombrarlo lo elimina. El agente se juzga EN LA ESCRITURA (un PATCH que apunta la ruta a un agente o la devuelve a active): ponerlo en pausa después no toca la ruta, y retirarlo mientras una ruta activa lo nombra da 409 en PATCH /v1/ai/agents/{id} y DELETE /v1/ai/agents/{id}.
hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530, ADR #304). Ausente o null = el número contesta a todas horas, exactamente como antes; en un PATCH, null ELIMINA el horario y omitir la clave lo conserva. Fuera del horario, o en un festivo, una llamada NUEVA se trata como indica la ruta closed (un mensaje u otro destino); una llamada ya admitida nunca se corta cuando pasa la hora de cierre. Una ruta optout no tiene horario: enviarlo con dest_type: optout, o mover una ruta que lo tiene a optout sin hours: null en la misma escritura, da 422. Una zona que no se resuelve, un festivo mal formado o repetido, más de 366 festivos, un closed que no es exactamente una de sus dos formas, o uno que nombra una cola, menú, agente o agente de IA que no está vivo en esta cuenta da 422 unprocessable. El mensaje closed se convierte en audio cuando se guarda el horario; si no se puede, la escritura da 503 prompt_render_failed y no se guarda nada. Una ruta con horario se aprovisiona anclada en FreeSWITCH (de otro modo, una ruta agent sin recording se entrega directamente al agente y core nunca ve la llamada): tras escribir el horario, haz POST /v1/inbound-routes/{id}/provision para que el borde SIP lo conozca.
recordingbooleannotrue se rechaza en una ruta optout y en una ruta ai_agent (el tramo de IA no se graba, ADR #200); si se omite ahí, es false. Por defecto true en cualquier otra ruta.
ai_enabledbooleannoDerivado del destino, no elegido (ADR #148, ADR #200): true si y solo si dest_type es ai_agent. Nombrar true en cualquier otro destino, o false en una ruta ai_agent, da 400 invalid (ai_enabled is derived from the destination ...); omítelo, o envía el valor que implica el destino (por defecto false).
notesstringno
json
{
  "e164": "+13125550171",
  "dest_type": "queue"
}

Respuestas

201 ​

Ruta creada.

CampoTipoObligatorioDescripción
inbound_routeobject (InboundRoute)sí
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoInmutable tras la creación.
inbound_route.dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta el menú IVR entrante que nombra dest_ref (core#1319). Una ruta guardada antes de core#1311 sin menú se sigue rechazando al conectar con CALL_REJECTED. optout es el número de baja (core#1316): el número que llama se añade a la lista de no llamar propia del tenant al conectar y FreeSWITCH confirma y cuelga; una ruta así siempre lee dest_ref: null, recording: false, ai_enabled: false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
inbound_route.dest_refstring | nullno
inbound_route.queue_idstring,null (uuid)noLa cola de una ruta queue (core#1347); null en cualquier otro tipo, y en una ruta queue guardada sin ella.
inbound_route.ai_agent_idstring,null (uuid)noEl agente de IA de una ruta ai_agent (core#1547); null en cualquier otro tipo.
inbound_route.hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530), o null cuando contesta a todas horas. Un mensaje closed se lee de vuelta como el texto que se envió.
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleannotrue si y solo si dest_type es ai_agent (derivado, ADR #200); false en cualquier otro tipo. Una escritura que nombre lo contrario da 400 (ADR #148). Las rutas que tenían true antes de que se rechazara el indicador se apagaron con una migración de datos.
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

409 — Conflict ​

Transición de estado no válida, conflicto de unicidad, o un asiento que está ocupado/reservado.

json
{
  "error": {
    "code": "conflict",
    "message": "invalid state transition"
  }
}

422 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

503 ​

El mensaje closed del horario no se pudo convertir en audio (prompt_render_failed); la ruta no se guardó. La petición es correcta y puede funcionar cuando responda el texto a voz.

Obtener una ruta entrante ​

http
GET /v1/inbound-routes/{id}

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Respuestas

200 ​

La ruta.

CampoTipoObligatorioDescripción
inbound_routeobject (InboundRoute)sí
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoInmutable tras la creación.
inbound_route.dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta el menú IVR entrante que nombra dest_ref (core#1319). Una ruta guardada antes de core#1311 sin menú se sigue rechazando al conectar con CALL_REJECTED. optout es el número de baja (core#1316): el número que llama se añade a la lista de no llamar propia del tenant al conectar y FreeSWITCH confirma y cuelga; una ruta así siempre lee dest_ref: null, recording: false, ai_enabled: false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
inbound_route.dest_refstring | nullno
inbound_route.queue_idstring,null (uuid)noLa cola de una ruta queue (core#1347); null en cualquier otro tipo, y en una ruta queue guardada sin ella.
inbound_route.ai_agent_idstring,null (uuid)noEl agente de IA de una ruta ai_agent (core#1547); null en cualquier otro tipo.
inbound_route.hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530), o null cuando contesta a todas horas. Un mensaje closed se lee de vuelta como el texto que se envió.
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleannotrue si y solo si dest_type es ai_agent (derivado, ADR #200); false en cualquier otro tipo. Una escritura que nombre lo contrario da 400 (ADR #148). Las rutas que tenían true antes de que se rechazara el indicador se apagaron con una migración de datos.
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Actualizar una ruta entrante (e164 inmutable) ​

http
PATCH /v1/inbound-routes/{id}

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Cuerpo de la petición (JSON, obligatorio)

CampoTipoObligatorioDescripción
dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta uno de los menús IVR entrantes del tenant (core#1319): dest_ref es OBLIGATORIO y debe ser el id de un menú publicado con /v1/inbound-ivr-menus en esta cuenta y no retirado, o la escritura da 400 invalid. Cada llamada oye la versión del menú vigente cuando se conecta; FreeSWITCH la contesta tras el veredicto del plan, core reproduce los avisos de voz, y la tecla (o, tras dos ventanas de silencio, el default del menú) la envía a una cola, un agente, la baja o un colgado. optout es el número de baja (core#1316, 47 CFR 64.1200(b)(3)): el número que llama se añade a la lista de no llamar propia del tenant cuando la llamada se conecta, antes de que conteste nada y sea cual sea el plan del tenant; con un plan activo, FreeSWITCH reproduce entonces una confirmación compuesta por la plataforma que nombra al vendedor del tenant (o un tono) y cuelga, con un plan apagado la llamada se rechaza sin contestar. Un llamante sin número utilizable (oculto o no válido) se rechaza y no se registra nada. Una ruta optout es desnuda: un dest_ref no nulo, recording: true o ai_enabled: true en la misma escritura se rechazan con 400 invalid; si se omiten, se fijan en ninguno/false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
dest_refstring (uuid)noObligatorio para agent (el id del agente) y para ivr (el id de un menú IVR entrante publicado y no retirado de esta cuenta, si no 400 invalid); un valor no nulo se rechaza en una ruta optout. Un valor que no es un UUID canónico se rechaza con 400 invalid (dest_ref must be a UUID, core#1338).
queue_idstring (uuid)noLa cola de una ruta queue (core#1347) o la cola de respaldo de una ruta ai_agent (core#1547): una cola ACTIVA de esta cuenta creada con /v1/inbound-queues; una retirada, de otra cuenta, inexistente o un id mal formado da 400 invalid. OBLIGATORIA en una ruta ai_agent (core#1547): la cola a la que recurre la llamada, sujeta a la misma regla. Se rechaza en cualquier otro dest_type. Opcional en una ruta queue: sin ella una ruta queue se acepta, como antes, y rechaza sus llamadas al conectar. Un PATCH que mueve la ruta a otro tipo sin nombrarla la elimina.
ai_agent_idstring (uuid)noOBLIGATORIO en una ruta ai_agent (core#1547, ADR #200): el id de un agente de IA live de esta cuenta, creado con /v1/ai/agents; uno en borrador, en pausa o retirado, de otra cuenta, inexistente o un id mal formado da 400 invalid. Se rechaza en cualquier otro dest_type; un PATCH que mueve la ruta a otro tipo sin nombrarlo lo elimina. El agente se juzga EN LA ESCRITURA (un PATCH que apunta la ruta a un agente o la devuelve a active): ponerlo en pausa después no toca la ruta, y retirarlo mientras una ruta activa lo nombra da 409 en PATCH /v1/ai/agents/{id} y DELETE /v1/ai/agents/{id}.
hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530, ADR #304). Ausente o null = el número contesta a todas horas, exactamente como antes; en un PATCH, null ELIMINA el horario y omitir la clave lo conserva. Fuera del horario, o en un festivo, una llamada NUEVA se trata como indica la ruta closed (un mensaje u otro destino); una llamada ya admitida nunca se corta cuando pasa la hora de cierre. Una ruta optout no tiene horario: enviarlo con dest_type: optout, o mover una ruta que lo tiene a optout sin hours: null en la misma escritura, da 422. Una zona que no se resuelve, un festivo mal formado o repetido, más de 366 festivos, un closed que no es exactamente una de sus dos formas, o uno que nombra una cola, menú, agente o agente de IA que no está vivo en esta cuenta da 422 unprocessable. El mensaje closed se convierte en audio cuando se guarda el horario; si no se puede, la escritura da 503 prompt_render_failed y no se guarda nada. Una ruta con horario se aprovisiona anclada en FreeSWITCH (de otro modo, una ruta agent sin recording se entrega directamente al agente y core nunca ve la llamada): tras escribir el horario, haz POST /v1/inbound-routes/{id}/provision para que el borde SIP lo conozca.
recordingbooleannotrue se rechaza en una ruta optout y en una ruta ai_agent (el tramo de IA no se graba, ADR #200); si se omite ahí, es false. Por defecto true en cualquier otra ruta.
ai_enabledbooleannoDerivado del destino, no elegido (ADR #148, ADR #200): true si y solo si dest_type es ai_agent. Nombrar true en cualquier otro destino, o false en una ruta ai_agent, da 400 invalid (ai_enabled is derived from the destination ...); omítelo, o envía el valor que implica el destino (por defecto false).
statusactive · disabledno
notesstringno
json
{
  "recording": false
}

Respuestas

200 ​

Ruta actualizada.

CampoTipoObligatorioDescripción
inbound_routeobject (InboundRoute)sí
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoInmutable tras la creación.
inbound_route.dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta el menú IVR entrante que nombra dest_ref (core#1319). Una ruta guardada antes de core#1311 sin menú se sigue rechazando al conectar con CALL_REJECTED. optout es el número de baja (core#1316): el número que llama se añade a la lista de no llamar propia del tenant al conectar y FreeSWITCH confirma y cuelga; una ruta así siempre lee dest_ref: null, recording: false, ai_enabled: false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
inbound_route.dest_refstring | nullno
inbound_route.queue_idstring,null (uuid)noLa cola de una ruta queue (core#1347); null en cualquier otro tipo, y en una ruta queue guardada sin ella.
inbound_route.ai_agent_idstring,null (uuid)noEl agente de IA de una ruta ai_agent (core#1547); null en cualquier otro tipo.
inbound_route.hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530), o null cuando contesta a todas horas. Un mensaje closed se lee de vuelta como el texto que se envió.
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleannotrue si y solo si dest_type es ai_agent (derivado, ADR #200); false en cualquier otro tipo. Una escritura que nombre lo contrario da 400 (ADR #148). Las rutas que tenían true antes de que se rechazara el indicador se apagaron con una migración de datos.
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

422 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

503 ​

El mensaje closed del horario no se pudo convertir en audio (prompt_render_failed); la ruta no se guardó. La petición es correcta y puede funcionar cuando responda el texto a voz.

Empujar la ruta al borde SIP ​

http
POST /v1/inbound-routes/{id}/provision

409 cuando la ruta está deshabilitada; 422 cuando el agente de destino no se puede resolver para esta sede o no tiene extensión SIP (puesto) a la que entregar; 200 {"status": "sbc_disabled"} cuando no hay KAMAILIO_RPC_URL configurada.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Respuestas

200 ​

Aprovisionada (o SBC deshabilitado en este entorno).

CampoTipoObligatorioDescripción
statusprovisioned · sbc_disabledsísbc_disabled = no hay KAMAILIO_RPC_URL en este entorno; la intención de la fila queda registrada, no empujada.

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

409 — Conflict ​

Transición de estado no válida, conflicto de unicidad, o un asiento que está ocupado/reservado.

json
{
  "error": {
    "code": "conflict",
    "message": "invalid state transition"
  }
}

422 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

502 — SbcError ​

El borde SIP rechazó la petición de aprovisionamiento.

json
{
  "error": {
    "code": "sbc_error",
    "message": "the SIP edge rejected the provisioning request"
  }
}

Deshabilitar una ruta entrante ​

http
POST /v1/inbound-routes/{id}/disable

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Respuestas

200 ​

La ruta deshabilitada.

CampoTipoObligatorioDescripción
inbound_routeobject (InboundRoute)sí
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoInmutable tras la creación.
inbound_route.dest_typeagent · queue · ivr · optout · ai_agentnoivr ejecuta el menú IVR entrante que nombra dest_ref (core#1319). Una ruta guardada antes de core#1311 sin menú se sigue rechazando al conectar con CALL_REJECTED. optout es el número de baja (core#1316): el número que llama se añade a la lista de no llamar propia del tenant al conectar y FreeSWITCH confirma y cuelga; una ruta así siempre lee dest_ref: null, recording: false, ai_enabled: false. agent puentea directamente al agente registrado; queue ancla el tramo en FreeSWITCH. Hoy la imagen de FreeSWITCH de producción no incluye extensiones de cola (ADR #104 D13: el corral de aparcamiento y dd_queue_hold son una dependencia pendiente de freeswitch, aún no entregada), así que FreeSWITCH cuelga un tramo de cola como UNALLOCATED_NUMBER sea cual sea el indicador. Cuando se entreguen: con el indicador inbound_queue_stream_enabled del tenant ACTIVADO y su agent_session_journal_enabled también ACTIVADO (core#1354: con el diario de puestos APAGADO la llamada se rechaza sin contestar, ya que no habría agente al que ofrecérsela), core admite la llamada en la cola de la ruta (enqueued), la extensión contesta con un tono generado, el propietario la ofrece al agente Ready más antiguo y la puentea (MT-CTI-17 FASE 3); con el indicador APAGADO (por defecto): el tramo termina sin contestar en el corral. ai_agent nombra un agente de IA de voz de la cuenta (core#1547, ADR #200): ai_agent_id (un agente live de esta cuenta) y queue_id (la cola activa a la que recurre la llamada) son OBLIGATORIOS, o la escritura da 400 invalid; ai_enabled lee true y recording false, ambos derivados del tipo, no elegidos. La admisión se decide antes de contestar la llamada (core#1548, ADR #200 decisión 3): con el indicador inbound_ai_enabled del tenant apagado (por defecto) o si falla cualquiera de sus comprobaciones, la llamada se trata como una llamada a la cola queue_id y no la contesta la IA; el motivo queda registrado en la evidencia del CDR de la llamada (compliance_snapshot.inbound_ai). Todavía nada entrega una llamada al agente (la bifurcación es una entrega posterior del ADR #200), así que una llamada a este número no la contesta la IA.
inbound_route.dest_refstring | nullno
inbound_route.queue_idstring,null (uuid)noLa cola de una ruta queue (core#1347); null en cualquier otro tipo, y en una ruta queue guardada sin ella.
inbound_route.ai_agent_idstring,null (uuid)noEl agente de IA de una ruta ai_agent (core#1547); null en cualquier otro tipo.
inbound_route.hoursInboundRouteHours | nullnoEl horario de la ruta (core#2530), o null cuando contesta a todas horas. Un mensaje closed se lee de vuelta como el texto que se envió.
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleannotrue si y solo si dest_type es ai_agent (derivado, ADR #200); false en cualquier otro tipo. Una escritura que nombre lo contrario da 400 (ADR #148). Las rutas que tenían true antes de que se rechazara el indicador se apagaron con una migración de datos.
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Nothing in these docs is legal advice — always confirm compliance posture with your own counsel.