Inbound routes
Generated from
DialerDigital/corecommit6e9f026f0a72— specopenapi/dialer-v1.yamlv0.36.0. Do not edit by hand; see How this reference is built. Download the OpenAPI spec.
Inbound DID routing + SBC provisioning.
Endpoints
| Method | Path | Summary |
|---|---|---|
GET | /v1/inbound-routes | List inbound routes |
POST | /v1/inbound-routes | Create 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}/provision | Push the route to the SIP edge |
POST | /v1/inbound-routes/{id}/disable | Disable an inbound route |
List inbound routes
GET /v1/inbound-routesResponses
200
The tenant's inbound routes.
| Field | Type | Required | Description |
|---|---|---|---|
inbound_routes | array of InboundRoute | yes | |
inbound_routes[].id | string (uuid) | no | |
inbound_routes[].tenant_id | string (uuid) | no | |
inbound_routes[].e164 | string | no | Immutable after creation. |
inbound_routes[].dest_type | agent · queue · ivr | no | agent 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_ref | string | null | no | |
inbound_routes[].recording | boolean | no | |
inbound_routes[].ai_enabled | boolean | no | |
inbound_routes[].status | active · disabled | no | |
inbound_routes[].notes | string | null | no | |
inbound_routes[].created_at | string (date-time) | no | |
inbound_routes[].updated_at | string (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).
{
"error": {
"code": "unauthorized",
"message": "invalid or revoked API key"
}
}Create an inbound route
POST /v1/inbound-routese164 is immutable after creation; tenant_id is injected by the router.
Request body (JSON, required)
| Field | Type | Required | Description |
|---|---|---|---|
e164 | string | yes | E.164 (immutable after creation). |
dest_type | agent · queue · ivr | yes | agent 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_ref | string | no | |
recording | boolean | no | |
ai_enabled | boolean | no | |
notes | string | no |
{
"e164": "+13125550171",
"dest_type": "ivr"
}Responses
201
Created route.
| Field | Type | Required | Description |
|---|---|---|---|
inbound_route | object (InboundRoute) | yes | |
inbound_route.id | string (uuid) | no | |
inbound_route.tenant_id | string (uuid) | no | |
inbound_route.e164 | string | no | Immutable after creation. |
inbound_route.dest_type | agent · queue · ivr | no | agent 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_ref | string | null | no | |
inbound_route.recording | boolean | no | |
inbound_route.ai_enabled | boolean | no | |
inbound_route.status | active · disabled | no | |
inbound_route.notes | string | null | no | |
inbound_route.created_at | string (date-time) | no | |
inbound_route.updated_at | string (date-time) | no |
400 — BadRequest
Malformed request (shape/type errors, invalid filters, bad timestamps).
{
"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).
{
"error": {
"code": "unauthorized",
"message": "invalid or revoked API key"
}
}409 — Conflict
Invalid state transition, uniqueness conflict, or a seat that is busy/reserved.
{
"error": {
"code": "conflict",
"message": "invalid state transition"
}
}Fetch one inbound route
GET /v1/inbound-routes/{id}Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | yes | Resource UUID. Malformed or cross-tenant ids read as 404. |
Responses
200
The route.
| Field | Type | Required | Description |
|---|---|---|---|
inbound_route | object (InboundRoute) | yes | |
inbound_route.id | string (uuid) | no | |
inbound_route.tenant_id | string (uuid) | no | |
inbound_route.e164 | string | no | Immutable after creation. |
inbound_route.dest_type | agent · queue · ivr | no | agent 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_ref | string | null | no | |
inbound_route.recording | boolean | no | |
inbound_route.ai_enabled | boolean | no | |
inbound_route.status | active · disabled | no | |
inbound_route.notes | string | null | no | |
inbound_route.created_at | string (date-time) | no | |
inbound_route.updated_at | string (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).
{
"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).
{
"error": {
"code": "not_found",
"message": "resource not found for this tenant"
}
}Update an inbound route (e164 immutable)
PATCH /v1/inbound-routes/{id}Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | yes | Resource UUID. Malformed or cross-tenant ids read as 404. |
Request body (JSON, required)
| Field | Type | Required | Description |
|---|---|---|---|
dest_type | agent · queue · ivr | no | agent 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_ref | string | no | |
recording | boolean | no | |
ai_enabled | boolean | no | |
status | active · disabled | no | |
notes | string | no |
{
"recording": false
}Responses
200
Updated route.
| Field | Type | Required | Description |
|---|---|---|---|
inbound_route | object (InboundRoute) | yes | |
inbound_route.id | string (uuid) | no | |
inbound_route.tenant_id | string (uuid) | no | |
inbound_route.e164 | string | no | Immutable after creation. |
inbound_route.dest_type | agent · queue · ivr | no | agent 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_ref | string | null | no | |
inbound_route.recording | boolean | no | |
inbound_route.ai_enabled | boolean | no | |
inbound_route.status | active · disabled | no | |
inbound_route.notes | string | null | no | |
inbound_route.created_at | string (date-time) | no | |
inbound_route.updated_at | string (date-time) | no |
400 — BadRequest
Malformed request (shape/type errors, invalid filters, bad timestamps).
{
"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).
{
"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).
{
"error": {
"code": "not_found",
"message": "resource not found for this tenant"
}
}Push the route to the SIP edge
POST /v1/inbound-routes/{id}/provision409 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | yes | Resource UUID. Malformed or cross-tenant ids read as 404. |
Responses
200
Provisioned (or SBC disabled in this environment).
| Field | Type | Required | Description |
|---|---|---|---|
status | provisioned · sbc_disabled | yes | sbc_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).
{
"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).
{
"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.
{
"error": {
"code": "conflict",
"message": "invalid state transition"
}
}422 — Unprocessable
Shape is fine, semantics are not (broken domain rule).
{
"error": {
"code": "unprocessable",
"message": "scheduled_at must be at least 10 minutes out"
}
}502 — SbcError
The SIP edge rejected the provisioning request.
{
"error": {
"code": "sbc_error",
"message": "the SIP edge rejected the provisioning request"
}
}Disable an inbound route
POST /v1/inbound-routes/{id}/disableParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | yes | Resource UUID. Malformed or cross-tenant ids read as 404. |
Responses
200
The disabled route.
| Field | Type | Required | Description |
|---|---|---|---|
inbound_route | object (InboundRoute) | yes | |
inbound_route.id | string (uuid) | no | |
inbound_route.tenant_id | string (uuid) | no | |
inbound_route.e164 | string | no | Immutable after creation. |
inbound_route.dest_type | agent · queue · ivr | no | agent 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_ref | string | null | no | |
inbound_route.recording | boolean | no | |
inbound_route.ai_enabled | boolean | no | |
inbound_route.status | active · disabled | no | |
inbound_route.notes | string | null | no | |
inbound_route.created_at | string (date-time) | no | |
inbound_route.updated_at | string (date-time) | no |
400 — BadRequest
Malformed request (shape/type errors, invalid filters, bad timestamps).
{
"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).
{
"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).
{
"error": {
"code": "not_found",
"message": "resource not found for this tenant"
}
}