Skip to content

Inbound routes

Generated from DialerDigital/core commit 6e9f026f0a72 — spec openapi/dialer-v1.yaml v0.36.0. Do not edit by hand; see How this reference is built. Download the OpenAPI spec.

Inbound DID routing + SBC provisioning.

Endpoints

MethodPathSummary
GET/v1/inbound-routesList inbound routes
POST/v1/inbound-routesCreate an inbound route
GET/v1/inbound-routes/{id}Fetch one inbound route
PATCH/v1/inbound-routes/{id}Update an inbound route (e164 immutable)
POST/v1/inbound-routes/{id}/provisionPush the route to the SIP edge
POST/v1/inbound-routes/{id}/disableDisable an inbound route

List inbound routes

http
GET /v1/inbound-routes

Responses

200

The tenant's inbound routes.

FieldTypeRequiredDescription
inbound_routesarray of InboundRouteyes
inbound_routes[].idstring (uuid)no
inbound_routes[].tenant_idstring (uuid)no
inbound_routes[].e164stringnoImmutable after creation.
inbound_routes[].dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
inbound_routes[].dest_refstring | nullno
inbound_routes[].recordingbooleanno
inbound_routes[].ai_enabledbooleanno
inbound_routes[].statusactive · disabledno
inbound_routes[].notesstring | nullno
inbound_routes[].created_atstring (date-time)no
inbound_routes[].updated_atstring (date-time)no

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

Create an inbound route

http
POST /v1/inbound-routes

e164 is immutable after creation; tenant_id is injected by the router.

Request body (JSON, required)

FieldTypeRequiredDescription
e164stringyesE.164 (immutable after creation).
dest_typeagent · queue · ivryesagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
dest_refstringno
recordingbooleanno
ai_enabledbooleanno
notesstringno
json
{
  "e164": "+13125550171",
  "dest_type": "ivr"
}

Responses

201

Created route.

FieldTypeRequiredDescription
inbound_routeobject (InboundRoute)yes
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoImmutable after creation.
inbound_route.dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
inbound_route.dest_refstring | nullno
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleanno
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest

Malformed request (shape/type errors, invalid filters, bad timestamps).

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

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

409 — Conflict

Invalid state transition, uniqueness conflict, or a seat that is busy/reserved.

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

Fetch one inbound route

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

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Responses

200

The route.

FieldTypeRequiredDescription
inbound_routeobject (InboundRoute)yes
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoImmutable after creation.
inbound_route.dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
inbound_route.dest_refstring | nullno
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleanno
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

404 — NotFound

Unknown id, malformed (non-UUID) id OR another tenant's id — RLS returns zero rows, so all three are indistinguishable by design (no existence leak, never a 403 for foreign ids).

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

Update an inbound route (e164 immutable)

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

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Request body (JSON, required)

FieldTypeRequiredDescription
dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
dest_refstringno
recordingbooleanno
ai_enabledbooleanno
statusactive · disabledno
notesstringno
json
{
  "recording": false
}

Responses

200

Updated route.

FieldTypeRequiredDescription
inbound_routeobject (InboundRoute)yes
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoImmutable after creation.
inbound_route.dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
inbound_route.dest_refstring | nullno
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleanno
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest

Malformed request (shape/type errors, invalid filters, bad timestamps).

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

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

404 — NotFound

Unknown id, malformed (non-UUID) id OR another tenant's id — RLS returns zero rows, so all three are indistinguishable by design (no existence leak, never a 403 for foreign ids).

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

Push the route to the SIP edge

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

409 when the route is disabled; 422 when the destination agent cannot be resolved for this sede or has no SIP extension (seat) to deliver to; 200 {"status": "sbc_disabled"} when no KAMAILIO_RPC_URL is configured.

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Responses

200

Provisioned (or SBC disabled in this environment).

FieldTypeRequiredDescription
statusprovisioned · sbc_disabledyessbc_disabled = no KAMAILIO_RPC_URL in this environment; the row's intent is recorded, not pushed.

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

404 — NotFound

Unknown id, malformed (non-UUID) id OR another tenant's id — RLS returns zero rows, so all three are indistinguishable by design (no existence leak, never a 403 for foreign ids).

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

409 — Conflict

Invalid state transition, uniqueness conflict, or a seat that is busy/reserved.

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

422 — Unprocessable

Shape is fine, semantics are not (broken domain rule).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at must be at least 10 minutes out"
  }
}

502 — SbcError

The SIP edge rejected the provisioning request.

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

Disable an inbound route

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

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Responses

200

The disabled route.

FieldTypeRequiredDescription
inbound_routeobject (InboundRoute)yes
inbound_route.idstring (uuid)no
inbound_route.tenant_idstring (uuid)no
inbound_route.e164stringnoImmutable after creation.
inbound_route.dest_typeagent · queue · ivrnoagent bridges straight to the registered agent; ivr runs the IVR engine on FreeSWITCH; queue anchors the leg on FreeSWITCH. Today the production FreeSWITCH image ships no queue extensions (ADR #104 D13: the park pen and dd_queue_hold are a pending freeswitch dependency, not yet delivered), so a queue leg is hung up by FreeSWITCH as UNALLOCATED_NUMBER regardless of the flag. Once they ship: with the tenant's inbound_queue_stream_enabled flag ON, core admits the call to the route's queue (enqueued), the extension answers with a generated tone, the owner offers it to the oldest Ready agent and bridges it (MT-CTI-17 FASE 3); flag OFF (default): the leg ends unanswered in the pen.
inbound_route.dest_refstring | nullno
inbound_route.recordingbooleanno
inbound_route.ai_enabledbooleanno
inbound_route.statusactive · disabledno
inbound_route.notesstring | nullno
inbound_route.created_atstring (date-time)no
inbound_route.updated_atstring (date-time)no

400 — BadRequest

Malformed request (shape/type errors, invalid filters, bad timestamps).

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

401 — Unauthorized

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature).

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

404 — NotFound

Unknown id, malformed (non-UUID) id OR another tenant's id — RLS returns zero rows, so all three are indistinguishable by design (no existence leak, never a 403 for foreign ids).

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

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