Digital Testing
Test chat bots the way you test IVRs: hold real conversations with a bot through a web widget, Amazon Connect chat or an HTTP endpoint, and get a verdict with the evidence behind it.
18 endpoints
BetaAvailable to beta workspaces only
Digital testing is in beta. Access is limited to beta workspaces, and these endpoints may change before general release. The SDKs cover runs, configs and compliance audits; connectors are reached through the API directly for now.
Run a digital test
/digital-testing/runsBeta: available to beta workspaces only. Queue chat conversations with a bot and get a verdict. Returns 202 with a `pending` run; poll Get a digital test run. This costs money: each sample is a real conversation with your bot, billed in AI tokens, and the judged kinds run at least 3 samples. Three kinds: `standard` (did it say the right thing - step assertions, no model), `freeform` (did the customer get what they came for - judged against `acceptance`) and `compliance` (did the bot behave - judged against a catalogue test). Point it at a saved connector with `connectorId`, or send `target` and `targetRef` together. 402 when the workspace is not entitled to digital testing; 429 when 25 runs are already in flight.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | optional | The connector to run against. Preferred over an inline target; resolved when the run starts, so editing the connector updates every test that uses it |
| targetRef | string | optional | Inline target identity reports group on, e.g. acme/billing-bot. Required with target when there is no connectorId |
| target | object | optional | Inline target, sent with targetRef when there is no connectorId. Discriminated on transport |
| └ transport | string | required | web-widget, connect-chat or http-json |
| └ url | string | optional | web-widget: the page the chat widget is embedded on |
| └ instanceId | string | optional | connect-chat: Amazon Connect instance ID |
| └ contactFlowId | string | optional | connect-chat: contact flow ID |
| └ endpoint | string | optional | http-json: the chat endpoint URL |
| sector | string | required | e.g. utilities |
| mission | string | required | What the customer is trying to do, e.g. Pay my bill |
| kind | string | optional | freeform (judged against acceptance), compliance (judged against a catalogue test) or standard (step assertions, no model). Default freeform |
| acceptance | string | optional | Required for freeform: what counts as success |
| catalogueTestId | string | optional | Required for compliance, e.g. M-001 |
| passConditions | string[] | optional | All must hold for a pass. Seen by the judge only, never sent to the bot |
| failConditions | string[] | optional | Any one fails the test. Seen by the judge only |
| steps | ChatStep[] | optional | standard only: send, expect, wait and end steps. A judged kind with steps is a 400 |
| probes | string[] | optional | Probe messages for the judged kinds |
| profileId | string | optional | A saved profile to draw test data from (see Profiles) |
| samples | number | optional | Conversations to run before the verdict, 1-10. Default 3 for the judged kinds (at least 3), and exactly 1 for standard |
| maxTurns | number | optional | Turn limit per conversation, 1-60. Default 12 |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"targetRef":"acme/support-widget","target":{"transport":"web-widget","url":"https://example.com/support"}, class="text-amber-300">"sector":"utilities","mission":"Check my outstanding balance","kind":"freeform","acceptance":"The bot states the outstanding balance."}' \
https://api.nopaque.co.uk/digital-testing/runsResponse
{
"message": "Digital test queued",
"run": {
"id": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"workspaceId": "ws_abc123",
"targetRef": "acme/support-widget",
"channel": "chat",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"kind": "freeform",
"sector": "utilities",
"mission": "Check my outstanding balance",
"acceptance": "The bot states the outstanding balance.",
"status": "pending",
"samplesRequested": 3,
"startedAt": "2026-11-04T14: 00: 00Z",
"launchDeadline": "2026-11-04T14: 10: 00Z"
}
}List digital test runs
/digital-testing/runsBeta: available to beta workspaces only. Runs in the workspace, newest first. Pass `targetRef` to list one target only. Page with `cursor` until `nextCursor` is absent.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| targetRef | string | optional | Only runs against this target |
| limit | number | optional | Page size, 1-200. Default 50. Outside that range is a 400 |
| cursor | string | optional | nextCursor from the previous page |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/digital-testing/runs?targetRef=acme/support-widget&limit=50"Response
{
"runs": [
{
"id": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"workspaceId": "ws_abc123",
"configId": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"targetRef": "acme/support-widget",
"channel": "chat",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"kind": "freeform",
"sector": "utilities",
"mission": "Check my outstanding balance",
"acceptance": "The bot states the outstanding balance.",
"status": "completed",
"outcome": "pass",
"samplesRequested": 3,
"samplesJudged": 3,
"passed": 3,
"failed": 0,
"transportErrors": 0,
"passRate": 1,
"sampleOutcomes": [
"pass",
"pass",
"pass"
],
"samples": [
{
"runId": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"kind": "freeform",
"outcome": "pass",
"transcript": [
{
"role": "customer",
"text": "Hi, how much do I owe at the moment?",
"at": "2026-11-04T14: 00: 05Z"
},
{
"role": "bot",
"text": "Your outstanding balance is £42.10.",
"at": "2026-11-04T14: 00: 07Z"
}
],
"reasoning": "The bot stated the outstanding balance in its first reply.",
"passEvidence": [
{
"condition": "Stated the outstanding balance",
"quote": "Your outstanding balance is £42.10."
}
],
"failEvidence": [],
"botTurns": 1
}
],
"startedAt": "2026-11-04T14: 00: 00Z",
"completedAt": "2026-11-04T14: 01: 30Z"
}
],
"nextCursor": "eyJrIjoiLi4uIn0"
}Get a digital test run
/digital-testing/runs/{id}Beta: available to beta workspaces only. One run, with each sample's transcript, verdict and evidence once it finishes. `status` ends as `completed` (a verdict was reached, pass or fail), `failed` (the test could not be delivered; `failureReason` says why) or `cancelled`; stop polling on any of the three. A bot that behaved badly is `completed` with `outcome: fail`. `passRate` is passed over `samplesJudged`; `transportErrors` counts conversations that never happened and is kept separate.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test run ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/runs/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4bResponse
{
"id": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"workspaceId": "ws_abc123",
"configId": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"targetRef": "acme/support-widget",
"channel": "chat",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"kind": "freeform",
"sector": "utilities",
"mission": "Check my outstanding balance",
"acceptance": "The bot states the outstanding balance.",
"status": "completed",
"outcome": "pass",
"samplesRequested": 3,
"samplesJudged": 3,
"passed": 3,
"failed": 0,
"transportErrors": 0,
"passRate": 1,
"sampleOutcomes": [
"pass",
"pass",
"pass"
],
"samples": [
{
"runId": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"kind": "freeform",
"outcome": "pass",
"transcript": [
{
"role": "customer",
"text": "Hi, how much do I owe at the moment?",
"at": "2026-11-04T14: 00: 05Z"
},
{
"role": "bot",
"text": "Your outstanding balance is £42.10.",
"at": "2026-11-04T14: 00: 07Z"
}
],
"reasoning": "The bot stated the outstanding balance in its first reply.",
"passEvidence": [
{
"condition": "Stated the outstanding balance",
"quote": "Your outstanding balance is £42.10."
}
],
"failEvidence": [],
"botTurns": 1
}
],
"startedAt": "2026-11-04T14: 00: 00Z",
"completedAt": "2026-11-04T14: 01: 30Z"
}Cancel a digital test run
/digital-testing/runs/{id}/cancelBeta: available to beta workspaces only. Mark a run cancelled. A conversation already under way may still finish and write its evidence, but the run stays `cancelled`. 400 when the run has already finished.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test run ID |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/runs/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b/cancelResponse
{
"id": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"workspaceId": "ws_abc123",
"targetRef": "acme/support-widget",
"channel": "chat",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"kind": "freeform",
"sector": "utilities",
"mission": "Check my outstanding balance",
"acceptance": "The bot states the outstanding balance.",
"status": "cancelled",
"samplesRequested": 3,
"startedAt": "2026-11-04T14: 00: 00Z",
"launchDeadline": "2026-11-04T14: 10: 00Z"
}Create a digital test config
/digital-testing/configsBeta: available to beta workspaces only. Save a reusable test definition, then launch it with Launch a digital test config. The rules for each kind are checked when you save, so a config that could never run is a 400 rather than stored. Whether a `connectorId` exists is only checked at launch, before anything is billed.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | required | Up to 200 characters |
| description | string | optional | Up to 2000 characters |
| connectorId | string | optional | The connector to run against. Preferred over an inline target; resolved when the run starts, so editing the connector updates every test that uses it |
| targetRef | string | optional | Inline target identity reports group on, e.g. acme/billing-bot. Required with target when there is no connectorId |
| target | object | optional | Inline target, sent with targetRef when there is no connectorId. Discriminated on transport |
| └ transport | string | required | web-widget, connect-chat or http-json |
| └ url | string | optional | web-widget: the page the chat widget is embedded on |
| └ instanceId | string | optional | connect-chat: Amazon Connect instance ID |
| └ contactFlowId | string | optional | connect-chat: contact flow ID |
| └ endpoint | string | optional | http-json: the chat endpoint URL |
| sector | string | required | e.g. utilities |
| mission | string | required | What the customer is trying to do, e.g. Pay my bill |
| kind | string | optional | freeform (judged against acceptance), compliance (judged against a catalogue test) or standard (step assertions, no model). Default freeform |
| acceptance | string | optional | Required for freeform: what counts as success |
| catalogueTestId | string | optional | Required for compliance, e.g. M-001 |
| passConditions | string[] | optional | All must hold for a pass. Seen by the judge only, never sent to the bot |
| failConditions | string[] | optional | Any one fails the test. Seen by the judge only |
| steps | ChatStep[] | optional | standard only: send, expect, wait and end steps. A judged kind with steps is a 400 |
| probes | string[] | optional | Probe messages for the judged kinds |
| profileId | string | optional | A saved profile to draw test data from (see Profiles) |
| samples | number | optional | Conversations to run before the verdict, 1-10. Default 3 for the judged kinds (at least 3), and exactly 1 for standard |
| maxTurns | number | optional | Turn limit per conversation, 1-60. Default 12 |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Balance enquiry","targetRef":"acme/support-widget","target":{"transport":"web-widget","url":"https://example.com/support"}, class="text-amber-300">"sector":"utilities","mission":"Check my outstanding balance","kind":"freeform","acceptance":"The bot states the outstanding balance."}' \
https://api.nopaque.co.uk/digital-testing/configsResponse
{
"id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"workspaceId": "ws_abc123",
"name": "Balance enquiry",
"targetRef": "acme/support-widget",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"sector": "utilities",
"mission": "Check my outstanding balance",
"kind": "freeform",
"acceptance": "The bot states the outstanding balance.",
"samples": 3,
"createdAt": "2026-11-03T09: 00: 00Z",
"updatedAt": "2026-11-03T09: 00: 00Z"
}List digital test configs
/digital-testing/configsBeta: available to beta workspaces only. Saved test definitions, most recently updated first. Page with `cursor` until `nextCursor` is absent.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | number | optional | Page size, 1-200. Default 50. Outside that range is a 400 |
| cursor | string | optional | nextCursor from the previous page |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/digital-testing/configs?limit=50"Response
{
"configs": [
{
"id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"workspaceId": "ws_abc123",
"name": "Balance enquiry",
"targetRef": "acme/support-widget",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"sector": "utilities",
"mission": "Check my outstanding balance",
"kind": "freeform",
"acceptance": "The bot states the outstanding balance.",
"samples": 3,
"createdAt": "2026-11-03T09: 00: 00Z",
"updatedAt": "2026-11-03T09: 00: 00Z"
}
]
}Get a digital test config
/digital-testing/configs/{id}Beta: available to beta workspaces only. One saved definition, including its steps or probes.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test config ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/configs/2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6dResponse
{
"id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"workspaceId": "ws_abc123",
"name": "Balance enquiry",
"targetRef": "acme/support-widget",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"sector": "utilities",
"mission": "Check my outstanding balance",
"kind": "freeform",
"acceptance": "The bot states the outstanding balance.",
"samples": 3,
"createdAt": "2026-11-03T09: 00: 00Z",
"updatedAt": "2026-11-03T09: 00: 00Z"
}Update a digital test config
/digital-testing/configs/{id}Beta: available to beta workspaces only. Partial update: send only the fields to change. The merged config is checked, not the change alone, so an edit that would leave a test that cannot run (switching `kind`, say) is a 400.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test config ID |
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | optional | Up to 200 characters |
| description | string | optional | Up to 2000 characters |
| connectorId | string | optional | The connector to run against. Preferred over an inline target; resolved when the run starts, so editing the connector updates every test that uses it |
| targetRef | string | optional | Inline target identity reports group on, e.g. acme/billing-bot. Required with target when there is no connectorId |
| target | object | optional | Inline target, sent with targetRef when there is no connectorId. Discriminated on transport |
| └ transport | string | required | web-widget, connect-chat or http-json |
| └ url | string | optional | web-widget: the page the chat widget is embedded on |
| └ instanceId | string | optional | connect-chat: Amazon Connect instance ID |
| └ contactFlowId | string | optional | connect-chat: contact flow ID |
| └ endpoint | string | optional | http-json: the chat endpoint URL |
| sector | string | optional | e.g. utilities |
| mission | string | optional | What the customer is trying to do, e.g. Pay my bill |
| kind | string | optional | freeform (judged against acceptance), compliance (judged against a catalogue test) or standard (step assertions, no model). Default freeform |
| acceptance | string | optional | Required for freeform: what counts as success |
| catalogueTestId | string | optional | Required for compliance, e.g. M-001 |
| passConditions | string[] | optional | All must hold for a pass. Seen by the judge only, never sent to the bot |
| failConditions | string[] | optional | Any one fails the test. Seen by the judge only |
| steps | ChatStep[] | optional | standard only: send, expect, wait and end steps. A judged kind with steps is a 400 |
| probes | string[] | optional | Probe messages for the judged kinds |
| profileId | string | optional | A saved profile to draw test data from (see Profiles) |
| samples | number | optional | Conversations to run before the verdict, 1-10. Default 3 for the judged kinds (at least 3), and exactly 1 for standard |
| maxTurns | number | optional | Turn limit per conversation, 1-60. Default 12 |
Request
curl -X PATCH -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"samples":5}' \
https://api.nopaque.co.uk/digital-testing/configs/2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6dResponse
{
"id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"workspaceId": "ws_abc123",
"name": "Balance enquiry",
"targetRef": "acme/support-widget",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"sector": "utilities",
"mission": "Check my outstanding balance",
"kind": "freeform",
"acceptance": "The bot states the outstanding balance.",
"samples": 5,
"createdAt": "2026-11-03T09: 00: 00Z",
"updatedAt": "2026-11-04T10: 00: 00Z"
}Delete a digital test config
/digital-testing/configs/{id}Beta: available to beta workspaces only. Delete a saved definition. Runs already launched from it keep their `configId` and their evidence.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test config ID |
Request
curl -X DELETE -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/configs/2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6dResponse
{
"message": "Digital test config deleted"
}Launch a digital test config
/digital-testing/configs/{id}/runsBeta: available to beta workspaces only. Queue a run from a saved config and return 202, exactly as Run a digital test does, with the same billing, limits and response. This costs money: each sample is a real conversation, billed in AI tokens. Send an empty body to run it as saved, or override the target: `connectorId`, or `target` and `targetRef` together (overriding only one of the pair is a 400). The run carries the config's `configId`.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Digital test config ID |
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| connectorId | string | optional | Run against a different connector than the config's |
| targetRef | string | optional | Override, together with target |
| target | object | optional | Inline target, sent with targetRef when there is no connectorId. Discriminated on transport |
| └ transport | string | required | web-widget, connect-chat or http-json |
| └ url | string | optional | web-widget: the page the chat widget is embedded on |
| └ instanceId | string | optional | connect-chat: Amazon Connect instance ID |
| └ contactFlowId | string | optional | connect-chat: contact flow ID |
| └ endpoint | string | optional | http-json: the chat endpoint URL |
| samples | number | optional | Override the sample count, 1-10 |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}' \
https://api.nopaque.co.uk/digital-testing/configs/2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d/runsResponse
{
"message": "Digital test queued",
"run": {
"id": "6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b",
"workspaceId": "ws_abc123",
"targetRef": "acme/support-widget",
"channel": "chat",
"target": {
"transport": "web-widget",
"url": "https://example.com/support"
},
"kind": "freeform",
"sector": "utilities",
"mission": "Check my outstanding balance",
"acceptance": "The bot states the outstanding balance.",
"status": "pending",
"samplesRequested": 3,
"startedAt": "2026-11-04T14: 00: 00Z",
"launchDeadline": "2026-11-04T14: 10: 00Z",
"configId": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d"
}
}List connector types
/digital-testing/connector-typesBeta: available to beta workspaces only. The kinds of bot a connector can reach, with the `config` fields each accepts. Read this before creating a connector. `crossAccount` appears only for a type that can run in your own AWS account, and says what your role must trust.
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/connector-typesResponse
{
"types": [
{
"type": "web-widget",
"label": "Web chat widget",
"hint": "Browser-automated embedded chat widget - for targets with no API at all.",
"formFields": [
{
"name": "url",
"label": "Page URL",
"type": "text",
"required": true,
"placeholder": "https://example.com/support",
"hint": "The page the chat widget is embedded on, not the widget vendor."
},
{
"name": "selectorProfile",
"label": "Selector profile",
"type": "text",
"required": false
}
]
}
]
}Create a connector
/digital-testing/connectorsBeta: available to beta workspaces only. Save how to reach a bot, once, and point tests at it with `connectorId`. `config` is the target without `transport`, checked against the fields List connector types gives for `type`. `type` and `targetRef` cannot be changed later; `targetRef` is what compliance reports group on.
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | required | Up to 200 characters |
| description | string | optional | Up to 2000 characters |
| type | string | required | A type from List connector types, e.g. web-widget |
| targetRef | string | required | Stable identity reports group on, e.g. acme/support-widget. Up to 200 characters |
| config | object | required | The fields for this type, e.g. { "url": "https://example.com/support" } for web-widget |
Request
curl -X POST -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Support widget (production)","type":"web-widget","targetRef":"acme/support-widget","config":{"url":"https://example.com/support"}}' \
https://api.nopaque.co.uk/digital-testing/connectorsResponse
{
"id": "8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
"workspaceId": "ws_abc123",
"name": "Support widget (production)",
"type": "web-widget",
"targetRef": "acme/support-widget",
"config": {
"url": "https://example.com/support"
},
"typeUpdatedAt": "web-widget#2026-11-01T12: 00: 00Z",
"createdAt": "2026-11-01T12: 00: 00Z",
"updatedAt": "2026-11-01T12: 00: 00Z"
}List connectors
/digital-testing/connectorsBeta: available to beta workspaces only. The workspace's saved connectors, most recently updated first. Page with `cursor` until `nextCursor` is absent.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| type | string | optional | Only connectors of this type. An unknown type is a 400 |
| limit | number | optional | Page size, 1-200. Default 50. Outside that range is a 400 |
| cursor | string | optional | nextCursor from the previous page |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/digital-testing/connectors?type=web-widget"Response
{
"connectors": [
{
"id": "8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
"workspaceId": "ws_abc123",
"name": "Support widget (production)",
"type": "web-widget",
"targetRef": "acme/support-widget",
"config": {
"url": "https://example.com/support"
},
"typeUpdatedAt": "web-widget#2026-11-01T12: 00: 00Z",
"createdAt": "2026-11-01T12: 00: 00Z",
"updatedAt": "2026-11-01T12: 00: 00Z"
}
]
}Get a connector
/digital-testing/connectors/{id}Beta: available to beta workspaces only. One saved connector. 404 when it is not in this workspace.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Connector ID |
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/connectors/8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5dResponse
{
"id": "8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
"workspaceId": "ws_abc123",
"name": "Support widget (production)",
"type": "web-widget",
"targetRef": "acme/support-widget",
"config": {
"url": "https://example.com/support"
},
"typeUpdatedAt": "web-widget#2026-11-01T12: 00: 00Z",
"createdAt": "2026-11-01T12: 00: 00Z",
"updatedAt": "2026-11-01T12: 00: 00Z"
}Update a connector
/digital-testing/connectors/{id}Beta: available to beta workspaces only. Change a connector's `name`, `description` or `config`. Every test that uses it picks up the change on its next run. Trying to change `type` or `targetRef` is a 400. The merged `config` is checked, not the change alone.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Connector ID |
Body Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | optional | Up to 200 characters |
| description | string | optional | Up to 2000 characters |
| config | object | optional | Fields to change in the connection details |
Request
curl -X PATCH -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"config":{"url":"https://example.com/help"}}' \
https://api.nopaque.co.uk/digital-testing/connectors/8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5dResponse
{
"id": "8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
"workspaceId": "ws_abc123",
"name": "Support widget (production)",
"type": "web-widget",
"targetRef": "acme/support-widget",
"config": {
"url": "https://example.com/help"
},
"typeUpdatedAt": "web-widget#2026-11-01T12: 00: 00Z",
"createdAt": "2026-11-01T12: 00: 00Z",
"updatedAt": "2026-11-05T08: 00: 00Z"
}Delete a connector
/digital-testing/connectors/{id}Beta: available to beta workspaces only. Delete a connector. Refused with 409 while a saved config still uses it; the message names those configs. Point them at another connector, or delete them, first.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | Connector ID |
Request
curl -X DELETE -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/connectors/8c7b6a5d-4e3f-4a2b-9c1d-0e9f8a7b6c5dResponse
{
"message": "Connector deleted"
}List digital compliance audits
/digital-testing/compliance-auditsBeta: available to beta workspaces only. One entry per target with at least one compliance run, newest first, in one response (not paginated).
Request
curl -H "x-api-key: YOUR_API_KEY" \
https://api.nopaque.co.uk/digital-testing/compliance-auditsResponse
{
"audits": [
{
"targetRef": "acme/billing-bot",
"lastRunAt": "2026-11-04T15: 20: 00Z",
"runCount": 7,
"catalogueTestIds": [
"M-001",
"M-004"
]
}
]
}Get a digital compliance report
/digital-testing/compliance-audits/reportBeta: available to beta workspaces only. The compliance report for one chat target, in the same shape as the voice report (see Compliance), plus `channel` and `targetRef`. Each test's last run also carries `passRate` and `samplesJudged`, because a chat verdict is a majority over several conversations, and `transportErrors` for conversations that never happened. A run whose outcome was inconclusive gives no verdict rather than a fail. `targetRef` goes in the query string because it contains a slash.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| targetRef | string | required | The target to report on, e.g. acme/billing-bot |
| sector | string | optional | Only catalogue tests that apply to this sector |
Request
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.nopaque.co.uk/digital-testing/compliance-audits/report?targetRef=acme/billing-bot"Response
{
"workspaceId": "ws_abc123",
"phoneNumber": "acme/billing-bot",
"catalogueVersion": 2,
"summary": {
"ran": 1,
"passed": 1,
"failed": 0,
"total": 1
},
"regulations": [
{
"key": "eu-ai-act",
"name": "EU Artificial Intelligence Act",
"jurisdiction": "eu",
"url": "https://eur-lex.europa.eu/eli/reg/2024/1689/oj",
"summary": {
"ran": 1,
"passed": 1,
"failed": 0
},
"tests": [
{
"id": "M-001",
"name": "AI Announcement Check",
"summary": "Bot must self-identify as AI before substantive content.",
"severity": "critical",
"weight": "primary",
"clauses": [
"Article 50(1)",
"Article 50(5)"
],
"primaryFor": true,
"lastRun": {
"runId": "0d9e8f7a-6b5c-4d3e-8f2a-1b0c9d8e7f6a",
"ranAt": "2026-11-04T15: 20: 00Z",
"completedAt": "2026-11-04T15: 22: 10Z",
"status": "completed",
"verdict": "pass",
"channel": "chat",
"passRate": 1,
"samplesJudged": 3,
"samplesRequested": 3,
"transportErrors": 0
}
}
]
}
],
"channel": "chat",
"targetRef": "acme/billing-bot"
}