Carrier Integrations

    Run tests through your own SIP trunk: find your trunk, manage the routes on it, and point test configs at a route.

    6 endpoints

    Invite-only. With a carrier integration, test calls leave through your own SIP trunk (your SBC) instead of our network, so you can test the vendor routes behind it. We set up the trunk with you: host, port, transport, the addresses to allowlist, and its limits. After that you manage its routes yourself, in the app or through these endpoints.

    1. Find your trunk. GET /testing/carrier-integrations returns its integrationId.
    2. Add a route for each code your SBC routes on: POST /testing/carrier-integrations/{integrationId}/routes with a techPrefix such as R7Q2#. A call to +5511400420xx on that route is sent as sip:R7Q2%235511400420xx@your-sbc.
    3. Point a test at the route. Create a test config (Testing) with the number to call, its steps, and carrierRouteId set to the route's routeId.
    4. Run it and read the result. POST /testing/runs with the testConfigId, then poll GET /testing/runs/{id}. Each entry in stepResults gives the digits sent (actionType, actionValue), what the IVR said (actualTranscript) and the step's outcome. The run carries the route it used (carrier) and the SIP hang-up cause (callTelemetry.telephony.sipHangupCause).

    Each trunk has a limit on calls at once (extra calls wait their turn) and on minutes per UTC day (runs over it are refused with 429 until 00:00 UTC). Ask us to change either. End a test with a listen step after the last DTMF, so the IVR's response to it is captured.

    List carrier integrations

    GET/testing/carrier-integrations

    The workspace's SIP trunks, each with the routes reached through it, sorted by name. A route's `dialable` says whether a run would be placed on it now: its trunk is `active` and the route is enabled. Needs the `testing:read` scope.

    Request

    bash
    curl -H "x-api-key: YOUR_API_KEY" \
      https://api.nopaque.co.uk/testing/carrier-integrations

    Response

    json
    {
      "integrations": [
        {
          "integrationId": "ci_8836db3c",
          "name": "Integral SBC",
          "host": "203.0.113.10",
          "port": 5060,
          "transport": "UDP",
          "mediaEncryption": "disabled",
          "status": "active",
          "hasCredentials": false,
          "maxConcurrentCalls": 5,
          "dailyMinutes": 300,
          "createdAt": "2026-10-20T12: 00: 00Z",
          "updatedAt": "2026-10-20T12: 00: 00Z",
          "routes": [
            {
              "routeId": "cr_7509f65c",
              "integrationId": "ci_8836db3c",
              "name": "Vendor R7Q2 (Brazil mobile)",
              "techPrefix": "R7Q2#",
              "customHeaders": [],
              "enabled": true,
              "dialable": true,
              "createdAt": "2026-10-25T09: 00: 00Z",
              "updatedAt": "2026-10-25T09: 00: 00Z"
            }
          ]
        }
      ]
    }

    Get a carrier integration

    GET/testing/carrier-integrations/{integrationId}

    One trunk with its routes, as it appears in the list. 404 when the trunk is not in this workspace.

    Path Parameters

    NameTypeRequiredDescription
    integrationIdstringrequiredCarrier integration (SIP trunk) ID, from List carrier integrations

    Request

    bash
    curl -H "x-api-key: YOUR_API_KEY" \
      https://api.nopaque.co.uk/testing/carrier-integrations/ci_8836db3c

    Response

    json
    {
      "integration": {
        "integrationId": "ci_8836db3c",
        "name": "Integral SBC",
        "host": "203.0.113.10",
        "port": 5060,
        "transport": "UDP",
        "mediaEncryption": "disabled",
        "status": "active",
        "hasCredentials": false,
        "maxConcurrentCalls": 5,
        "dailyMinutes": 300,
        "createdAt": "2026-10-20T12: 00: 00Z",
        "updatedAt": "2026-10-20T12: 00: 00Z",
        "routes": [
          {
            "routeId": "cr_7509f65c",
            "integrationId": "ci_8836db3c",
            "name": "Vendor R7Q2 (Brazil mobile)",
            "techPrefix": "R7Q2#",
            "customHeaders": [],
            "enabled": true,
            "dialable": true,
            "createdAt": "2026-10-25T09: 00: 00Z",
            "updatedAt": "2026-10-25T09: 00: 00Z"
          }
        ]
      }
    }

    List carrier routes

    GET/testing/carrier-integrations/{integrationId}/routes

    The routes on one trunk, sorted by name, including ones that cannot be dialled (see `dialable`). Use a route's `routeId` as a test config's `carrierRouteId`.

    Path Parameters

    NameTypeRequiredDescription
    integrationIdstringrequiredCarrier integration (SIP trunk) ID, from List carrier integrations

    Request

    bash
    curl -H "x-api-key: YOUR_API_KEY" \
      https://api.nopaque.co.uk/testing/carrier-integrations/ci_8836db3c/routes

    Response

    json
    {
      "routes": [
        {
          "routeId": "cr_7509f65c",
          "integrationId": "ci_8836db3c",
          "name": "Vendor R7Q2 (Brazil mobile)",
          "techPrefix": "R7Q2#",
          "customHeaders": [],
          "enabled": true,
          "dialable": true,
          "createdAt": "2026-10-25T09: 00: 00Z",
          "updatedAt": "2026-10-25T09: 00: 00Z"
        }
      ]
    }

    Get a carrier route

    GET/testing/carrier-integrations/{integrationId}/routes/{routeId}

    One route on one trunk. 404 when either is not in this workspace.

    Path Parameters

    NameTypeRequiredDescription
    integrationIdstringrequiredCarrier integration (SIP trunk) ID, from List carrier integrations
    routeIdstringrequiredCarrier route ID

    Request

    bash
    curl -H "x-api-key: YOUR_API_KEY" \
      https://api.nopaque.co.uk/testing/carrier-integrations/ci_8836db3c/routes/cr_7509f65c

    Response

    json
    {
      "route": {
        "routeId": "cr_7509f65c",
        "integrationId": "ci_8836db3c",
        "name": "Vendor R7Q2 (Brazil mobile)",
        "techPrefix": "R7Q2#",
        "customHeaders": [],
        "enabled": true,
        "dialable": true,
        "createdAt": "2026-10-25T09: 00: 00Z",
        "updatedAt": "2026-10-25T09: 00: 00Z"
      }
    }

    Create a carrier route

    POST/testing/carrier-integrations/{integrationId}/routes

    Add a route to a trunk. Calls through it are sent to your SBC as `sip:{techPrefix}{number without +}@{host}:{port}`, so the prefix is whatever your SBC routes on: digits, letters, `#` and `*`, up to 16 characters (a `#` is sent as `%23`). A route cannot change where the trunk points or the caller ID. Needs the `testing:write` scope; in the app, workspace owners and admins. Every change is written to the workspace's activity log first; if it cannot be, the answer is 503 and nothing changed.

    Path Parameters

    NameTypeRequiredDescription
    integrationIdstringrequiredCarrier integration (SIP trunk) ID, from List carrier integrations

    Body Parameters

    NameTypeRequiredDescription
    namestringrequiredDisplay name, up to 100 characters
    techPrefixstringoptionalDialled in front of the number: `A-Z`, `a-z`, `0-9`, `#` and `*`, up to 16 characters. Leave it out (or empty) for the trunk's default route
    customHeadersCustomHeader[]optionalUp to 10 `X-` headers sent on the INVITE, for SBCs that route on a header
    └ namestringrequiredHeader name; must start with `X-`
    └ valuestringrequiredHeader value
    enabledbooleanoptionalDefaults to true

    Request

    bash
    curl -X POST -H "x-api-key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"name":"Vendor R7Q2 (Brazil mobile)","techPrefix":"R7Q2#"}' \
      https://api.nopaque.co.uk/testing/carrier-integrations/ci_8836db3c/routes

    Response

    json
    {
      "route": {
        "routeId": "cr_7509f65c",
        "integrationId": "ci_8836db3c",
        "name": "Vendor R7Q2 (Brazil mobile)",
        "techPrefix": "R7Q2#",
        "customHeaders": [],
        "enabled": true,
        "dialable": true,
        "createdAt": "2026-10-25T09: 00: 00Z",
        "updatedAt": "2026-10-25T09: 00: 00Z"
      }
    }

    Update a carrier route

    PATCH/testing/carrier-integrations/{integrationId}/routes/{routeId}

    Rename a route, change its prefix or headers, or turn it off. Send only the fields to change. Turning a route off refuses every run that names it straight away. 409 when someone else changed the route at the same moment; read it again and retry.

    Path Parameters

    NameTypeRequiredDescription
    integrationIdstringrequiredCarrier integration (SIP trunk) ID, from List carrier integrations
    routeIdstringrequiredCarrier route ID

    Body Parameters

    NameTypeRequiredDescription
    namestringoptionalDisplay name, up to 100 characters
    techPrefixstringoptional`A-Z`, `a-z`, `0-9`, `#` and `*`, up to 16 characters
    customHeadersCustomHeader[]optionalUp to 10 `X-` headers sent on the INVITE, for SBCs that route on a header
    └ namestringrequiredHeader name; must start with `X-`
    └ valuestringrequiredHeader value
    enabledbooleanoptionalfalse stops runs from using the route

    Request

    bash
    curl -X PATCH -H "x-api-key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"enabled":false}' \
      https://api.nopaque.co.uk/testing/carrier-integrations/ci_8836db3c/routes/cr_7509f65c

    Response

    json
    {
      "route": {
        "routeId": "cr_7509f65c",
        "integrationId": "ci_8836db3c",
        "name": "Vendor R7Q2 (Brazil mobile)",
        "techPrefix": "R7Q2#",
        "customHeaders": [],
        "enabled": false,
        "dialable": false,
        "createdAt": "2026-10-25T09: 00: 00Z",
        "updatedAt": "2026-10-25T09: 00: 00Z"
      }
    }