Testing
Create test configurations, run test jobs against IVR systems, and retrieve results. Ideal for CI/CD integration.
15 endpoints
Language codes
The language field on these endpoints takes one of the transcription codes below. Omit it and the call is transcribed in en-GB (English (UK)), which is why a caller who never sets it only ever gets English. multi covers a call that switches between languages. Anything not in this table is rejected with a 400.
| Code | Language |
|---|---|
| en-GB | English (UK)(default) |
| en-US | English (US) |
| en-AU | English (Australia) |
| en-IN | English (India) |
| en-NZ | English (New Zealand) |
| multi | Auto / multilingual |
| ar | Arabic |
| be | Belarusian |
| bn | Bengali |
| bs | Bosnian |
| bg | Bulgarian |
| ca | Catalan |
| zh-HK | Chinese (Cantonese) |
| zh | Chinese (Mandarin) |
| hr | Croatian |
| cs | Czech |
| da | Danish |
| nl | Dutch |
| et | Estonian |
| fi | Finnish |
| nl-BE | Flemish |
| fr | French |
| de | German |
| el | Greek |
| gu | Gujarati |
| he | Hebrew |
| hi | Hindi |
| hu | Hungarian |
| id | Indonesian |
| it | Italian |
| ja | Japanese |
| kn | Kannada |
| ko | Korean |
| lv | Latvian |
| lt | Lithuanian |
| mk | Macedonian |
| ms | Malay |
| mr | Marathi |
| no | Norwegian |
| fa | Persian |
| pl | Polish |
| pt | Portuguese |
| ro | Romanian |
| ru | Russian |
| sr | Serbian |
| sk | Slovak |
| sl | Slovenian |
| es | Spanish |
| sv | Swedish |
| tl | Tagalog |
| ta | Tamil |
| te | Telugu |
| th | Thai |
| tr | Turkish |
| uk | Ukrainian |
| ur | Urdu |
| vi | Vietnamese |
These are not the mission-test call languages. Mission tests take a shorter list of bare codes, including en, which this list rejects — use a regional code such as en-GB here, and see the Mission Tests page for the call-language list.
Create a test config
/testing/configsCreate a new test configuration.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | required | Display name for the test config |
| phoneNumber | string | required | Phone number to test in E.164 format |
| carrierRouteId | string | optional | Invite-only. Dial this config through one of your carrier routes, over your own SIP trunk (see Carrier Integrations). If the route cannot be dialled when a run starts, the run is refused rather than sent another way |
| language | string | optional | Transcription language for every run of this config, e.g. en-GB, fr, or multi for a call that switches language. Listed in full under Language codes at the top of this page — any other value is rejected with a 400. Omit it and runs are transcribed in en-GB, so a caller who never sets it only ever gets English. These are the regional transcription codes, not the shorter mission-test call languages: a bare en is rejected here |
| steps | TestStep[] | required | Array of test steps defining the call flow |
| └ name | string | required | Display name for this step |
| └ type | 'dtmf' | 'audio' | 'listen' | required | Step type: send DTMF tones, play audio, or listen for a response |
| └ expected | string | required | Expected transcript to match against the IVR response |
| └ threshold | number | required | Similarity percentage required for a match (0-100, default 90) |
| └ timeout | number | required | Max seconds to wait for a match before failing the step |
| └ delay | number | optional | Send DTMF after N seconds even if threshold not met |
| └ dtmf | string | optional | DTMF digit(s) to send (e.g. "1", "123") |
| └ audioUrl | string | optional | URL of audio file to play (for type: audio) |
| └ profileItemId | string | optional | Reference to a profile item for data or voice |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Sales Flow Test","phoneNumber":"+441234567890","steps":[{"name":"Main menu","type":"dtmf","expected":"press 1 for sales","dtmf":"1"},{"name":"Sales queue","type":"listen","expected":"connecting you to sales"}]}' \
https://api.nopaque.co.uk/testing/configsResponse
{
"id": "cfg_abc123",
"name": "Sales Flow Test",
"phoneNumber": "+441234567890",
"steps": [
{
"id": "stp_1",
"name": "Main menu",
"type": "dtmf",
"expected": "press 1 for sales",
"threshold": 90,
"timeout": 30,
"dtmf": "1"
},
{
"id": "stp_2",
"name": "Sales queue",
"type": "listen",
"expected": "connecting you to sales",
"threshold": 90,
"timeout": 30
}
],
"createdAt": "2026-04-10T12: 00: 00Z"
}List test configs
/testing/configsList all test configurations in the workspace.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | number | optional | Maximum items to return (default 50) |
| nextToken | string | optional | Pagination token from previous response |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/configsResponse
{
"items": [
{
"id": "cfg_abc123",
"name": "Sales Flow Test",
"phoneNumber": "+441234567890",
"createdAt": "2026-04-10T12: 00: 00Z"
}
],
"nextToken": null
}Get a test config
/testing/configs/{id}Get a specific test configuration by ID.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test configuration ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/configs/cfg_abc123Response
{
"id": "cfg_abc123",
"name": "Sales Flow Test",
"phoneNumber": "+441234567890",
"steps": [
{
"action": "dtmf",
"value": "1"
}
],
"createdAt": "2026-04-10T12: 00: 00Z"
}Update a test config
/testing/configs/{id}Update a test configuration.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test configuration ID |
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | optional | Updated display name |
| phoneNumber | string | optional | Updated phone number |
| carrierRouteId | string | optional | Invite-only. Set to change the route, or null to dial normally. Dials through one of your carrier routes, over your own SIP trunk (see Carrier Integrations). If the route cannot be dialled when a run starts, the run is refused rather than sent another way |
| language | string | optional | Updated transcription language, e.g. en-GB, fr, or multi. Listed in full under Language codes at the top of this page — any other value is rejected with a 400. Omit it and the saved language is left unchanged (it is not reset to en-GB). Not the mission-test call languages: a bare en is rejected here |
| steps | TestStep[] | optional | Updated test steps |
| └ name | string | required | Display name for this step |
| └ type | 'dtmf' | 'audio' | 'listen' | required | Step type: send DTMF tones, play audio, or listen for a response |
| └ expected | string | required | Expected transcript to match against the IVR response |
| └ threshold | number | required | Similarity percentage required for a match (0-100, default 90) |
| └ timeout | number | required | Max seconds to wait for a match before failing the step |
| └ delay | number | optional | Send DTMF after N seconds even if threshold not met |
| └ dtmf | string | optional | DTMF digit(s) to send (e.g. "1", "123") |
| └ audioUrl | string | optional | URL of audio file to play (for type: audio) |
| └ profileItemId | string | optional | Reference to a profile item for data or voice |
Request
curl -X PUT -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Updated Sales Flow"}' \
https://api.nopaque.co.uk/testing/configs/cfg_abc123Response
{
"id": "cfg_abc123",
"name": "Updated Sales Flow",
"updatedAt": "2026-04-10T12: 10: 00Z"
}Delete a test config
/testing/configs/{id}Delete a test configuration.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test configuration ID |
Request
curl -X DELETE -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/configs/cfg_abc123Response
{
"message": "Test configuration deleted successfully"
}Create a test job
/testing/jobsCreate a new test job from a configuration.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| configId | string | required | Test configuration ID to use |
| name | string | optional | Optional name override for this job |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"configId":"cfg_abc123"}' \
https://api.nopaque.co.uk/testing/jobsResponse
{
"id": "job_abc123",
"configId": "cfg_abc123",
"status": "created",
"createdAt": "2026-04-10T12: 00: 00Z"
}List test jobs
/testing/jobsList all test jobs in the workspace.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | number | optional | Maximum items to return (default 50) |
| nextToken | string | optional | Pagination token from previous response |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/jobsResponse
{
"items": [
{
"id": "job_abc123",
"configId": "cfg_abc123",
"status": "completed",
"createdAt": "2026-04-10T12: 00: 00Z"
}
],
"nextToken": null
}Get a test job
/testing/jobs/{id}Get a specific test job by ID.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test job ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/jobs/job_abc123Response
{
"id": "job_abc123",
"configId": "cfg_abc123",
"status": "completed",
"createdAt": "2026-04-10T12: 00: 00Z",
"completedAt": "2026-04-10T12: 05: 00Z"
}Delete a test job
/testing/jobs/{id}Delete a test job and its results.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test job ID |
Request
curl -X DELETE -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/jobs/job_abc123Response
{
"message": "Test job deleted successfully"
}Start a test run
/testing/runsStart a test run. Pass exactly one of jobId (run an existing scheduled test job) or testConfigId (ad-hoc run directly from a test config).
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| jobId | string | optional | Test job ID to run. Pass this OR testConfigId (exactly one required). |
| testConfigId | string | optional | Test config ID for an ad-hoc run (no saved job needed). Pass this OR jobId (exactly one required). |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"testConfigId":"cfg_abc123"}' \
https://api.nopaque.co.uk/testing/runsResponse
{
"message": "Test run started",
"run": {
"id": "run_def456",
"jobId": "job_abc123",
"testConfigId": "cfg_abc123",
"status": "pending",
"startedAt": "2026-04-10T12: 15: 00Z"
}
}List test runs
/testing/runsList test runs in the workspace. Filter by run type, outcome, phone number, config, or catalogue test, bound by start time, sort, and page with an opaque cursor. Items are slim run summaries.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| runType | string | optional | Filter by run type: mission, compliance, standard, or param |
| outcome | string | optional | Filter by outcome: PASS, FAIL, ERROR, INCONCLUSIVE, or pending |
| phoneNumber | string | optional | Filter by phone number in E.164 format |
| configId | string | optional | Filter by test config id |
| catalogueTestId | string | optional | Filter by compliance catalogue test id |
| jobId | string | optional | Filter by test job id (legacy back-compat) |
| startedAfter | string | optional | Only return runs started at or after this ISO8601 datetime |
| startedBefore | string | optional | Only return runs started at or before this ISO8601 datetime |
| sortBy | string | optional | Sort field: startedAt (default) or completedAt |
| sortDir | string | optional | Sort direction: asc or desc (default desc) |
| limit | number | optional | Maximum items to return, 1-200 (default 50) |
| cursor | string | optional | Opaque pagination cursor from the previous response |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/testing/runs?runType=mission&outcome=PASS&limit=10"Response
{
"runs": [
{
"id": "run_def456",
"workspaceId": "ws_abc123",
"runType": "mission",
"configId": "mtc_abc123",
"status": "completed",
"outcome": "PASS",
"phoneNumber": "+441234567890",
"mission": "Reset my online banking password",
"passedSteps": 4,
"failedSteps": 0,
"callDurationSecs": 182,
"startedAt": "2026-04-10T12: 15: 00Z",
"completedAt": "2026-04-10T12: 18: 00Z"
}
],
"nextCursor": null
}Aggregate test run results
/testing/runs/aggregateAggregate test runs into counts grouped by a dimension, with the same filters as the list endpoint. Supply an optional timeBucket to break the counts down by day, week, or month. Without a timeBucket the response returns groups; with one it returns buckets.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| groupBy | string | required | Dimension to group by: outcome, runType, configId, catalogueTestId, or phoneNumber |
| timeBucket | string | optional | Break counts down over time: day, week, or month |
| runType | string | optional | Filter by run type: mission, compliance, standard, or param |
| outcome | string | optional | Filter by outcome: PASS, FAIL, ERROR, INCONCLUSIVE, or pending |
| phoneNumber | string | optional | Filter by phone number in E.164 format |
| configId | string | optional | Filter by test config id |
| catalogueTestId | string | optional | Filter by compliance catalogue test id |
| startedAfter | string | optional | Only include runs started at or after this ISO8601 datetime |
| startedBefore | string | optional | Only include runs started at or before this ISO8601 datetime |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/testing/runs/aggregate?groupBy=outcome&runType=mission"Response
{
"groups": [
{
"key": "PASS",
"count": 42
},
{
"key": "FAIL",
"count": 7
},
{
"key": "INCONCLUSIVE",
"count": 3
}
],
"truncated": false,
"totalGroups": 3
}Get a test run
/testing/runs/{id}Get a specific test run by ID with full results. `stepResults` has one entry per step: what was sent (`actionType`, `actionValue`, e.g. dtmf and the digits), what the IVR said (`actualTranscript`) against what was expected, the similarity score and the step `outcome` (PASS, FAIL, TIMEOUT or ERROR). Completed runs may carry an optional callTelemetry object (schemaVersion 1) with telephony (including `hangupCause` and `sipHangupCause`), quality, audio, timing, and per-turn detail, and each step result may carry turnTelemetry. All telemetry fields are optional. A run dialled through a carrier route carries `carrier` (`integrationId`, `routeId`).
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Test run ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/runs/run_def456Response
{
"id": "run_def456",
"testConfigId": "cfg_abc123",
"phoneNumber": "+441234567890",
"status": "completed",
"outcome": "PASS",
"startedAt": "2026-04-10T12: 15: 00Z",
"completedAt": "2026-04-10T12: 15: 41Z",
"carrier": {
"integrationId": "ci_8836db3c",
"routeId": "cr_7509f65c"
},
"stepResults": [
{
"stepIndex": 0,
"stepName": "Main menu",
"actionType": "dtmf",
"actionValue": "1",
"expectedTranscript": "press 1 for sales",
"actualTranscript": "Welcome to Acme. Press 1 for sales, 2 for support.",
"similarity": 96,
"threshold": 90,
"outcome": "PASS",
"duration": 9.4
},
{
"stepIndex": 1,
"stepName": "Sales queue",
"actionType": "listen",
"actionValue": "",
"expectedTranscript": "connecting you to sales",
"actualTranscript": "Thank you. Connecting you to sales.",
"similarity": 94,
"threshold": 90,
"outcome": "PASS",
"duration": 4.1
}
],
"callTelemetry": {
"schemaVersion": 1,
"telephony": {
"hangupCause": "normal_clearing",
"sipHangupCause": "200"
},
"timing": {
"totalCallSecs": 41
}
}
}Get a mission test run
/testing/mission-test-runs/{id}Get a single mission test run by id with its verdict and evidence. Mission tests have no step results, so the response carries verdict, judge reasoning, transcript, and compliance evidence rather than steps.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Mission test run id |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/testing/mission-test-runs/mtr_abc123Response
{
"id": "mtr_abc123",
"workspaceId": "ws_abc123",
"configId": "mtc_abc123",
"status": "completed",
"outcome": "PASS",
"sector": "banking",
"mission": "Reset my online banking password",
"acceptance": "Agent verifies identity and resets password",
"passed": true,
"verdict": "pass",
"passReasoning": "The agent verified identity and completed the reset.",
"judgeReasoning": "All acceptance criteria met with no compliance breaches.",
"phoneNumber": "+441234567890",
"startedAt": "2026-05-06T12: 00: 00Z",
"completedAt": "2026-05-06T12: 05: 00Z"
}Check whether a number can be called
/testing/destination-checkAsk whether a test, mission test or map to this number would be dialled, from the platform dial policy (which countries and number types are enabled) and, when `carrierRouteId` is given, your own carrier route, which the country allowlist does not apply to. Nothing is saved and nothing is dialled, so it is free and safe to call as a number is typed. When refused, `kind` and `reason` say why and `message` is a sentence to show a person. 403 when `carrierRouteId` is sent but bring-your-own-carrier is not enabled for the workspace. 503 when the dial policy or route could not be read; try again. The published SDKs (0.13.0) have no method for this, so the sample is curl only.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| phoneNumber | string | required | E.164, e.g. +442079460958 |
| carrierRouteId | string | optional | One of your carrier routes (Carrier Integrations), to check the number as that route would dial it |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phoneNumber":"+6495550123"}' \
https://api.nopaque.co.uk/testing/destination-checkResponse
{
"allowed": false,
"country": "NZ",
"numberType": "FIXED_LINE",
"kind": "policy-denied",
"reason": "Destination NZ is not enabled for dialling.",
"message": "We can't call numbers in New Zealand yet. We can call numbers in Canada, France, Germany, the United Kingdom and the United States."
}