# Account properties
Source: https://docs.operata.com/docs/account-properties
The accountProperties fields Operata's Cloud Collector attaches to every Amazon Connect Contact record — group ID, platform name, AWS account number, instance ID, and region.
The `accountProperties` object identifies the Operata account, Amazon Connect instance, and AWS region a Contact belongs to. The Cloud Collector attaches it to every Contact record it ships to Operata.
## Schema
```json theme={null}
"accountProperties": {
"operataGroupId": "a28453f9-abab-cdcd-efef-84d9e67ac297",
"operataGroupName": "Operata Demo",
"service": "Amazon Connect",
"serviceAccountNumber": "012345678910",
"serviceInstanceId": "62e2306a-aaaa-bbbb-cccc-5a1508195aa5",
"region": "ap-southeast-2"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `operataGroupId` | string (UUID) | yes | Operata Group ID assigned at account creation. The credential identifier used in API requests. | `a28453f9-abab-cdcd-efef-84d9e67ac297` |
| `operataGroupName` | string | yes | Friendly name of the Operata account. | `Operata Demo` |
| `service` | string | yes | Contact-center platform the contact came from. Always `Amazon Connect` for pages in this group. | `Amazon Connect` |
| `serviceAccountNumber` | string | no | AWS account number that owns the Amazon Connect instance. Present when CTR collection is enabled. | `012345678910` |
| `serviceInstanceId` | string (UUID) | no | Amazon Connect instance ID. Present when CTR collection is enabled. | `62e2306a-aaaa-bbbb-cccc-5a1508195aa5` |
| `region` | string | no | AWS region the Amazon Connect instance runs in. Present when CTR collection is enabled. | `ap-southeast-2` |
# Agent
Source: https://docs.operata.com/docs/agent
The serviceAgent fields the Agent Collector captures for each Amazon Connect Contact — machine resources, browser, network, softphone versions, and interaction metrics.
The `serviceAgent` object captures the agent endpoint's state for one Amazon Connect Contact: machine resource usage, browser and softphone versions, network details, and interaction metrics. The Agent Collector emits this object for every Contact.
## Schema
```json theme={null}
"serviceAgent": {
"username": "agent_42",
"friendlyName": "Riley Chen",
"machine": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz",
"idlePercentage": { "avg": 77.12 },
"utilisedPercentage": { "min": 20.25, "max": 27.93, "avg": 22.88 }
},
"memory": {
"availableGb": 16,
"utilisedPercentage": { "min": 97.34, "max": 99.25, "avg": 98.11 }
}
},
"network": {
"internetGatewayIp": "103.120.49.101",
"mediaIpAddress": "192.168.1.12",
"type": "wifi",
"availableInterfaces": [
{ "address": "192.168.1.12", "type": "wifi" },
{ "address": "169.254.139.0", "type": "" }
],
"isp": "Bcd Networks Pty Ltd",
"geolocation": {
"city": "Whittlesea",
"region": "Victoria",
"country": "Australia"
}
},
"browser": {
"name": "Chrome",
"version": "115.0.5790.170"
},
"softphone": {
"softphoneUrl": "https://operata-prod.awsapps.com/connect/ccp-v2/softphone",
"softphoneContextUrl": "https://operata-prod.awsapps.com/connect/ccp-v2/softphone",
"operataChromeExtVersion": "1.6.13",
"operataCollectorVersion": "diagnostics",
"connectStreamsVersion": "1.7.4"
},
"interaction": {
"totalDurationSec": 54,
"onHoldDurationSec": 11,
"talkingDurationSec": 43,
"onMuteDurationSec": 10
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `username` | string | yes | Agent login username as configured in Amazon Connect. | `agent_42` |
| `friendlyName` | string | no | The agent's first name as configured in Amazon Connect. | `Riley Chen` |
| `serviceId` | string (UUID) | no | Amazon Connect agent ID. Present when CTR collection is enabled. | `23aca65c-7bc8-4ead-b9e5-9df15f06b8af` |
| `machine.cpu` | object | yes | Agent machine CPU utilization and availability metrics. See [System CPU and memory usage](/docs/system-resources) for the standalone CPU schema. | — |
| `machine.memory` | object | yes | Agent machine memory utilization and availability metrics. | — |
| `network` | object | yes | Agent network information: available interfaces, types, IP addresses, and which interface handled media during the Contact. See [Machine, browser, and network data](/docs/machine-browser-network) and [Geolocation and ISP](/docs/geolocation-isp) for the standalone network schemas. | — |
| `network.isp` | string | no | Name of the internet service provider, identified from the internet interface sending data to Operata. | `Bcd Networks Pty Ltd` |
| `network.geolocation` | object | no | Geolocation of the ISP point of presence. | — |
| `browser` | object | yes | Browser name and version reported by the Agent Collector. | — |
| `softphone` | object | yes | Softphone URL and version information, including the Agent Collector and Amazon Connect Streams versions. | — |
| `interaction` | object | yes | Key interaction metrics captured after the Contact connects to the agent: total duration, on-hold time, talking time, on-mute time. | — |
# Agent feedback
Source: https://docs.operata.com/docs/agent-feedback
The structured feedback agents submit from the Agent Collector toolbar when reporting an issue during an Amazon Connect Contact.
The `agentFeedback` object is the structured payload agents submit from the Agent Collector toolbar when they report an issue during or after an Amazon Connect Contact.
## Schema
```json theme={null}
{
"category": "Softphone would not work",
"message": "Could not hear customer",
"scenario": "Outbound",
"severity": "Critical"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `category` | string | yes | Issue category selected by the agent from the feedback form's category list. | `Softphone would not work` |
| `message` | string | yes | Free-text message entered by the agent describing the issue. | `Could not hear customer` |
| `scenario` | string | yes | Contact direction at the time the feedback was submitted. One of `Inbound`, `Outbound`. | `Outbound` |
| `severity` | string | yes | Severity level selected by the agent. One of `Critical`, `High`, `Medium`, `Low`. | `Critical` |
# Authentication
Source: https://docs.operata.com/docs/api-authentication
Authenticate to the Operata API with HTTP Basic — your Operata Group ID as the username and an API token as the password.
The Operata API uses **HTTP Basic** authentication (RFC 7617). Every request carries your Operata Group ID as the username and an API token as the password, encoded in the `Authorization` header.
| Security scheme type | HTTP |
| - | - |
| HTTP authorization scheme | Basic |
## Credentials
Your **Operata Group ID** is the UUID in the URL when you're logged in to Operata.
For example, if your URL is `https://app.operata.io/a28453f9-abab-cdcd-efef-84d9e67ac297/dashboard`, your Group ID is `a28453f9-abab-cdcd-efef-84d9e67ac297`.
Log in to the [Operata console](https://app.operata.io) and go to **Settings → Config → API** to create a token. Treat tokens like passwords — store them securely and never commit them to version control.
Pass your Group ID and token using HTTP Basic auth. Most HTTP clients encode and attach the header automatically.
## Example request
```bash cURL theme={null}
curl -u ":" \
https://api.operata.io/v1/data/calls
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const token = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${token}`).toString("base64");
const response = await fetch("https://api.operata.io/v1/data/calls", {
headers: { Authorization: `Basic ${auth}` },
});
```
```python Python theme={null}
import os
import requests
response = requests.get(
"https://api.operata.io/v1/data/calls",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
```
See the [API section of Group Settings](/docs/help/group-settings#api) for where to create and revoke tokens in the Operata console.
**Keep tokens secret.** Store API tokens in environment variables or a secrets manager. Rotate them regularly in line with your organization's security policy.
# Query CCP logs
Source: https://docs.operata.com/docs/api-ccp-logs
GET /v1/data/ccpLogs
Fetch raw Contact Control Panel (CCP) log entries captured by the Agent Collector for one agent across a time window — to inspect agent-side errors, state transitions, and timing.
Returns raw Contact Control Panel (CCP) log entries that the Agent Collector forwarded to Operata. Use it to inspect agent-side errors, softphone state transitions, and timing for a single agent across a time window.
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/data/ccpLogs
```
## Parameters
### Query
| Name | Type | Required | Description |
| - | - | - | - |
| `criteria` | string (JSON) | yes | JSON object encoding the filter for this query. Url-encode the whole value. Supports `agent` (string), `fromTime` and `toTime` (ISO 8601 UTC). |
The `criteria` value is a JSON object passed as a single query-string parameter. For example, `{"agent":"agent_42","fromTime":"2026-05-18T00:00:00Z","toTime":"2026-05-18T01:00:00Z"}` becomes `criteria=%7B%22agent%22%3A%22agent_42%22%2C%22fromTime%22%3A%222026-05-18T00%3A00%3A00Z%22%2C%22toTime%22%3A%222026-05-18T01%3A00%3A00Z%22%7D`.
## Response
`200 OK` with an array of CCP log entries, ordered by `time`.
```json theme={null}
[
{
"agent": "agent_42",
"component": "ccp",
"exception": null,
"level": "TRACE",
"line": 0,
"loggerId": "1747526402159-lbngq11trj",
"objects": [
{ "nextToken": null, "permissions": ["outboundCall"] }
],
"text": "AWSClient: <-- Operation 'getAgentPermissions' succeeded.",
"time": "2026-05-18T00:01:02.577Z"
}
]
```
| Field | Type | Description |
| - | - | - |
| `agent` | string | Agent username the log entry came from. |
| `component` | string | CCP subsystem that emitted the entry. Typical values: `ccp`, `softphone`. |
| `level` | string | Log level: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`. |
| `exception` | string \| null | Stack or exception text when the entry is an error. `null` otherwise. |
| `loggerId` | string | The CCP logger instance that emitted the entry. |
| `objects` | array | Structured payload the CCP attached to the entry, when present. |
| `text` | string | Human-readable log message. |
| `time` | string (ISO 8601) | UTC timestamp the entry was emitted. |
CCP log capture requires the Agent Collector to be running in the agent's browser. Entries from a session in progress may not appear until that session ends.
## Example
```bash curl theme={null}
CRITERIA='{"agent":"agent_42","fromTime":"2026-05-18T00:00:00Z","toTime":"2026-05-18T01:00:00Z"}'
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
--get "https://api.operata.io/v1/data/ccpLogs" \
--data-urlencode "criteria=$CRITERIA"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const criteria = JSON.stringify({
agent: "agent_42",
fromTime: "2026-05-18T00:00:00Z",
toTime: "2026-05-18T01:00:00Z",
});
const url = new URL("https://api.operata.io/v1/data/ccpLogs");
url.searchParams.set("criteria", criteria);
const response = await fetch(url, {
headers: { Authorization: `Basic ${auth}` },
});
const entries = await response.json();
```
```python Python theme={null}
import json, os, requests
criteria = json.dumps({
"agent": "agent_42",
"fromTime": "2026-05-18T00:00:00Z",
"toTime": "2026-05-18T01:00:00Z",
})
response = requests.get(
"https://api.operata.io/v1/data/ccpLogs",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params={"criteria": criteria},
)
response.raise_for_status()
entries = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 400 | `invalid_request` | `criteria` is missing, not valid JSON, or references unknown fields. | Confirm the JSON parses and the field names are `agent`, `fromTime`, `toTime`. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family. For request caps see [Rate limits](/docs/api-rate-limits).
## Related
* [Get complete contact record](/docs/api-contact-record) — fetch the full Operata record for a contact ID surfaced in the logs.
* [CCP error logs](/docs/ccp-error-logs) — field reference for CCP error entries.
* [CCP agent states](/docs/ccp-agent-states) — agent state values referenced in log entries.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
# API changelog
Source: https://docs.operata.com/docs/api-changelog
Versioned changes to the Operata API: new endpoints, fields, deprecations, and breaking changes.
Releases that affect the Operata REST API. This page exposes an RSS feed for subscribers. For Collector and platform releases, see the [Platform changelog](/docs/changelog).
*Documentation release. No API behavior changed.*
This release ships the first complete API reference layer for the Operata API. Nothing changed in the wire protocol, authentication scheme, or response shapes — only the documentation. Existing integrations keep working without modification.
**Endpoints now documented end to end**
Contact endpoints (5):
* [List contact summaries](/docs/api-contact-summary) — `GET /v1/data/calls`.
* [Get a contact record](/docs/api-contact-record) — `GET /v1/data/{contactId}`.
* [List contact stats](/docs/api-contact-stats) — `GET /v1/data/calls/{contactId}/details`.
* [List CCP logs](/docs/api-ccp-logs) — `GET /v1/data/ccpLogs`.
* [List users](/docs/api-list-users) — `GET /v2/admin/users`.
Data redaction endpoints (3):
* [Get redaction config](/docs/api-get-redaction-config) — `GET /v1/config/REDACTION_CONFIG/json`.
* [Update redaction config](/docs/api-update-redaction-config) — `PUT /v1/config/json`.
* [Delete redaction config](/docs/api-delete-redaction-config) — `DELETE /v1/config/REDACTION_CONFIG`.
See the [Data redaction overview](/docs/api-data-redaction) for the redaction model and field-pattern syntax.
**Cross-cutting reference pages**
* [Getting started](/docs/api-getting-started) — base URL, authentication header, and a first request.
* [Errors](/docs/api-errors) — the Stripe-pattern error table mapping HTTP status to error `code` and `type`, with the recommended client behavior for each row.
* [Pagination](/docs/api-pagination) — cursor-based pagination, page size limits, and `next_cursor` semantics.
* [Rate limits](/docs/api-rate-limits) — request quotas, the `X-RateLimit-*` headers, and `429` retry guidance.
* [Idempotency](/docs/api-idempotency) — the `Idempotency-Key` header, replay window, and supported methods.
* [Versioning](/docs/api-versioning) — the `v2` path prefix, the deprecation policy, and how breaking changes get announced.
**Webhooks**
* [Webhooks overview](/docs/api-webhooks-overview) — Operata delivers webhooks via Amazon EventBridge. The page covers the delivery model, the event envelope, and how to subscribe an EventBridge bus.
* [Webhook events](/docs/api-webhooks-events) — the catalog of event types Operata emits, each with a sample payload.
**What did not change**
* No new endpoints, no new fields, no removed fields, no changed response codes, no changed authentication. The API surface this release documents is the surface that has been live; this entry exists to anchor the changelog stream.
# Get complete contact record
Source: https://docs.operata.com/docs/api-contact-record
GET /v1/data/{contactId}
Fetch every Operata field captured for a single contact — softphone summary, Contact Trace Record (CTR), contact flow, headset analytics, and per-leg event timestamps.
Returns every Operata field captured for a single Amazon Connect contact: softphone summary, Contact Trace Record (CTR), contact flow modules, headset analytics, and per-leg event timestamps. You'll typically have the `contactId` from [List contact summaries](/docs/api-contact-summary).
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/data/{contactId}
```
## Parameters
### Path
| Name | Type | Required | Description |
| - | - | - | - |
| `contactId` | string | yes | The Amazon Connect Contact ID for the call. |
## Response
`200 OK` with one object containing every captured block for the contact. A block is absent when its telemetry hasn't arrived yet.
```json theme={null}
{
"contactFlowSummary": [
{
"contactFlowModuleType": "SetLoggingBehavior",
"timestamp": "2026-05-18T10:14:09.833Z"
}
],
"softphoneSummary": {
"contactId": "db248964-dad8-4da8-8ca4-8094d2d254c5",
"agentUserName": "agent_42",
"agentCity": "Sydney",
"agentRegion": "New South Wales",
"agentCountry": "Australia",
"agentISP": "Google LLC",
"agentExternalIPAddress": "35.197.161.176",
"agentLocalIPAddress": "192.168.1.12",
"networkType": "wlan",
"protocol": "udp",
"port": 52500,
"browser": { "name": "Chrome", "version": "124.0.6367.119" },
"operataClientInfo": {
"operataClientId": "client_acme",
"group": "ACME Limited"
},
"networkPerformanceMetrics": {
"jitter": { "min": 1, "avg": 12, "max": 30 },
"rtt": { "min": 63, "avg": 66, "max": 77 },
"packetLoss": { "min": 0, "avg": 1, "max": 2 },
"mos": { "min": 4.27, "avg": 4.32, "max": 4.40 }
}
},
"jabraSummary": {
"contactId": "db248964-dad8-4da8-8ca4-8094d2d254c5",
"agent": "agent_42",
"deviceInfo": {
"deviceName": "Jabra Engage 50",
"deviceConnection": "USB",
"firmwareVersion": "1.24.0",
"serialNumber": "000098577437"
},
"analytics": {
"totalSeconds": "93.23",
"txSpeechTotalPct": 0,
"rxSpeechTotalPct": 78.82,
"crossTalkTotalPct": 10.08,
"silenceTotalPct": 11.10
},
"timestamp": "2026-05-18T10:16:28.245Z"
},
"contactTraceSummary": {
"ContactId": "db248964-dad8-4da8-8ca4-8094d2d254c5",
"Channel": "VOICE",
"InitiationMethod": "INBOUND",
"InitiationTimestamp": "2026-05-18T10:14:09Z",
"DisconnectTimestamp": "2026-05-18T10:16:36Z",
"Agent": {
"Username": "agent_42",
"AgentInteractionDuration": 16
},
"Queue": { "Name": "billing-tier-1", "Duration": 7 }
},
"softphoneEvents": {
"initiated": "2026-05-18T10:14:09.213Z",
"connecting": "2026-05-18T10:14:19.213Z",
"connected": "2026-05-18T10:14:20.213Z",
"disconnected": "2026-05-18T10:16:23.213Z"
},
"operataBillingSummary": {
"agentInteractionDurationRoundedMin": 1,
"agentInteractionDurationActualSec": 16,
"operataStatsDurationRoundedMin": 2,
"operataStatsDurationSec": 103
},
"contactDurationSummary": {
"contactDurationRoundedMin": 1,
"contactDurationActualSec": 27
}
}
```
| Field | Type | Description |
| - | - | - |
| `softphoneSummary` | object | Browser-side telemetry from the Agent Collector. See [Machine, browser, network](/docs/machine-browser-network). |
| `contactFlowSummary` | array | Ordered list of contact-flow modules the contact passed through, with timestamps. |
| `contactTraceSummary` | object | The Amazon Connect Contact Trace Record. See [Contact trace records](/docs/contact-trace-records). |
| `jabraSummary` | object | Headset analytics for Jabra devices. See [Headset logs](/docs/headset-logs). Absent for non-Jabra headsets. |
| `softphoneEvents` | object | Lifecycle timestamps for the contact: `initiated`, `connecting`, `connected`, `disconnected`, `ended`. |
| `operataBillingSummary` | object | Durations Operata uses for billing rollups. |
| `contactDurationSummary` | object | Total contact duration in seconds and rounded minutes. |
Telemetry continues to arrive for a short window after the contact ends. Fetching immediately may return a `softphoneSummary` without the headset or contact-flow blocks — retry a few seconds later to get the complete record.
## Example
```bash curl theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/db248964-dad8-4da8-8ca4-8094d2d254c5"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const contactId = "db248964-dad8-4da8-8ca4-8094d2d254c5";
const response = await fetch(`https://api.operata.io/v1/data/${contactId}`, {
headers: { Authorization: `Basic ${auth}` },
});
const record = await response.json();
```
```python Python theme={null}
import os, requests
contact_id = "db248964-dad8-4da8-8ca4-8094d2d254c5"
response = requests.get(
f"https://api.operata.io/v1/data/{contact_id}",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
response.raise_for_status()
record = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 404 | `not_found` | No contact with `contactId` exists for this Operata account, or telemetry has not landed yet. | Confirm the ID against [List contact summaries](/docs/api-contact-summary). If the contact ended within the last minute, retry after a short delay. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
## Related
* [List contact summaries](/docs/api-contact-summary) — find a `contactId` across a time window.
* [Get detailed contact stats](/docs/api-contact-stats) — second-by-second metrics for the same contact.
* [Contact trace records](/docs/contact-trace-records) — field reference for the CTR block.
* [Headset logs](/docs/headset-logs) — field reference for the `jabraSummary` block.
# Get detailed contact stats
Source: https://docs.operata.com/docs/api-contact-stats
GET /v1/data/calls/{contactId}/details
Get the per-second network performance trace for a single contact — jitter, RTT, MOS, and packet counts — to chart call quality across the full contact duration.
Returns the per-second network performance trace for one contact: jitter, round-trip time (RTT), MOS, packets sent and received, and agent status at each sample. Use it to chart call quality across the full duration of a contact — find the `contactId` first in [List contact summaries](/docs/api-contact-summary).
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/data/calls/{contactId}/details
```
## Parameters
### Path
| Name | Type | Required | Description |
| - | - | - | - |
| `contactId` | string | yes | The Amazon Connect Contact ID for the call. |
## Response
`200 OK` with an array of samples sorted by `timestamp`. Each sample covers one second of network metrics for the contact.
```json theme={null}
[
{
"agentStatus": "Talk",
"jitter": 24,
"mos": 4.72,
"packetsReceived": 50,
"packetsSent": 50,
"rtt": 58,
"timestamp": "2026-05-18T10:14:22.272Z"
},
{
"agentStatus": "Talk",
"jitter": 22,
"mos": 4.75,
"packetsReceived": 50,
"packetsSent": 50,
"rtt": 56,
"timestamp": "2026-05-18T10:14:23.272Z"
}
]
```
| Field | Type | Description |
| - | - | - |
| `agentStatus` | string | `Talk` when the agent is unmuted, `Mute` when muted. |
| `jitter` | integer | Jitter for this sample, in milliseconds. |
| `mos` | number | Mean Opinion Score for this sample, 1.0–5.0. Higher is better. |
| `packetsReceived` | integer | Inbound packets in this one-second window. |
| `packetsSent` | integer | Outbound packets in this one-second window. |
| `rtt` | integer | Round-trip time for this sample, in milliseconds. |
| `timestamp` | string (ISO 8601) | UTC timestamp for the sample. |
Sample count matches contact duration — one entry per second of active call. For aggregated min/avg/max values across the whole contact, use [Get complete contact record](/docs/api-contact-record).
## Example
```bash curl theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls/db248964-dad8-4da8-8ca4-8094d2d254c5/details"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const contactId = "db248964-dad8-4da8-8ca4-8094d2d254c5";
const response = await fetch(
`https://api.operata.io/v1/data/calls/${contactId}/details`,
{ headers: { Authorization: `Basic ${auth}` } },
);
const samples = await response.json();
```
```python Python theme={null}
import os, requests
contact_id = "db248964-dad8-4da8-8ca4-8094d2d254c5"
response = requests.get(
f"https://api.operata.io/v1/data/calls/{contact_id}/details",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
response.raise_for_status()
samples = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 404 | `not_found` | No contact with `contactId` exists for this Operata account, or no per-second samples have arrived yet. | Confirm the ID against [List contact summaries](/docs/api-contact-summary). If the contact ended within the last minute, retry after a short delay. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family. For request caps see [Rate limits](/docs/api-rate-limits).
## Related
* [Get complete contact record](/docs/api-contact-record) — every captured field for the same contact, including aggregated network metrics.
* [List contact summaries](/docs/api-contact-summary) — list contacts to find a `contactId` to drill into.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
# List contact summaries
Source: https://docs.operata.com/docs/api-contact-summary
GET /v1/data/calls
Query a time window and get a paginated list of contacts — each with headline agent, network, audio, and duration metrics — to drive exports, listings, or alerting.
Query a time window and get a page of contacts with summary metrics — agent, location, network performance, MOS, and contact duration. Use it to power listing views, scheduled exports, or threshold-based alerting before drilling into the full record per contact.
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/data/calls
```
## Parameters
### Query
| Name | Type | Required | Description |
| - | - | - | - |
| `fromTime` | string (ISO 8601) | yes | Inclusive lower bound. UTC. |
| `toTime` | string (ISO 8601) | yes | Exclusive upper bound. UTC. |
| `cursor` | string | no | Opaque pagination cursor. See [Pagination](/docs/api-pagination). |
| `size` | integer | no | Page size. 1–100. Default 50. See [Pagination](/docs/api-pagination). |
| `contactId` | string | no | Filter to a single Amazon Connect Contact ID. |
| `networkType` | string | no | Filter by network type, for example `wlan` or `ethernet`. |
| `agentCity` | string | no | Filter by the agent's geolocated city. |
| `agentStatus` | string | no | Filter by agent status during the contact: `Talk` or `Mute`. |
| `mosFrom` | number | no | Inclusive lower bound on average MOS. Send with `mosTo`. |
| `mosTo` | number | no | Inclusive upper bound on average MOS. Send with `mosFrom`. |
| `jitterFrom` | integer | no | Inclusive lower bound on average jitter in milliseconds. Send with `jitterTo`. |
| `jitterTo` | integer | no | Inclusive upper bound on average jitter in milliseconds. Send with `jitterFrom`. |
| `rttFrom` | integer | no | Inclusive lower bound on average round-trip time in milliseconds. Send with `rttTo`. |
| `rttTo` | integer | no | Inclusive upper bound on average round-trip time in milliseconds. Send with `rttFrom`. |
| `packetsLostFrom` | integer | no | Inclusive lower bound on packets lost. Send with `packetsLostTo`. |
| `packetsLostTo` | integer | no | Inclusive upper bound on packets lost. Send with `packetsLostFrom`. |
Range filters (`mos*`, `jitter*`, `rtt*`, `packetsLost*`) require both ends in the same request.
## Response
`200 OK` with a paginated envelope. Each entry in `data[]` summarizes one contact.
```json theme={null}
{
"data": [
{
"softphoneSummary": {
"contactId": "6347b169-063f-48f1-8d2e-001204be6677",
"agentUserName": "agent_42",
"agentCity": "Sydney",
"agentRegion": "New South Wales",
"agentCountry": "Australia",
"agentISP": "Google LLC",
"agentExternalIPAddress": "35.197.161.176",
"agentLocalIPAddress": "192.168.1.12",
"networkType": "wlan",
"protocol": "udp",
"port": 52500,
"networkPerformanceMetrics": {
"jitter": { "min": 1, "avg": 12, "max": 30 },
"rtt": { "min": 63, "avg": 75, "max": 77 },
"packetLoss": { "min": 0, "avg": 1, "max": 2 },
"mos": { "min": 4.27, "avg": 4.32, "max": 4.40 },
"totals": {
"bytesReceived": 447283,
"bytesSent": 480531,
"packetsLost": 0,
"packetsSent": 0,
"packetsReceived": 0
}
}
},
"operataBillingSummary": {
"agentInteractionDurationRoundedMin": 1,
"agentInteractionDurationActualSec": 16,
"operataStatsDurationRoundedMin": 2,
"operataStatsDurationSec": 103
},
"contactDurationSummary": {
"contactDurationRoundedMin": 1,
"contactDurationActualSec": 27
}
}
],
"next_cursor": "eyJvZmZzZXQiOjUwfQ=="
}
```
| Field | Type | Description |
| - | - | - |
| `data[].softphoneSummary` | object | Agent, location, network, and call-quality metrics captured by the Agent Collector. |
| `data[].softphoneSummary.contactId` | string | Amazon Connect Contact ID. Pair with [Contact record](/docs/api-contact-record) or [Contact stats](/docs/api-contact-stats). |
| `data[].operataBillingSummary` | object | Durations Operata uses for billing rollups. |
| `data[].contactDurationSummary` | object | Total contact duration in seconds and rounded minutes. |
| `next_cursor` | string \| null | Cursor for the next page, or `null` at the end. See [Pagination](/docs/api-pagination). |
## Example
Fetch the first page of a 24-hour window, then advance to the next page using the returned cursor.
```bash curl theme={null}
# First page.
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-17T00:00:00Z&toTime=2026-05-18T00:00:00Z&size=50"
# Next page — copy `next_cursor` from the previous response.
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?cursor=eyJvZmZzZXQiOjUwfQ%3D%3D&size=50"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const url = new URL("https://api.operata.io/v1/data/calls");
url.searchParams.set("fromTime", "2026-05-17T00:00:00Z");
url.searchParams.set("toTime", "2026-05-18T00:00:00Z");
url.searchParams.set("size", "50");
const response = await fetch(url, {
headers: { Authorization: `Basic ${auth}` },
});
const { data, next_cursor: nextCursor } = await response.json();
```
```python Python theme={null}
import os, requests
response = requests.get(
"https://api.operata.io/v1/data/calls",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params={
"fromTime": "2026-05-17T00:00:00Z",
"toTime": "2026-05-18T00:00:00Z",
"size": 50,
},
)
response.raise_for_status()
body = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 400 | `invalid_range` | `toTime` is missing, equal to, or before `fromTime`. | Send a window where `toTime` is strictly after `fromTime`. |
| 400 | `invalid_cursor` | The cursor is malformed or was issued by a different query. | Restart from the first page with the same filters. See [Pagination](/docs/api-pagination). |
| 404 | `not_found` | No contact summary records match the window or filters. | Widen the window or remove a filter. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
# Data redaction
Source: https://docs.operata.com/docs/api-data-redaction
One config per Operata account controls which CTR fields the Cloud Collector ships. Three endpoints read, replace, and remove it.
The redaction config is a single JSON document stored against your Operata account. It tells the Cloud Collector which CTR (Contact Trace Record) fields to keep or drop before contact trace records leave AWS for Operata. One config per account. Three endpoints manage it.
## Endpoints
| Operation | Endpoint | Use it to |
| - | - | - |
| [Get redaction config](/docs/api-get-redaction-config) | `GET /v1/config/REDACTION_CONFIG/json` | Read the active config. Returns `404` if none is set. |
| [Update redaction config](/docs/api-update-redaction-config) | `PUT /v1/config/json` | Replace the active config with a new allow-list or deny-list. Full replace, not patch. |
| [Delete redaction config](/docs/api-delete-redaction-config) | `DELETE /v1/config/REDACTION_CONFIG` | Remove the active config. The collector reverts to the privacy-first default. |
Each endpoint is idempotent. See [Idempotency](/docs/api-idempotency) for the per-method contract. `PUT` is a full replace — fields you omit from the new body do not survive the call.
## Config shape
The config is one of two shapes, distinguished by `value.type`:
* `WHITELIST` — allow-list. Ships only the mandatory CTR fields plus the fields you name.
* `BLACKLIST` — deny-list. Ships every CTR field except the ones you name.
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": [
"Attributes.CustomerDetails"
]
}
}
```
The mandatory CTR fields (for example `ContactId`, `InitiationTimestamp`, `Queue.Name`) ship regardless. A deny-list cannot remove them; an allow-list cannot omit them.
With no config in place, the Cloud Collector applies the privacy-first default and ships only the mandatory CTR fields. The endpoints return `404` in that state.
## Related
* [Get redaction config](/docs/api-get-redaction-config) — inspect what is in effect.
* [Update redaction config](/docs/api-update-redaction-config) — replace the active config.
* [Delete redaction config](/docs/api-delete-redaction-config) — remove the config and revert to the default.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — the step-by-step rollout guide.
* [Contact trace records](/docs/contact-trace-records) — the CTR data model the `fields` array references.
* [Errors](/docs/api-errors), [Rate limits](/docs/api-rate-limits), [Idempotency](/docs/api-idempotency), [Versioning](/docs/api-versioning) — shared API conventions.
# Delete redaction config
Source: https://docs.operata.com/docs/api-delete-redaction-config
DELETE /v1/config/REDACTION_CONFIG
Remove the active CTR redaction config for your Operata account and revert the Cloud Collector to the privacy-first default.
Removes the redaction config for your Operata account. After the call, the Cloud Collector reverts to the privacy-first default and ships only the mandatory CTR fields. Use it to roll back a config before applying a new one, or to retire a config you no longer need.
**Destructive operation.** Deleting the redaction config opens a propagation window during which subsequent CTRs may include PII fields the config previously stripped. The collector keeps applying the old config to in-flight contacts for up to 30 minutes after this call returns, then reverts to the default. To change the field set without this exposure window, send a new config to [`PUT /v1/config/json`](/docs/api-update-redaction-config) instead — that replaces the document atomically.
`DELETE /v1/config/REDACTION_CONFIG` is idempotent. Deleting an already-deleted config converges on the same end state — no config, collector on the default. The current wire response on a second call is `404` (see [Errors](#errors) below); treat it as success. See [Idempotency](/docs/api-idempotency) for the per-method contract.
## Endpoint
```http theme={null}
DELETE https://api.operata.io/v1/config/REDACTION_CONFIG
```
## Parameters
### Headers
| Name | Type | Required | Description |
| - | - | - | - |
| `Idempotency-Key` | string | no, not yet honored | Reserved for a future contract. The endpoint is already idempotent — deleting an already-deleted config returns `404` and the end state matches. See [Idempotency](/docs/api-idempotency). |
This endpoint takes no path, query, or body parameters. Credentials on the request determine the Operata account scope.
## Response
`200 OK` with a plain-text body `REDACTION_CONFIG removed`.
```text theme={null}
REDACTION_CONFIG removed
```
The deletion is durable as soon as the call returns. Propagation across all collection points can take up to 30 minutes; CTRs from contacts that end during that window may still apply the now-deleted config.
## Example
```bash curl theme={null}
curl -X DELETE -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/config/REDACTION_CONFIG"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const response = await fetch(
"https://api.operata.io/v1/config/REDACTION_CONFIG",
{
method: "DELETE",
headers: { Authorization: `Basic ${auth}` },
},
);
```
```python Python theme={null}
import os, requests
response = requests.delete(
"https://api.operata.io/v1/config/REDACTION_CONFIG",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
response.raise_for_status()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 404 | `not_found` | No redaction config exists for this Operata account. Either it was never created, or a previous `DELETE` already removed it. | Confirm with [Get redaction config](/docs/api-get-redaction-config). If no config is expected, treat `404` as success — the end state matches. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
## Related
* [Data redaction](/docs/api-data-redaction) — what redaction does and how the three endpoints fit together.
* [Get redaction config](/docs/api-get-redaction-config) — confirm what is in effect before you delete it.
* [Update redaction config](/docs/api-update-redaction-config) — replace the config atomically instead of deleting then re-creating.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
* [Rate limits](/docs/api-rate-limits) — per-token request budget.
* [Idempotency](/docs/api-idempotency) — `DELETE` is idempotent; the end state matches whether the config existed or not.
* [Versioning](/docs/api-versioning) — this endpoint lives under `/v1`.
# Errors
Source: https://docs.operata.com/docs/api-errors
Every HTTP status code and stable `error.code` the Operata API returns, with the recovery pattern for each.
Every Operata API endpoint returns standard HTTP status codes and, where useful, a stable string `error.code` you match on — use that code in your error-handling logic, not the human-readable `message`.
## Endpoint
```http theme={null}
Any endpoint under https://api.operata.io
```
## Parameters
This page covers error responses. The error shape applies to every endpoint; check each endpoint's own reference page for the codes it emits.
## Response
Operata returns errors as JSON in a stable envelope:
```json theme={null}
{
"error": {
"status": 400,
"code": "invalid_range",
"message": "to must be after from."
}
}
```
| Field | Type | Description |
| - | - | - |
| `error.status` | integer | The HTTP status code, repeated in the body for clients that only parse JSON. |
| `error.code` | string | A short, stable identifier. Match on this, not on `message`. |
| `error.message` | string | A human-readable summary. Wording can change between releases; do not parse it. |
## Example
An error response from a reversed time window on the contact summary endpoint:
```bash curl theme={null}
curl -i -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-17T00:00:00Z"
```
```python Python theme={null}
import os, requests
response = requests.get(
"https://api.operata.io/v1/data/calls",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params={"fromTime": "2026-05-18T00:00:00Z", "toTime": "2026-05-17T00:00:00Z"},
)
if response.status_code >= 400:
body = response.json().get("error", {})
print(body["code"], body["message"])
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 400 | `invalid_request` | The request body or query string did not validate against the endpoint schema. | Read `error.message` and fix the client. Do not retry until the input changes. |
| 400 | `invalid_range` | `fromTime` and `toTime` are missing, equal, or out of order. | Send a window where `toTime` is strictly after `fromTime`. |
| 400 | `invalid_config` | The redaction config body failed validation (returned as `REDACTION_CONFIG not valid` today). | Check the field names against [Data redaction](/docs/api-data-redaction) and re-send. |
| 401 | `unauthorized` | The `Authorization` header is missing, malformed, or the credentials are wrong. | See [Authentication](/docs/api-authentication). Rotate the token if you suspect it leaked. |
| 403 | `forbidden` | The credentials are valid but the Operata account does not have access to the resource. | Ask an account admin to grant the relevant role. |
| 404 | `not_found` | The resource you requested does not exist for this Operata account. Examples: an unknown `contactId`, a redaction config that has not been created yet. | Confirm the identifier. For redaction config, create it with `PUT /v1/config/json` first. |
| 409 | `conflict` | A write conflicts with current state (for example, deleting a resource that another request just deleted). | Re-fetch the current state and decide whether to retry. |
| 422 | `invalid_signal` | A submitted signal payload references fields that the platform does not recognize. | Compare your payload against the relevant glossary page in **Data reference**, for example [Contact trace records](/docs/contact-trace-records). |
| 429 | `rate_limited` | You exceeded the per-token request budget. | Back off using the `Retry-After` header. See [Rate limits](/docs/api-rate-limits). |
| 500 | `internal_error` | An unexpected error in the Operata platform. | Retry with exponential backoff. If it persists, capture the response and contact support. |
| 502 | `bad_gateway` | A downstream dependency (Amazon Connect, Kinesis) is unreachable. | Retry with exponential backoff. |
| 503 | `service_unavailable` | The platform is in a brief degraded state, typically during a deploy. | Retry with exponential backoff. |
| 504 | `gateway_timeout` | An upstream request took longer than the gateway allows. | Retry with exponential backoff. Narrow the query window if it persists. |
# Get redaction config
Source: https://docs.operata.com/docs/api-get-redaction-config
GET /v1/config/REDACTION_CONFIG/json
Fetch the active CTR redaction config for your Operata account so you can confirm what is in effect before changing it.
Fetches the redaction config currently in effect for your Operata account, as a single JSON document. Use it to confirm the active allow-list or deny-list before you replace or remove it. If no config exists, the endpoint returns `404` and the Cloud Collector falls back to the privacy-first default — it ships only the mandatory CTR fields.
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/config/REDACTION_CONFIG/json
```
## Parameters
This endpoint takes no parameters. Credentials on the request determine the Operata account scope.
## Response
`200 OK` with the active redaction config.
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": [
"Agent.ARN",
"Agent.RoutingProfile"
]
}
}
```
| Field | Type | Description |
| - | - | - |
| `key` | string | Always `REDACTION_CONFIG`. Identifies the config record. |
| `value` | object | The redaction config body. |
| `value.type` | string | `WHITELIST` for an allow-list, `BLACKLIST` for a deny-list. One config per account; the two modes are mutually exclusive. |
| `value.fields` | array of string | The CTR field paths to include (allow-list) or exclude (deny-list). Dot notation matches the CTR data model — see [Contact trace records](/docs/contact-trace-records). |
## Example
```bash curl theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/config/REDACTION_CONFIG/json"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const response = await fetch(
"https://api.operata.io/v1/config/REDACTION_CONFIG/json",
{ headers: { Authorization: `Basic ${auth}` } },
);
const config = await response.json();
```
```python Python theme={null}
import os, requests
response = requests.get(
"https://api.operata.io/v1/config/REDACTION_CONFIG/json",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
response.raise_for_status()
config = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 404 | `not_found` | No redaction config exists for this Operata account. The Cloud Collector falls back to the privacy-first default. | Create a config with [Update redaction config](/docs/api-update-redaction-config) if you want to override the default. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
## Related
* [Data redaction](/docs/api-data-redaction) — what redaction does and how the three endpoints fit together.
* [Update redaction config](/docs/api-update-redaction-config) — replace the active config.
* [Delete redaction config](/docs/api-delete-redaction-config) — remove the config and revert to the default.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
* [Rate limits](/docs/api-rate-limits) — per-token request budget.
* [Idempotency](/docs/api-idempotency) — `GET` is idempotent; retry without coordination.
* [Versioning](/docs/api-versioning) — this endpoint lives under `/v1`.
# Getting started with the Operata API
Source: https://docs.operata.com/docs/api-getting-started
Authenticate with HTTP Basic, make your first call, and read the paginated response envelope Operata returns from every list endpoint.
The Operata API gives you programmatic access to every contact, observation, and insight your collectors have stored. You authenticate with HTTP Basic — your Group ID as username, your API token as password — then hit `https://api.operata.io`. This guide walks you through generating credentials, making your first call, and reading the paginated response envelope.
## Before you start
* An [Operata account](https://app.operata.io). Your **Operata Group ID** is the UUID in the console URL.
* The Admin role on that account. The console exposes token creation under **Settings → Config → API**.
* `curl` (any recent version) and a shell that exports environment variables.
## Steps
### 1. Generate an API token
In the Operata console, go to **Settings → Config → API** and click **Create token**. Copy the token immediately — the console shows it once. Treat tokens like passwords.
```bash theme={null}
export OPERATA_GROUP_ID="a28453f9-abab-cdcd-efef-84d9e67ac297"
export OPERATA_API_TOKEN="paste-your-token-here"
```
You now have credentials in your shell. See [Authentication](/docs/api-authentication) for the full credential lifecycle.
### 2. Make your first call
Operata uses HTTP Basic. The Group ID is the username, the token is the password. Hit the contact summary endpoint with a small window:
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-17T00:00:00Z&toTime=2026-05-18T00:00:00Z&size=1"
```
A `200 OK` confirms your credentials are valid and the account has access to contact data.
### 3. Read the response envelope
Every list endpoint returns the same envelope: a `data` array and a `next_cursor` you follow for the next page.
```json theme={null}
{
"data": [
{
"id": "ctr_0HXYZ123456789ABCDE",
"started_at": "2026-05-17T15:02:11Z",
"duration_ms": 184200
}
],
"next_cursor": "eyJvZmZzZXQiOjUwfQ=="
}
```
You parse `data` for the records and re-send the request with `cursor=` to walk further. See [Pagination](/docs/api-pagination) for the loop pattern.
### 4. Handle errors and rate limits
Operata returns a stable JSON error envelope on every 4xx and 5xx:
```json theme={null}
{ "error": { "status": 401, "code": "unauthorized", "message": "Invalid credentials." } }
```
Match on `error.code`, not on `error.message`. Honor the `Retry-After` header on `429 rate_limited` — the default budget is 100 requests per minute per token. See [Errors](/docs/api-errors) and [Rate limits](/docs/api-rate-limits).
## Verify
Run the call from step 2 again and confirm three things:
* The HTTP status is `200`.
* The body parses as JSON with a `data` array.
* The response headers include `X-RateLimit-Remaining` with a value below 100.
If you see `401 unauthorized`, your Group ID and token do not pair correctly — re-check the env vars. If you see `400 invalid_range`, the time window is malformed; the `toTime` must be strictly after `fromTime`.
## Related
* [Quickstart](/docs/quickstart) — the 90-second version of this guide, when you want the curl line and nothing else.
* [Pagination](/docs/api-pagination) — walk every page of a result set with one cursor variable.
* [Contact summary](/docs/api-contact-summary) — the first endpoint most integrations call.
* [Data redaction](/docs/api-data-redaction) — strip sensitive fields before they reach Operata.
# Idempotency
Source: https://docs.operata.com/docs/api-idempotency
Which Operata write endpoints are safe to retry today, and the planned `Idempotency-Key` header contract for future POST endpoints.
The Operata API is idempotent today by HTTP method — `GET`, `PUT`, and `DELETE` are all safe to retry without coordination. `POST` endpoints are not yet exposed; when they are, the platform will honor a Stripe-style `Idempotency-Key` header contract described below.
## Endpoint
```http theme={null}
Any write endpoint under https://api.operata.io
```
## Parameters
| Name | Type | Required | Description |
| - | - | - | - |
| `Idempotency-Key` | string (header) | no, not yet honored | Reserved for a future contract. The server accepts the header today but does not act on it. See the rollout plan below. |
## Response
Today, idempotency is a property of the HTTP method, not of an extra header. The current Operata API behaves as follows on retry:
| Method | Endpoint | Idempotent today | Notes |
| - | - | - | - |
| `GET` | every read endpoint | yes | Reads never change state. Retry without coordination. |
| `PUT` | `/v1/config/json` | yes | Sending the same redaction config body twice yields the same final state. Sending a different body replaces the previous one. |
| `DELETE` | `/v1/config/REDACTION_CONFIG` | yes | Deleting an already-deleted config returns `404 not_found`. The end state matches. |
| `POST` | none today | n/a | The current API exposes no `POST` write endpoints. When it does, the rules below apply. |
The planned `Idempotency-Key` contract follows the Stripe pattern:
* The key is a client-generated string, opaque to the server, 1–255 characters. UUIDv4 is the recommended shape.
* The server stores the response for 24 hours, keyed by the tuple `(token, method, path, idempotency_key)`.
* A repeat request with the same key returns the stored response with header `Idempotency-Replayed: true`.
* A repeat request with the same key but a different body returns `409 conflict` with code `idempotency_conflict`.
* After the 24-hour window, the key is forgotten and the request executes normally.
## Example
Sending the same redaction config twice leaves one final state:
```bash curl theme={null}
# First request — writes the config.
curl -X PUT -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"REDACTION_CONFIG","value":{"type":"BLACKLIST","fields":["Agent.ARN"]}}' \
"https://api.operata.io/v1/config/json"
# Same request, sent again — same final state, no duplicate side-effects.
curl -X PUT -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"REDACTION_CONFIG","value":{"type":"BLACKLIST","fields":["Agent.ARN"]}}' \
"https://api.operata.io/v1/config/json"
```
```python Python theme={null}
import os, uuid, requests
# Generate one key per logical operation, not per HTTP attempt.
# The header is accepted today but not honored — include it now to be ready.
key = str(uuid.uuid4())
headers = {"Idempotency-Key": key, "Content-Type": "application/json"}
body = {"key": "REDACTION_CONFIG", "value": {"type": "BLACKLIST", "fields": ["Agent.ARN"]}}
response = requests.put(
"https://api.operata.io/v1/config/json",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
headers=headers,
json=body,
)
response.raise_for_status()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 409 | `idempotency_conflict` | A future request reuses an `Idempotency-Key` from the last 24 hours with a different body. Reserved; not emitted today. | Either send the original body or generate a new key. |
| 400 | `invalid_idempotency_key` | Reserved. The key violates the length or character set rules. | Generate a fresh UUIDv4. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized` and `429 rate_limited`.
# Get configured users
Source: https://docs.operata.com/docs/api-list-users
GET /v2/admin/users
List all teammates in your Operata account — their roles, emails, and the groups they belong to — so you can audit access or map Operata user IDs to your own identity store.
Returns every teammate configured in the Operata account, with each user's role and the groups they belong to. Use it to audit who has access or to map Operata user IDs to your own identity store.
## Endpoint
```http theme={null}
GET https://api.operata.io/v2/admin/users
```
## Parameters
This endpoint takes no parameters. Credentials on the request determine the Operata account scope.
## Response
`200 OK` with the configured users for the account.
```json theme={null}
[
{
"id": 714,
"name": "Andy Admin",
"email": "admin@example.com",
"role": "Group Admin",
"groups": [
{
"id": "a28453f9-abab-cdcd-efef-84d9e67ac297",
"name": "Operata Demo",
"ccp": "https://operata-prod.awsapps.com/connect/ccp-v2"
}
]
}
]
```
| Field | Type | Description |
| - | - | - |
| `id` | integer | Stable internal user ID. |
| `name` | string | Display name as configured in the Operata console. |
| `email` | string | The user's login email. |
| `role` | string | The user's role. Today: `Group Admin` or `User`. Treat as an opaque string — additional roles may appear without a version bump. |
| `groups` | array | Each Operata account the user belongs to, with the CCP URL for that group. |
| `groups[].id` | string (UUID) | The Operata Group ID for that account. Used as the username for HTTP Basic on API requests. |
| `groups[].name` | string | Human-readable group name. |
| `groups[].ccp` | string (URL) | The Amazon Connect CCP URL associated with the group. |
## Example
```bash curl theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v2/admin/users"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const response = await fetch("https://api.operata.io/v2/admin/users", {
headers: { Authorization: `Basic ${auth}` },
});
const users = await response.json();
```
```python Python theme={null}
import os, requests
response = requests.get(
"https://api.operata.io/v2/admin/users",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
)
response.raise_for_status()
users = response.json()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 403 | `forbidden` | The token belongs to a user without the Admin role. | Generate a token from an account with the **Group Admin** role under **Settings → Config → API**. |
| 404 | `not_found` | No users exist in the Operata account this token authenticates to. | Confirm you sent the right `Operata Group ID` in the Basic credentials. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
## Related
* [Authentication](/docs/api-authentication) — how the `Operata Group ID` returned in `groups[].id` authenticates API requests.
* [Versioning](/docs/api-versioning) — this endpoint lives under `/v2`; the versioning policy explains how `/v1` and `/v2` coexist.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
# Pagination
Source: https://docs.operata.com/docs/api-pagination
Cursor-based pagination for Operata list endpoints — the response envelope, `next_cursor` semantics, and a complete loop example.
List endpoints return one page at a time. Walk the full result set by following the opaque `next_cursor` value from each response until the server returns `null`. The cursor is the only state you carry between pages.
## Endpoint
```http theme={null}
GET https://api.operata.io/v1/data/calls
GET https://api.operata.io/v1/data/ccpLogs
```
Any endpoint that returns a list uses this envelope.
## Parameters
### Query
| Name | Type | Required | Description |
| - | - | - | - |
| `cursor` | string | no | Opaque cursor returned by the previous page. Omit on the first request. |
| `size` | integer | no | Page size. 1–100. Default 50. |
| `fromTime` | string (ISO 8601) | endpoint-dependent | Inclusive lower bound for time-windowed lists. UTC. |
| `toTime` | string (ISO 8601) | endpoint-dependent | Exclusive upper bound for time-windowed lists. UTC. |
## Response
Every list response uses the same JSON envelope:
```json theme={null}
{
"data": [
{ "id": "ctr_0HXYZ123456789ABCDE", "started_at": "2026-05-18T10:14:22Z" }
],
"next_cursor": "eyJvZmZzZXQiOjUwfQ=="
}
```
| Field | Type | Description |
| - | - | - |
| `data` | array | The page of records. Length is at most `size`. |
| `next_cursor` | string \| null | Cursor for the next page, or `null` when you have reached the end. |
The cursor is opaque — don't parse it, base64-decode it, or assume it encodes an offset. Treat it as a string token the server issues and you echo back unchanged.
## Example
A loop that fetches every contact in a 24-hour window:
```bash curl theme={null}
# First page.
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-17T00:00:00Z&toTime=2026-05-18T00:00:00Z&size=50"
# Next page — copy the `next_cursor` from the previous response.
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?cursor=eyJvZmZzZXQiOjUwfQ%3D%3D&size=50"
```
```python Python theme={null}
import os, requests
def iter_contacts(from_iso, to_iso, size=50):
cursor = None
while True:
params = {"fromTime": from_iso, "toTime": to_iso, "size": size}
if cursor:
params["cursor"] = cursor
response = requests.get(
"https://api.operata.io/v1/data/calls",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params=params,
)
response.raise_for_status()
body = response.json()
for record in body["data"]:
yield record
cursor = body.get("next_cursor")
if cursor is None:
return
for contact in iter_contacts("2026-05-17T00:00:00Z", "2026-05-18T00:00:00Z"):
print(contact["id"])
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 400 | `invalid_cursor` | The cursor is malformed or was issued by a different query (different time window or filters). | Restart the walk from the first page with the same filters. Do not edit the cursor. |
| 400 | `invalid_range` | `toTime` is missing, equal to, or before `fromTime`. | Send a valid window. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized` and `429 rate_limited`.
# Rate limits
Source: https://docs.operata.com/docs/api-rate-limits
The Operata API enforces 100 requests per minute per token. Reference for the rate-limit headers, the 429 response body, and the correct back-off pattern.
The Operata API caps each API token at 100 requests per minute. When you exceed the budget the API returns `429 rate_limited` with a `Retry-After` header. Back off and retry; do not retry without a delay.
## Endpoint
```http theme={null}
Any endpoint under https://api.operata.io
```
## Parameters
Rate limiting applies to every request. Three response headers show your current standing:
| Name | Type | Required | Description |
| - | - | - | - |
| `X-RateLimit-Limit` | integer | yes | The per-token request ceiling for the current window. Currently 100. |
| `X-RateLimit-Remaining` | integer | yes | Requests left in the current window. Hits zero before you receive 429. |
| `X-RateLimit-Reset` | integer | yes | Unix epoch seconds when the window rolls over and `Remaining` resets to `Limit`. |
| `Retry-After` | integer | on 429 only | Seconds to wait before the next request. Use this; do not invent your own delay. |
## Response
A throttled request returns the standard error envelope from [Errors](/docs/api-errors):
```json theme={null}
{
"error": {
"status": 429,
"code": "rate_limited",
"message": "You have exceeded the per-token rate limit of 100 requests per minute."
}
}
```
The response headers tell you exactly when to retry:
```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1747555417
Content-Type: application/json
```
## Example
A client that reads `Retry-After` and adds exponential back-off:
```bash curl theme={null}
# Inspect headers on every response.
curl -i -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?size=1"
```
```python Python theme={null}
import os, time, requests
def call_with_backoff(url, params, max_attempts=5):
delay = 1.0
for attempt in range(max_attempts):
response = requests.get(
url,
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params=params,
)
if response.status_code != 429:
return response
wait = int(response.headers.get("Retry-After", delay))
time.sleep(wait)
delay *= 2
response.raise_for_status()
call_with_backoff(
"https://api.operata.io/v1/data/calls",
{"fromTime": "2026-05-17T00:00:00Z", "toTime": "2026-05-18T00:00:00Z", "size": "50"},
)
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 429 | `rate_limited` | You exceeded 100 requests per minute on this token. | Wait `Retry-After` seconds, then retry. Add exponential back-off if 429 repeats. |
See [Errors](/docs/api-errors) for the full status code table.
# Update redaction config
Source: https://docs.operata.com/docs/api-update-redaction-config
PUT /v1/config/json
Replace the active CTR redaction config for your Operata account with a new allow-list or deny-list document.
Replaces the redaction config for your Operata account with the body you send. It's a full replace, not a patch — the document on disk after the call equals the document you sent. Use it to apply a new allow-list, switch from an allow-list to a deny-list, or extend the field set on an existing config.
## Endpoint
```http theme={null}
PUT https://api.operata.io/v1/config/json
```
## Parameters
### Headers
| Name | Type | Required | Description |
| - | - | - | - |
| `Content-Type` | string | yes | `application/json`. |
| `Idempotency-Key` | string | no, not yet honored | Reserved for a future contract. The endpoint is already idempotent — sending the same body twice yields the same final state. See [Idempotency](/docs/api-idempotency). |
### Body
| Name | Type | Required | Description |
| - | - | - | - |
| `key` | string | yes | Always `REDACTION_CONFIG`. |
| `value` | object | yes | The config document. |
| `value.type` | string | yes | `WHITELIST` for an allow-list, `BLACKLIST` for a deny-list. One config per account; the two are mutually exclusive. |
| `value.fields` | array of string | yes | CTR field paths to include (allow-list) or exclude (deny-list). Use dot notation matching the [CTR data model](/docs/contact-trace-records). An empty array on a deny-list sends the full CTR; an empty array on an allow-list sends only the mandatory fields. |
The Cloud Collector always ships the mandatory CTR fields (for example `ContactId`, `InitiationTimestamp`, `Queue.Name`) regardless of config. You cannot remove them with a deny-list or omit them from an allow-list.
`PUT /v1/config/json` is idempotent. Sending the same body twice yields the same final state — the document on disk after the second call equals the one on disk after the first. Retry safely. See [Idempotency](/docs/api-idempotency) for the per-method contract across the API.
## Response
`200 OK` with a plain-text body `REDACTION_CONFIG updated`.
```text theme={null}
REDACTION_CONFIG updated
```
The config is durable as soon as the call returns, but propagation across all collection points can take up to 30 minutes. CTRs from contacts that end before propagation completes may still apply the previous config.
## Example
A deny-list that strips one PII attribute from every CTR:
```bash curl theme={null}
curl -X PUT -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": ["Attributes.CustomerDetails"]
}
}' \
"https://api.operata.io/v1/config/json"
```
```javascript Node.js theme={null}
const groupId = process.env.OPERATA_GROUP_ID;
const apiToken = process.env.OPERATA_API_TOKEN;
const auth = Buffer.from(`${groupId}:${apiToken}`).toString("base64");
const body = {
key: "REDACTION_CONFIG",
value: {
type: "BLACKLIST",
fields: ["Attributes.CustomerDetails"],
},
};
const response = await fetch("https://api.operata.io/v1/config/json", {
method: "PUT",
headers: {
Authorization: `Basic ${auth}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
```
```python Python theme={null}
import os, requests
body = {
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": ["Attributes.CustomerDetails"],
},
}
response = requests.put(
"https://api.operata.io/v1/config/json",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
headers={"Content-Type": "application/json"},
json=body,
)
response.raise_for_status()
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 400 | `invalid_config` | The body failed validation. Today the wire response is `text/plain` `REDACTION_CONFIG not valid`. Common causes: misspelled `type` (must be exactly `WHITELIST` or `BLACKLIST`), a field path that does not exist in the CTR data model, or malformed JSON. | Check `type`, check each entry in `fields` against the [CTR data model](/docs/contact-trace-records), and re-send. |
See [Errors](/docs/api-errors) for shared codes such as `401 unauthorized`, `429 rate_limited`, and the `5xx` family.
## Related
* [Data redaction](/docs/api-data-redaction) — what redaction does and how the three endpoints fit together.
* [Get redaction config](/docs/api-get-redaction-config) — fetch the current config before you replace it.
* [Delete redaction config](/docs/api-delete-redaction-config) — remove the config and revert to the default.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — the step-by-step rollout guide.
* [Errors](/docs/api-errors) — shared status codes and recovery patterns.
* [Rate limits](/docs/api-rate-limits) — per-token request budget.
* [Idempotency](/docs/api-idempotency) — `PUT` is idempotent; sending the same body twice yields the same final state.
* [Versioning](/docs/api-versioning) — this endpoint lives under `/v1`.
# Versioning
Source: https://docs.operata.com/docs/api-versioning
How Operata versions the API by URL prefix, what counts as a breaking change, and how deprecations are announced via response headers.
Operata versions the API by URL prefix. The current stable version is `v1`. Endpoints under `/v2/` are stable but scoped to admin-only surfaces today. Breaking changes ship behind a new prefix; additive changes ship in place.
## Endpoint
```http theme={null}
https://api.operata.io/v1/...
https://api.operata.io/v2/...
```
## Parameters
There's no version header — the version lives in the path. Pin your client to the prefix you tested against.
| Prefix | Status | Surface |
| - | - | - |
| `/v1/` | stable | Data endpoints (`/v1/data/calls`, `/v1/data/{contactId}`, `/v1/data/calls/{contactId}/details`, `/v1/data/ccpLogs`), redaction config (`/v1/config/*`). |
| `/v2/` | stable | Admin endpoints (`/v2/admin/users`). New admin endpoints land here, not under `/v1/`. |
## Response
Operata signals deprecation on the response headers of any endpoint scheduled for removal:
```http theme={null}
HTTP/1.1 200 OK
Deprecation: true
Sunset: Tue, 17 Nov 2026 00:00:00 GMT
Link: ; rel="deprecation"
```
| Header | When present | Meaning |
| - | - | - |
| `Deprecation` | the endpoint is deprecated | Always the literal string `true`. |
| `Sunset` | the endpoint has a removal date | RFC 7231 HTTP date. The endpoint stops responding after this date. |
| `Link` | always with `Deprecation` | Points at the changelog entry that describes the replacement. |
The Operata change policy:
* **Additive changes ship in place.** New optional fields on responses, new optional query parameters, new endpoints under an existing version. Your client keeps working without changes.
* **Breaking changes ship under a new prefix.** Renamed fields, removed fields, changed types, new required parameters, changed status codes, changed error codes — these go to the next major version. Operata does not silently change the wire shape of an existing endpoint.
* **Deprecation window is six months minimum.** From the day a `Sunset` header first appears, you have at least six months before the endpoint stops responding. Watch the [API changelog](/docs/api-changelog) for the announcement.
## Example
A deprecation-aware client inspects response headers on every call:
```bash curl theme={null}
curl -i -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?size=1" \
| grep -iE '^(deprecation|sunset|link):'
```
```python Python theme={null}
import os, requests
from email.utils import parsedate_to_datetime
response = requests.get(
"https://api.operata.io/v1/data/calls",
auth=(os.environ["OPERATA_GROUP_ID"], os.environ["OPERATA_API_TOKEN"]),
params={"size": "1"},
)
if response.headers.get("Deprecation") == "true":
sunset = response.headers.get("Sunset")
print(f"deprecated; sunsets {sunset}")
if sunset:
deadline = parsedate_to_datetime(sunset)
# Schedule the migration before deadline.
```
## Errors
| Status | Code | When | Recover |
| - | - | - | - |
| 404 | `unknown_version` | The path begins with a version prefix the API does not recognize, for example `/v3/data/calls`. | Pin to a documented version: `v1` for data, `v2` for admin. |
| 410 | `version_sunset` | You called an endpoint after its `Sunset` date. | Migrate to the replacement listed in the [API changelog](/docs/api-changelog). |
See [Errors](/docs/api-errors) for shared codes.
# Configure webhooks
Source: https://docs.operata.com/docs/api-webhooks-configure
Create the Operata partner event source in your AWS account and bind it to an Amazon EventBridge event bus so Operata events start flowing to your targets.
Bind the Operata partner event source to an Amazon EventBridge bus in your AWS account, so Operata events land on the bus ready for you to attach rules and targets.
## Before you start
* An [Operata account](/docs/api-authentication) with the **Group Admin** role on the group you want events for.
* An AWS account where you can administer EventBridge — permission to associate a partner event source and create rules in the target region.
* Your **12-digit AWS account number** and the **AWS region** that should receive the events.
The partner event source is bound to one AWS account and region. Operata cannot move it after creation. Confirm the destination before you raise the request.
## Steps
### 1. Request the partner event source from Operata
Email [Operata Support](mailto:support@operata.com) with:
* The 12-digit AWS account number that receives the events.
* The AWS region the event source must live in.
* The Operata group the events are for.
Operata creates the partner event source and replies with the **Event Source Name** — a string of the form `aws.partner/operata.com//`. The source appears in your AWS console under **Amazon EventBridge → Partner event sources** in the requested region, in the `Pending` state.
### 2. Associate the partner event source with an event bus
In the AWS console, open **EventBridge → Partner event sources** in the region Operata provisioned, then:
1. Select the event source Operata created.
2. Choose **Associate with event bus**.
3. Accept the suggested bus name (it matches the event source name) or set your own.
The state changes from `Pending` to `Active`. EventBridge creates a custom event bus under **EventBridge → Event buses** with the name you accepted.
### 3. Create at least one EventBridge rule
Without a rule, events arrive on the bus and are discarded. Create a rule that matches the event types you care about and routes them to a target:
```json theme={null}
{
"source": ["aws.partner/operata.com/a28453f9-abab-cdcd-efef-84d9e67ac297/acmeEventBus"],
"detail-type": ["CallSummary", "InsightsSummary"]
}
```
Common targets: CloudWatch Logs (for inspection), Lambda (for transformation), SQS or Kinesis (for fan-out), or another EventBridge bus in a different account. See the [event catalog](/docs/api-webhooks-events) for the full list of `detail-type` values.
## Result
Place a test contact through the Amazon Connect instance Operata is observing, then wait up to 5 minutes for post-contact enrichment. In CloudWatch Logs (or the target you wired up), look for a `CallSummary` event whose `detail.contact.id.current` matches the contact ID from the CCP.
If no event arrives within 5 minutes:
* Confirm the partner event source is `Active`, not `Pending`.
* Confirm the rule matches on the `source` exactly as Operata sent it.
* Confirm the target has permission to receive events from EventBridge.
## Related
* [Event catalog](/docs/api-webhooks-events) — every `detail-type`, its payload, and when it fires.
* [Webhooks overview](/docs/api-webhooks-overview) — the delivery model and example consumers.
* [Versioning](/docs/api-versioning) — how Operata ships additive and breaking changes to event payloads.
# Event catalog
Source: https://docs.operata.com/docs/api-webhooks-events
Every Operata Amazon EventBridge event type — detail-type, trigger condition, and example payload.
Every event type Operata publishes to your partner event source. Each entry covers the `detail-type`, trigger condition, and an example payload.
Post-contact events arrive between 30 seconds and 5 minutes after the contact ends. Build consumers that key off `detail.contact.id.current` rather than wall-clock order.
## Call summary
The enriched contact record — one event per completed contact.
**`detail-type`:** `CallSummary`
**When it fires:** After a contact completes, once Operata finishes joining the CTR, agent-side telemetry, and WebRTC session metrics.
**Payload:**
```json theme={null}
{
"version": "0",
"id": "530848f3-1111-2222-3333-b33ba70c19f0",
"detail-type": "CallSummary",
"source": "aws.partner/operata.com/a28453f9-1111-2222-3333-84d9e67ac297/customerEventBus",
"account": "083560837128",
"time": "2023-06-01T05:00:13Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"accountProperties": {
"operataGroupName": "Operata",
"operataGroupId": "a28453f9-1111-2222-3333-84d9e67ac297"
},
"contact": {
"id": {
"current": "ac7a6a89-1111-2222-3333-1e659475d24e",
"previous": "",
"next": ""
},
"direction": "Inbound",
"events": {
"connectingToAgent": "2023-06-01T04:59:51.523Z",
"enqueued": "2023-06-01T04:59:30.795Z"
},
"endedBy": "Agent",
"queueName": "Operata Prod Default Queue",
"callerId": "+61402960149"
},
"webRTCSession": {
"metrics": {
"inbound": {
"packetsReceived": 636,
"packetsLost": 12,
"packetsLostPercentage": 1.85,
"bytesReceived": 67178,
"audioLevel": {
"min": 0,
"max": 400,
"avg": 51.23
},
"jitterBufferMils": {
"min": 0,
"max": 8,
"avg": 3
}
},
"outbound": {
"packetsSent": 786,
"packetsLost": 10,
"packetsLostPercentage": 1.27,
"bytesSent": 65585,
"audioLevel": {
"min": 0,
"max": 4515,
"avg": 618.62
},
"jitterBufferMils": {
"min": 4,
"max": 26,
"avg": 11.23
}
},
"rtt": {
"min": 0,
"max": 145,
"avg": 110
},
"jitter": {
"min": 0,
"max": 8,
"avg": 3
},
"mos": {
"min": 3.65,
"max": 4.43,
"avg": 4.25
}
},
"serviceEndpoint": {
"fqdn": "",
"transportLifeTimeSeconds": 0,
"expiry": "0001-01-01T00:00:00Z"
},
"mediaEndpoint": {
"fqdn": "turnnlb-93f2de0c97c4316b.elb.ap-southeast-2.amazonaws.com.",
"destinationPort": "3478",
"sourcePort": "49985",
"transport": "udp",
"privateIp": "10.4.3.108"
},
"signallingEndpoint": {
"fqdn": ""
},
"usedDevices": [
{
"timestamp": "2023-06-01T04:59:55.041Z",
"deviceId": "default",
"groupId": "293e6a9871f0d56112233445566773d1e36f9e6ed9f4926c5a9318336ecfeec",
"kind": "audioinput",
"label": "Default - Elgato Wave:3 (0fd9:0070)"
},
{
"timestamp": "2023-06-01T04:59:55.041Z",
"deviceId": "default",
"groupId": "ccdd7abe9a3cd1122334455667762315f154461e744b2072bae72719239a",
"kind": "audiooutput",
"label": "Default - Internal Speakers (Built-in)"
}
]
},
"serviceAgent": {
"username": "andy",
"machine": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz",
"idlePercentage": {
"avg": 69.89
},
"utilisedPercentage": {
"min": 28.53,
"max": 31.84,
"avg": 30.11
}
},
"memory": {
"availableGb": 16,
"utilisedPercentage": {
"min": 92.27,
"max": 92.49,
"avg": 92.31
}
}
},
"network": {
"internetGatewayIp": "103.120.49.101",
"mediaIpAddress": "192.168.1.12",
"type": "wlan",
"isp": "Bcd Networks Pty Ltd",
"geolocation": {
"city": "Nutfield",
"region": "Victoria",
"country": "Australia"
}
},
"browser": {
"name": "Chrome",
"version": "113.0.5672.126"
},
"softphone": {
"softphoneUrl": "https://softphone.awsapps.com/connect/ccp-v2/softphone#ac7a6a89-43ff-4dce-8aa2-1e659475d24e",
"softphoneContextUrl": "https://softphone.awsapps.com/connect/ccp-v2/softphone#ac7a6a89-43ff-4dce-8aa2-1e659475d24e"
},
"interaction": {
"totalDurationSec": 14,
"onHoldDurationSec": 0,
"talkingDurationSec": 14,
"onMuteDurationSec": 0
},
"friendlyName": "Andy",
"agentId": "arn:aws:connect:ap-southeast-2:107413333282:instance/ac0eba8d-93d6-4f2f-a63d-aa576453c190/agent/1c591639-ce3d-4444-2222-6c9fa5ce8d93",
"autoAnswer": false
},
"billing": {
"durationRoundedMin": 1,
"agentDataReceived": true,
"cloudDataReceived": true,
"agentReadinessTest": false
},
"timestamp": "2023-06-01T05:00:11.871Z"
}
}
```
## Insights summary
The insights Operata established for a contact. Fires alongside `CallSummary` when at least one insight applies.
**`detail-type`:** `InsightsSummary`
**When it fires:** When Operata establishes one or more insights for a completed contact. Contacts with no insights produce no `InsightsSummary` event.
**Payload:**
```json theme={null}
{
"version": "0",
"id": "e063ddf9-ac05-08ee-138c-7105a7d3c04b",
"detail-type": "InsightsSummary",
"source": "aws.partner/operata.com/a28453f9-c9d3-4c48-a7cd-84d9e67ac297/customerEventBus",
"account": "083560837128",
"time": "2023-06-01T05:00:13Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"accountProperties": {
"operataGroupId": "a28453f9-c9d3-4c48-a7cd-84d9e67ac297"
},
"contact": {
"id": {
"current": "ac7a6a89-43ff-4dce-8aa2-1e659475d24e"
}
},
"insights": {
"count": 1,
"tags": [
{
"description": "High Packet Loss"
}
]
}
}
}
```
## Agent reported issue
An issue submitted by an agent through Tenor for human agents, including the surrounding device and browser context.
**`detail-type`:** `AgentReportedIssue`
**When it fires:** When an agent submits an issue through Tenor. Independent of contact lifecycle — agents can report issues with or without an active contact.
**Payload:**
```json theme={null}
{
"version": "0",
"id": "2549e62b-aaaa-bbbb-ccc-3bc2dfae7676",
"detail-type": "AgentReportedIssue",
"source": "aws.partner/operata.com/a28453f9-3333-4444-555d-84d9e67ac297/customerEventBus",
"account": "08350123456788",
"time": "2023-06-01T04:26:12Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"operataClientId": "a28453f9-c9d3-4c48-a7cd-84d9e67ac297",
"agent": "andy",
"state": "AgentReportedIssue",
"context": {
"callContactId": "",
"category": "Softphone would not work",
"cause": "Softphone would not work",
"message": "Unresponsive softphone",
"scenario": "",
"severity": "Terrible"
},
"browser": {
"name": "Chrome",
"version": "113.0.5672.126"
},
"system": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz",
"idlePercentage": 76.91,
"usedPercentage": 23.09
},
"memory": {
"total": 16,
"available": 1.33
}
},
"softphoneError": {
"type": "Softphone would not work",
"message": ""
},
"timestamp": "2023-06-01T04:25:07.495Z",
"id": "72f456d5ead0e9a2701fb03530ff3799"
}
}
```
## Headset summary
Per-contact headset telemetry, delivered when headset stats collection is enabled for the group.
**`detail-type`:** `HeadsetSummary`
**When it fires:** When the group has headset stats collection enabled and a contact ends. Contacts without an attached headset produce no `HeadsetSummary` event.
**Payload:**
```json theme={null}
{
"version": "0",
"id": "0ee84093-239d-b992-cb79-495a41952f30",
"detail-type": "HeadsetSummary",
"source": "aws.partner/operata.com/a28453f9-c9d3-4c48-a7cd-84d9e67ac297/customerEventBus",
"account": "0835123456787",
"time": "2023-06-01T04:49:23Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"accountProperties": {
"operataGroupId": "a28453f9-aaaa-bbbb-cccc-84d9e67ac297"
},
"contact": {
"id": {
"current": "8794983f-aaaa-bbbb-cccc-251045cfadd0",
"previous": "",
"next": ""
},
"interaction": {
"totalDurationSec": 0,
"onHoldDurationSec": 0,
"agentInteractionDurationSec": 0
},
"queueName": ""
},
"headset": {
"modelName": "Jabra PanaCast 20",
"firmwareVersion": "3.2.6",
"serialNumber": "A0000052B691",
"apiVersion": "3.0.0-beta.4",
"metrics": {
"speech": {
"crossTalkTotal": 0,
"crossTalkTotalPct": 0,
"rxSpeechTotal": 0,
"rxSpeechTotalPct": 0,
"silenceTotal": 55.7,
"silenceTotalPct": 100,
"totalSeconds": 55.7,
"txSpeechTotal": 0,
"txSpeechTotalPct": 0
},
"exposureDb": {
"min": 0,
"max": 0,
"avg": 0
},
"backgroundNoiseDb": {
"min": 0,
"max": 0,
"avg": 0
},
"misalignedBoomArmCount": 0,
"deviceMuteCount": 0,
"deviceVolumeAdjustCount": 0
}
}
}
}
```
## Heartbeat workflow
The result of a Heartbeat synthetic test, scored across each link in the call path. Operata delivers the payload as a JSON array — one entry per agent or routing profile in the test.
**When it fires:** When a Heartbeat test triggers its workflow. Configured per Heartbeat schedule; see the Heartbeat integration docs for cadence options.
**Payload:**
```json theme={null}
[
{
"agentId": "kanchan",
"agentType": "",
"axScore": 10,
"createdOn": "2022-03-31T05:40:57.967565Z",
"cxScore": 10,
"diallerCallId": "CA355bf611223344557f2b9f420d77a52841",
"groupId": "5bbbd17a-1111-2222-3333-c4674035f406",
"heartbeatId": "7ac7ba31-1111-2222-3333-6796c5d0f2e5",
"jobId": "1648705257967728403",
"networkScore": 10,
"receiverCallId": "5981c50a-1111-2222-3333-b65004a777f2",
"routingProfileId": "",
"status": "Call Not Accepted by Agent",
"toNumber": "",
"updatedOn": "2022-03-31T05:41:36.130184Z"
}
]
```
## CCP log files
CCP log lines streamed off the agent desktop as they appear.
**Scope:** `ERROR` and `WARN` level log lines, plus `INFO` for `ICE Connect Error` only.
**When it fires:** As log lines at those levels appear in the CCP. Operata does not buffer to contact boundaries — log events flow continuously while agents are signed in.
## Related
* [Webhooks overview](/docs/api-webhooks-overview) — delivery model, envelope, and example consumers.
* [Configure webhooks](/docs/api-webhooks-configure) — create the partner event source and route events to a target.
* [API changelog](/docs/api-changelog) — payload changes and new event types.
# Webhooks
Source: https://docs.operata.com/docs/api-webhooks-overview
Operata delivers enriched contact records, agent-reported issues, and Heartbeat results to your AWS account as Amazon EventBridge events — no HTTP endpoint required.
Operata's webhook mechanism is Amazon EventBridge (not an HTTP POST to a URL you host). After each contact ends — and on other triggers such as agent-reported issues and Heartbeat workflow results — Operata publishes a JSON event to a partner event source in your AWS account. You attach EventBridge rules and route events to any consumer you need.
## Endpoint
There is no HTTP webhook endpoint to register. Delivery flows from Operata to a partner event source dedicated to your Operata account:
```text theme={null}
aws.partner/operata.com//
```
You provide the AWS account and region; Operata creates the partner event source and emails you the source name to associate in the AWS console. See [Configure webhooks](/docs/api-webhooks-configure) for the one-time setup.
## Delivery model
EventBridge is Operata's only outbound event channel. Operata does not POST to an HTTPS URL you host. Reasons:
* AWS-native routing. EventBridge rules, targets, and pipes are configuration in your account — no consumer you have to keep online.
* At-least-once delivery from EventBridge to your targets, with the retry and dead-letter behavior you configure on the rule.
* No signing-key rotation, no IP allowlist, no consumer endpoint to monitor. The trust boundary is the partner event source association.
Once you associate the partner event source with an event bus in your account, every event Operata publishes for that account lands on that bus. Filter and fan out from there.
## Event types
| `detail-type` | When it fires | Catalog entry |
| - | - | - |
| `CallSummary` | After a contact completes, with the full enriched record. | [Call summary](/docs/api-webhooks-events#call-summary) |
| `InsightsSummary` | When Operata establishes one or more insights for a contact. | [Insights summary](/docs/api-webhooks-events#insights-summary) |
| `AgentReportedIssue` | When an agent reports an issue through Tenor for human agents. | [Agent reported issue](/docs/api-webhooks-events#agent-reported-issue) |
| `HeadsetSummary` | When headset stats collection is enabled and a contact ends. | [Headset summary](/docs/api-webhooks-events#headset-summary) |
| Heartbeat workflow | When a Heartbeat test triggers its workflow. | [Heartbeat workflow](/docs/api-webhooks-events#heartbeat-workflow) |
| CCP log lines | For CCP log lines at `ERROR` and `WARN`, plus `INFO` for `ICE Connect Error`. | [CCP log files](/docs/api-webhooks-events#ccp-log-files) |
Each entry in the catalog includes the synopsis, payload shape, and trigger condition.
## Delivery timing
Post-contact events arrive between 30 seconds and 5 minutes after the contact ends. The delay depends on the upstream enrichment pipeline: Contact Trace Record (CTR) availability, conversational analytics output, and signal aggregation. Build consumers that tolerate this window and key off `detail.contact.id.current` rather than wall-clock order.
## Envelope
Every event uses the standard EventBridge envelope. The Operata-specific payload lives under `detail`:
```json theme={null}
{
"version": "0",
"id": "530848f3-1111-2222-3333-b33ba70c19f0",
"detail-type": "CallSummary",
"source": "aws.partner/operata.com/a28453f9-abab-cdcd-efef-84d9e67ac297/acmeEventBus",
"account": "083560837128",
"time": "2026-05-18T05:00:13Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"accountProperties": { "operataGroupId": "a28453f9-abab-cdcd-efef-84d9e67ac297" },
"contact": { "id": { "current": "ac7a6a89-1111-2222-3333-1e659475d24e" } }
}
}
```
Filter on `detail-type` to route by event type, and on `source` to scope rules to a specific Operata account.
## Example consumers
* **Network-performance alerting.** Send `CallSummary` events to CloudWatch and use Anomaly Detection on packet loss, jitter, or MOS to surface trends across remote agents.
* **BI dashboards.** Stream `CallSummary` and `InsightsSummary` into Amazon QuickSight, Elasticsearch, or Splunk for contact-quality reporting.
* **Ticket creation.** Route `AgentReportedIssue` through Lambda into your ticketing system, attaching the full payload — browser, system, and softphone error — to the ticket.
## Versioning
Event payloads follow the same additive-change policy as the REST API: new optional fields ship without notice; breaking changes ship under a new `detail-type` or a new partner event source. See [Versioning](/docs/api-versioning) for the full policy and deprecation headers.
EventBridge events do not carry the REST API's `Deprecation` or `Sunset` headers. Watch the [API changelog](/docs/api-changelog) for event-shape changes.
## Related
* [Configure webhooks](/docs/api-webhooks-configure) — create the partner event source and associate it with an event bus.
* [Event catalog](/docs/api-webhooks-events) — payload shape and trigger for every event type.
* [Versioning](/docs/api-versioning) — how Operata signals additive and breaking changes.
* [API changelog](/docs/api-changelog) — announcements for new event types and payload changes.
# Tag the Cloud Collector AWS resources
Source: https://docs.operata.com/docs/aws-tagging
Apply AWS tags to the EventBridge Pipe, Lambda, and IAM resources the Operata CloudFormation stack creates.
Apply AWS tags to the Operata CloudFormation stack so every resource it manages
carries the keys you need for cost allocation, access control, or compliance
reporting.
## Before you start
* The Operata [CTR collection stack](/docs/ctr-installation) deployed
in your AWS account.
* IAM permission to update CloudFormation stacks
(`cloudformation:UpdateStack`) and tag the underlying resources.
* A tag policy or naming convention you want to apply (for example,
`Environment`, `CostCentre`, `OperataGroupId`).
Tags added at the stack level propagate to every resource the stack
manages — the Amazon EventBridge Pipe, the redactor Lambda, the API
destination, the Secrets Manager secret, and the IAM roles.
## Steps
### 1. Open the CloudFormation stack
In the AWS console, open **CloudFormation** and select the Operata
stack (typically named `OperataAWSIntegration-CTR-{instance}`). Click
**Update**.
### 2. Reuse the current template
Choose **Use existing template** and click **Next**. You're updating
metadata, not changing the template itself.
### 3. Skip the parameters screen
Leave the parameters unchanged. Click **Next**.
### 4. Add or edit tags
On the **Configure stack options** page, scroll to **Tags**. Add the
key/value pairs you want applied to every resource in the stack. For
example:
| Key | Example value |
| - | - |
| `Environment` | `prod` |
| `CostCentre` | `cx-platform` |
| `OperataGroupId` | `` |
| `ManagedBy` | `Operata-CloudCollector` |
Click **Next**, review, acknowledge the IAM acknowledgement if shown,
and click **Submit**.
## Verify
Open one of the resources the stack created — for example, the
EventBridge Pipe `operataEventsPipe-{instance}-amazonConnect` — and
check the **Tags** tab. Every key/value pair you set on the stack is
present.
## Related
* [Install CTR collection](/docs/ctr-installation) — the deploy that created the resources you just tagged.
* [IAM policies reference](/docs/iam-policies) — the roles each tag now applies to.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — if the stack update fails.
# Troubleshoot the AWS integration
Source: https://docs.operata.com/docs/aws-troubleshooting
Diagnose and fix missing Contact Trace Records, CloudFormation failures, KMS errors, and stale Operata secrets in the Cloud Collector integration.
The Cloud Collector on Amazon Connect fails in four common ways: CTR delivery gaps, CloudFormation failures, integration monitoring gaps, and stale Operata secrets. Start at the section that matches your symptom.
## Before you start
* Admin access to the AWS account hosting the [Cloud Collector](/docs/concepts-cloud-collector).
* The Operata Group ID for the integration.
* AWS CLI configured with permissions for CloudWatch, Secrets Manager, and Amazon EventBridge.
## Contact Trace Records are not appearing in Operata
### Wait at least five minutes
Contact Trace Records (CTRs) only emit when the contact is fully closed. Allow up to five minutes between the contact ending and the record appearing in Operata.
Check the basics:
* The [Agent Collector](/docs/collector-overview) is installed in the agent's browser.
* The CCP URL matches the Amazon Connect instance the stack was deployed against.
* The agent closed the contact (set status to `After Contact Work →
Available` or similar).
### Check the source Kinesis stream for KMS encryption
If the Kinesis CTR stream uses a customer-managed AWS Key Management Service (KMS) key, the Amazon EventBridge Pipe execution role needs decrypt permission. Follow [Grant KMS access to the EventBridge Pipe](/docs/kms-encryption).
### Check the EventBridge Pipe status
In the AWS console, open **EventBridge → Pipes** and find `operataEventsPipe-{instance}-amazonConnect`. The status should be `RUNNING`. Click into the pipe and check **Monitoring** for delivery failures. The most common failures are KMS access denied (see above), Lambda timeouts (raise the Lambda's memory or VPC routing), and API destination 4xx responses (regenerate the Operata API token).
### Check the redactor Lambda logs
In the AWS console, open **CloudWatch → Log groups** and find `/aws/lambda/CloudCollectorV3Stack-cloudcollectorv3redactor-…`. Look for `ERROR` or `Task timed out`. Forward the relevant log lines to [Operata Support](mailto:support@operata.com).
## CloudFormation deployment fails
### Verify the deploying principal's IAM permissions
The stack creates IAM roles, Secrets Manager secrets, Amazon EventBridge resources, and a Lambda. Confirm the deploying principal has the [administrator deployment policy](/docs/iam-policies#administrator-deployment-policy) attached, or equivalent permissions.
### Check for leftover resources from a prior install
If CloudFormation reports `ResourceAlreadyExists` on Secrets Manager or the EventBridge connection, an earlier install left state behind. Follow [Rotate or delete Operata secrets](#rotate-or-delete-operata-secrets) below, then re-run the stack.
### Send the failure to Operata Support
If the deploy still fails, take a screenshot of the **Events** tab of the failed CloudFormation stack and send it to [Operata Support](mailto:support@operata.com).
## Monitor the integration
The Amazon EventBridge Pipe and the redactor Lambda emit CloudTrail events and CloudWatch metrics. Operata recommends:
* **CloudWatch alarm on `Invocations` failing** for the redactor Lambda (above zero over five minutes).
* **CloudWatch alarm on EventBridge Pipe delivery failures** (above zero over five minutes).
* **CloudTrail trail** for all `events`, `pipes`, and `lambda` API calls in the integration region.
For details on Pipe-specific monitoring, see [Monitoring EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes-monitoring.html) in the AWS documentation.
## Rotate or delete Operata secrets
The Cloud Collector stores credentials in two places:
1. **`cloud-collector-v3/ctr/{Operata Group ID}/apiToken`** in Secrets Manager — the Operata API token the Lambda uses to authenticate.
2. **`events!connection/operataAPIgroup-{Operata Group ID}/…`** in Secrets Manager — created by EventBridge when the API destination was registered. Holds the API destination connection credentials.
Rotate or delete them when you rotate the Operata API token, decommission the integration, or hit a `ResourceAlreadyExists` error on redeploy.
**Deleting the API token secret immediately stops CTR delivery.**
The Lambda can't authenticate with Operata while the secret is gone. No CTRs reach the Operata API until you create a new secret with a valid token.
### Delete the Secrets Manager API token
```bash theme={null}
# List Operata secrets in this region
aws secretsmanager list-secrets \
--filters Key=name,Values=cloud-collector-v3
# Delete with the default seven-day recovery window
aws secretsmanager delete-secret \
--secret-id "cloud-collector-v3/ctr/$OPERATA_GROUP_ID/apiToken"
# Or delete immediately (no recovery window — use with care)
aws secretsmanager delete-secret \
--secret-id "cloud-collector-v3/ctr/$OPERATA_GROUP_ID/apiToken" \
--force-delete-without-recovery
```
### Delete the EventBridge connection secret
Deleting the EventBridge connection deletes the associated secret.
```bash theme={null}
aws events list-connections
aws events delete-connection \
--name "operataAPIgroup-$OPERATA_GROUP_ID"
```
### Console alternative
In the AWS console, open **Secrets Manager**, filter on `cloud-collector-v3`, select the secret, and choose **Actions → Delete**. To delete the EventBridge connection, open **EventBridge → API destinations → Connections** and delete `operataAPIgroup-{Group ID}`.
### Restore the integration after deletion
1. If you used the default recovery window, wait it out, or restore the secret in the console.
2. Update the CloudFormation stack — re-running it with a valid API token recreates both secrets.
3. Verify the pipe status returns to `RUNNING` and CTRs flow again under [Contact Trace Records are not appearing in Operata](#contact-trace-records-are-not-appearing-in-operata).
## Verify
Place a test contact through Amazon Connect. Within five minutes of contact end, the contact appears in **Get the Details** in the [Operata console](https://app.operata.io). If it doesn't, the [EventBridge Pipe monitoring panel](https://console.aws.amazon.com/events/home#/pipes) shows the failure reason.
## What next
* [Install CTR collection](/docs/ctr-installation) — re-run if you deleted the stack.
* [IAM policies reference](/docs/iam-policies) — the roles the stack creates and what each one is for.
* [Grant KMS access to the EventBridge Pipe](/docs/kms-encryption) — for CMK-encrypted streams.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the data path you're troubleshooting.
# Browser compatibility
Source: https://docs.operata.com/docs/browser-compatibility
Chrome and Edge versions certified for the Operata Agent Collector.
The Operata Agent Collector runs in Google Chrome and Microsoft Edge. Older versions may work but are not actively tested.
## Supported browsers
| Browser | Version |
| - | - |
| Google Chrome | Last three stable versions |
| Microsoft Edge | Last three stable versions |
## Check your browser version
Open Chrome and enter `chrome://version` in the address bar. The version appears next to **Google Chrome** at the top of the page.
Open Edge and enter `edge://version` in the address bar. The version appears next to **Microsoft Edge** at the top of the page.
## Related
* [Platform compatibility](/docs/compatibility-platforms) — certified CCaaS versions.
* [Headset compatibility](/docs/headset-compatibility) — supported Jabra devices.
* [Chrome extension](/docs/chrome-extension) — install the Collector for Chrome.
* [Edge extension](/docs/edge-extension) — install the Collector for Edge.
# Call signalling and handling events
Source: https://docs.operata.com/docs/call-events
Timestamps for every signalling and handling state change in an Amazon Connect Contact's lifecycle, emitted by the Agent Collector.
The `callEvents` object contains timestamps for every signalling and handling state change in one Amazon Connect Contact's lifecycle. The Agent Collector emits this object on every Contact.
## Schema
```json theme={null}
"callEvents": {
"initiated": "2026-05-18T10:14:13Z",
"incoming": "2026-05-18T10:14:14.427Z",
"connecting": "2026-05-18T10:14:14.428Z",
"accepted": "2026-05-18T10:14:20.025Z",
"connected": "2026-05-18T10:14:20.626Z",
"muted": "2026-05-18T10:14:44.975Z",
"unmuted": "2026-05-18T10:14:55.018Z",
"onHold": "2026-05-18T10:14:22.346Z",
"resumed": "2026-05-18T10:14:33.951Z",
"disconnected": "2026-05-18T10:15:49Z",
"ended": {
"party": "Agent",
"timestamp": "2026-05-18T10:15:05.182Z"
}
}
```
## Fields
All timestamps are ISO 8601 UTC strings.
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `initiated` | string (ISO 8601) | yes | The time the Contact connected to the Amazon Connect environment. | `2026-05-18T10:14:13Z` |
| `incoming` | string (ISO 8601) | no | The Contact is incoming and waiting for acceptance. | `2026-05-18T10:14:14.427Z` |
| `connecting` | string (ISO 8601) | no | The Contact is connecting. For voice Contacts, this is when the agent accepts the incoming call; for other Contact types, the Contact is accepted during the `INCOMING` state. | `2026-05-18T10:14:14.428Z` |
| `accepted` | string (ISO 8601) | no | The Contact has been accepted by the agent. | `2026-05-18T10:14:20.025Z` |
| `connected` | string (ISO 8601) | no | The Contact is connected. | `2026-05-18T10:14:20.626Z` |
| `muted` | string (ISO 8601) | no | The agent's local media is muted. | `2026-05-18T10:14:44.975Z` |
| `unmuted` | string (ISO 8601) | no | The agent's local media is unmuted. | `2026-05-18T10:14:55.018Z` |
| `onHold` | string (ISO 8601) | no | The Contact is connected but on hold. | `2026-05-18T10:14:22.346Z` |
| `resumed` | string (ISO 8601) | no | The Contact has been taken off hold. | `2026-05-18T10:14:33.951Z` |
| `disconnected` | string (ISO 8601) | no | The connection is no longer connected to the Contact. | `2026-05-18T10:15:49Z` |
| `ended.party` | string | no | Party that ended the Contact. One of `Agent`, `Customer`, `System`. | `Agent` |
| `ended.timestamp` | string (ISO 8601) | no | The time the Contact ended. | `2026-05-18T10:15:05.182Z` |
## Notes
* All fields except `initiated` are optional. They're absent when the corresponding state didn't occur — for example, `muted` and `unmuted` are absent on contacts where the agent never muted the microphone.
* `initiated` is always present and marks when the Contact connected to the Amazon Connect environment.
* `ended.party` distinguishes who terminated the Contact: `Agent`, `Customer`, or `System`.
# CCP agent states
Source: https://docs.operata.com/docs/ccp-agent-states
CCP (Contact Control Panel) agent state transitions Operata captures — one record per state change, emitted by the Agent Collector.
The `agentState` record captures each Contact Control Panel (CCP) state transition the Agent Collector detects — one record per change.
## Schema
```json theme={null}
{
"state": "MissedCallAgent",
"timestamp": "2026-05-18T10:14:20.626Z"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `state` | string | yes | The agent state reported by the CCP at the point of change. Standard values include `Available`, `Busy`, `AfterCallWork`, `Offline`, `MissedCallAgent`, `FailedConnectAgent`, `FailedConnectCustomer`, `Init`. Custom queue states configured in your Amazon Connect instance also appear here. | `MissedCallAgent` |
| `timestamp` | string (ISO 8601) | yes | When the state transition occurred. UTC. | `2026-05-18T10:14:20.626Z` |
For the full list of standard CCP agent states, see the [Amazon Connect Streams documentation](https://github.com/amazon-connect/amazon-connect-streams/blob/master/Documentation.md#agent-states-logging).
# Changelog
Source: https://docs.operata.com/docs/changelog
Product updates, release notes, and announcements for the Operata Agent Experience Collector, Cloud Integration, and platform features.
*New feature — Amazon Connect on Edge and Chrome browsers*
The [Agent Collector](/docs/chrome-extension) can now collect from the Amazon Connect chat CCP (`ccp-v2/chat`). This is off by default. Contact [Operata Support](mailto:support@operata.com) to enable it for your account.
*Update — Amazon Connect on Edge and Chrome browsers*
[CCP logs](/docs/api-ccp-logs) are now easier to tie back to the right interaction, even when an agent handles a voice call and chats at the same time:
* Each log entry now carries the agent ID and the Agent Collector version.
* Logs are attributed to the contact they belong to, including the initial contact ID for transferred contacts.
* Noisy, repetitive chat log lines are filtered out, while chat lifecycle and connection health entries are kept.
*Bug fix — Edge and Chrome browsers*
Fixes false [High CPU Utilization](/docs/insights-catalog#high-cpu-utilization) insights on call summaries. Samples with no CPU reading were previously scored as 100% CPU usage. They are now treated as missing data, so the insight only fires on real CPU load.
*Bug fix — Genesys on Edge and Chrome browsers*
Fixes two issues with softphone logs collected from [Genesys Cloud](/docs/resources-data-collection-genesys):
* **Log levels:** Each entry now keeps its original Genesys level (for example `ERROR` or `WARN`). Entries with an unrecognized level were previously dropped. They are now recorded as `INFO`.
* **Timestamps:** Each entry now shows the time it was logged on the agent's machine. Previously, every entry in an uploaded batch shared the same collection time, which hid the real order of events.
*Bug fix — Edge and Chrome browsers*
Fixes [Agent Readiness Test](/docs/help/agent-readiness-test) results intermittently showing as **No test** when the softphone was open in more than one browser tab. Clicking **Run Test** could start a test in every open tab, which reserved a second test number and stopped the result from being recorded. The test now runs only in the tab where the agent clicked **Run Test**, and repeat requests are ignored while a test is in progress.
*Bug fix — Edge and Chrome browsers*
Extends [Island Browser](https://www.island.io/) detection in the [Agent Collector](/docs/chrome-extension) to cover Island builds that present as stock Chrome in both the user agent string and client-hints brands. Detection now checks Island's self-identification API first, then falls back to the existing user agent and client-hints checks. These installs are now correctly reported as Island instead of Chrome, so they are no longer evaluated by the Legacy Browser insight.
*Bug fix — Edge and Chrome browsers*
Improves [Island Browser](https://www.island.io/) detection in the [Agent Collector](/docs/chrome-extension). Some Island builds ship a stock Chrome user agent and only identify themselves through client-hints brands. Those agents were still reported as Chrome and evaluated by the Legacy Browser insight. Detection now checks client-hints brands in addition to the user agent string, so these installs are correctly reported as Island.
*Update — Edge and Chrome browsers*
The description field on the [agent issue report](/docs/agent-feedback) form is now capped at 250 characters. The browser stops typing and paste at the limit, and any longer draft saved before this change is truncated when restored. This keeps reports concise and reduces the chance of PII being included.
*Bug fix — Edge and Chrome browsers*
The [Agent Collector](/docs/chrome-extension) now recognizes the [Island Browser](https://www.island.io/) and reports it as `Island` instead of Chrome. Island installs were previously identified as Chrome because Island's user agent appends its name to a standard Chrome string, which caused Island agents to be evaluated by the Legacy Browser insight as if they were running Chrome.
*Bug fix — Amazon Connect on Edge and Chrome browsers*
Restores the media strategy (for example `StandardStrategy` or `CitrixVDIStrategy`) on [call summaries](/docs/webrtc-session) for agents on Amazon Connect's persistent agent connection path (RtcPeerConnectionManagerV2). The field was silently dropped for V2 sessions and returns to the same source of truth used for V1.
*New feature — Edge and Chrome browsers*
The [Agent Collector](/docs/chrome-extension) now respects a per-agent allow-list. When an agent signs in, Operata checks whether they are enabled for your account:
* Agents on the allow-list are collected as usual and see [Tenor for human agents](/docs/help/agent-copilot).
* Agents outside the allow-list have no telemetry collected or sent, and the Tenor widget is not shown.
The check runs at every agent login, so shared machines and agent switching are handled correctly. Contact [Operata Support](mailto:support@operata.com) to configure an allow-list for your account.
*Bug fix — Edge and Chrome browsers*
Fixes a memory leak in the [Agent Collector browser extension](/docs/chrome-extension). The extension left an event listener attached each time it collected data from the softphone page, so browser memory usage grew gradually over long sessions. Listeners are now removed after each collection.
*Update — Edge and Chrome browsers*
The **Resolve Issue** button on [alert cards](/docs/help/agent-copilot) is renamed **Acknowledge Alert** to better reflect what the action does.
*Bug fix — Edge and Chrome browsers*
Tooltips in [Tenor for human agents](/docs/help/agent-copilot) now display above the panel instead of behind it. This affects the alert card actions and the panel's close and alignment controls.
*Bug fix — Edge and Chrome browsers*
Fixes stale [network data](/docs/machine-browser-network) on CCPs using persistent agent connections (RtcPeerConnectionManagerV2). Network statistics now refresh correctly across consecutive calls instead of carrying values over from a previous contact.
*Improved microphone reporting — Edge and Chrome browsers*
The in-use microphone is now read from the live call audio track. In Salesforce Omni and other non-Amazon Connect environments, Operata previously reported the browser default device even when call audio ran through a headset. Mid-call device switches are picked up too.
*Bug fix — Edge and Chrome browsers*
Fixes the agent test call on CCPs using persistent agent connections (RtcPeerConnectionManagerV2). The test call now plays audio instead of failing and needing to be ended manually.
*Bug fix — Edge and Chrome browsers*
Fixes memory utilization in the call summary, which climbed toward 100% over the course of a call.
*Improved Genesys support — Edge and Chrome browsers*
Improvements to Genesys environment data collection:
* Statistics collection reconnects when Genesys replaces the media connection, so data keeps flowing through a full shift.
* Added detection and telemetry for multiple concurrent media connections.
*Version Alignment — Edge and Chrome browsers*
Version to bring the Chrome and Edge version numbers into alignment. No functional change.
*Minor Enhancement — Edge and Chrome browsers*
Further efficiency improvements to CCP log collection.
*Minor Enhancement — Edge and Chrome browsers*
Efficiency improvements to CCP log collection.
*Minor Enhancement — Edge and Chrome browsers*
Improvements to Agent Copilot scaling within Salesforce environments.
*Minor Enhancement — Edge and Chrome browsers*
Improvements to Genesys environment data collection:
* Support for Genesys media helper.
* Support for Genesys call transfers.
*Minor Enhancement — Edge and Chrome browsers*
Improvements to Genesys environment data collection.
*Improved Genesys support — Edge and Chrome browsers*
Update to improve Genesys environment data collection.
*Minor Enhancement — Edge and Chrome browsers*
Update to support RtcPeerConnectionManagerV2 persistent agent connection within HDX environments.
*Minor Enhancement — Edge and Chrome browsers*
Update to support RtcPeerConnectionManagerV2 persistent agent connection.
*Minor Enhancement — Edge and Chrome browsers*
Updated to support RtcPeerConnectionManagerV2.
*Minor Enhancement — Edge and Chrome browsers*
Agent Copilot 'Agent Reported Issue' UI scaling issue resolved for Amazon Connect/Salesforce environments.
*Minor Enhancements — Edge and Chrome browsers*
* Krisp and Sanas support — enable collection of the Headset device using Krisp/Sanas as well as enabled features such as noise cancellation and accent conversion.
* Allow initialization of the extension when `window.pwt` is undefined.
*Minor Enhancements — Edge and Chrome browsers*
Amazon Connect — Improvements to Agent Auto answer data collection.
*Minor Enhancements — Edge and Chrome browsers*
* Improvements to MissedCallAgent detection.
* Support for Headset identification when using the Krisp application.
* Improved data collection for Genesys environments (queues and missed calls).
*Minor Enhancements — Edge and Chrome browsers*
* Enable Log collection in Genesys environments.
*Minor Bug fixes — Edge and Chrome browsers*
* Resolved issue with Agent Audio for Heartbeat tests.
* Ignore `microphone_not_shared` notification if mic is available.
* Fix invalid URI encoding for agent username in agent config fetch.
*Updates for WCAG compliance — Edge and Chrome browsers*
* Improved UI for WCAG 2.2 compliance.
*Transferred calls improved data collections — Edge and Chrome browsers*
* Collect initial contact id in the summary v2 payload to better understand call transfers.
*Updates for WCAG compliance — Edge and Chrome browsers*
* Improved UI for WCAG 2.2 compliance.
*Updates for WCAG compliance — Edge and Chrome browsers*
* Improved UI for WCAG 2.2 compliance.
*Updates to Headset Change data capture — Edge and Chrome browsers*
* Improvement to headset-change tracking during calls.
*Remove audio setting capability from within Agent Copilot — Edge and Chrome browsers*
* The capability to set the Mic and Speaker settings from within Agent Copilot has been removed to provide a more consistent experience to agents — changes only made using the native softphone or device settings.
* The AX Copilot alert has also been updated to remove the 'Change Device settings' button.
*Updates to locally calculated insights — Edge and Chrome browsers*
* Updates and additions to locally calculated insights.
*Auto load extension and resolve Agent Reported issue guidance text — Edge and Chrome browsers*
* Auto load Operata extension when added to Chrome and Edge (does not require a browser refresh).
* UI configured agent reported issue guidance now appears in Agent Copilot.
*Auto load extension — Edge browsers*
* Auto load Operata extension when added to Edge (does not require a browser refresh).
*Agent Copilot UI update — Chrome and Edge browsers*
* Agent Copilot popup placement and CSS loading inside the shadow root.
*Agent Copilot ART update — Chrome and Edge browsers*
* Updated WebSocket connection to no longer require the Heartbeat tag and added telemetry logging for WebSocket connection type.
* Updated the Agent Readiness test to use of pool number with the ART Key.
*Agent Copilot ART update — Chrome and Edge browsers*
* Update the approach to tagging Agent Readiness Tests to improve the accuracy of the results dashboard and billing.
*Agent Copilot ART update — Chrome and Edge browsers*
* Update the approach to creating Agent Readiness Tests to improve the accuracy of the results seen in the ART dashboard.
*Agent Copilot UI refinement — Chrome and Edge browsers*
* Default to "Report Issue" tab when Agent Copilot is opened and no alerts or actions are present.
* Fixed an issue where Alert and Action toasts were not dismissing after they expire.
*Persistent Agent Connection support — Chrome and Edge browsers*
* Support for agents using Amazon Connect Persistent Agent Connection.
*Additional telemetry — Chrome and Edge browsers*
* Add telemetry logging to detect customers who have enabled CCP agent persistent connections.
*UI updates for the new Agent Messenger widget (Agent Copilot) — Chrome and Edge browsers*
* A number of UI updates to progress release of the new Agent Messenger widget, branded Agent Copilot.
*UI updates for the new Agent Messenger widget (Agent Copilot) — Chrome and Edge browsers*
* A number of UI updates to progress release of the new Agent Messenger widget, branded Agent Copilot.
*Bug fixes and further UI updates for the new Agent Messenger widget (AX Copilot) — Chrome and Edge browsers*
* A number of UI updates to progress release of the new Agent Messenger widget, branded AX Copilot.
* Fix for Agent Copilot to dismiss any Agent Readiness toast alerts if the readiness call is in progress.
*UI updates for the new Agent Messenger widget (AX Copilot) — Chrome and Edge browsers*
* A number of UI updates to progress release of the new Agent Messenger widget, branded AX Copilot.
*UI updates for the new Agent Messenger widget (AX Copilot) — Chrome and Edge browsers*
* A number of UI updates to progress release of the new Agent Messenger widget, branded AX Copilot.
* Small update to the Agent Readiness Test logic to ensure agent scores and audio performance measures are captured.
*For Amazon Connect agents — Ignore network performance statistics when callers are placed on Hold — Chrome and Edge browsers*
* Agent Messenger has been updated to ignore network performance measures when the agent has placed the caller on hold, as in this state the 'you are on hold' announcement source introduces network latency. The WebRTC softphone is not actively transmitting or receiving customer audio at this time, hence any MOS collected at this point would not reflect the actual customer experience, however this does impact the average and worst case (min) network performance scores for calls.
*Agent messenger v2 capability — Chrome and Edge browsers*
* Enables updated Agent Messenger (v2) user interface.
* Enables selected agent deployment of agent messenger.
*Enhancements to Agent Test sequence and Messenger 2.0 — Chrome and Edge browsers*
* Agent Test sequence updated to ensure Agent response and call quality metrics are passed to the Dashboard.
* Update to the messenger widget in preparation for Messenger 2.0.
*Support for Amazon Connect screen recording telemetry — Chrome and Edge browsers*
* Event details for Amazon Connect Screen Recording capability now captured as telemetry data.
*Resolved Heartbeat reference Audio file play — Chrome and Edge browsers*
* CCP Mute function change prevented the Heartbeat Agent reference audio file from being played, this version resolves the issue.
*Improved Agent Readiness Test — Chrome and Edge browsers*
* Reduce the time taken to complete the Agent Readiness Test process.
*Improved support for Nice CXone — Chrome and Edge browsers*
* Update to collect Nice CXone Agent ID.
*Support for new MS Edge Browser API — Chrome and Edge browsers*
* Update to ensure full support against the new MS Edge API.
*Agent Readiness Test and Data Teams*
Operata have launched an agent readiness feature and Data Teams (role based access to specific data) as part of the Kora release — [details here](https://operata.com/blog/introducing-the-kora-release-from-operata-advancing-agent-assurance-and-data-teams).
*Enable Adagio components for Agent Collector v2 — Chrome and Edge browsers*
* Update to enable new graphical components to support the net iteration of the Agent Collector widget.
*HDX Media performance data collection issue — Chrome and Edge browsers*
* Resolves CCP media data collection where environments use proprietary connect-rtc and open source version.
*Salesforce UI issue resolution — Chrome and Edge browsers*
* Cosmetic UI error issue resolved for Amazon Connect with Salesforce users.
*Agent Start of Day — Chrome and Edge browsers*
* Support for the new Agent Start of Day service — see Operata for details.
*HDX improvements — Chrome and Edge browsers*
* Support data collection in hybrid environments with agents running both non-HDX and HDX environments.
*HDX and Nice CXOne improvements — Chrome and Edge browsers*
* Improvements to HDX data collection.
* Enables Nice CXone media data collection when using Azure VDI.
*Improved support for HDX and support for non-standard Approved Origin URL's — Chrome and Edge browsers*
* Capture HDX performance metrics when configured as a Custom Softphone in Operata Group configuration.
* Ignore trailing slash when determining if current frame url is a valid.
*Tango support — Chrome and Edge browsers*
* Enhancement to support customers using the Tango CRM platform.
*Stability and telemetry updates — Chrome and Edge browsers*
* General improvements to load tolerance in poor networks and enhanced telemetry.
*Tagging for VDI, HDX and standard WebRTC environments — Chrome and Edge browsers*
* Enhancement to capture VDI, CitrixHDX and Standard WebRTC media strategies for every call.
*Improve Agent environment data collection — Chrome and Edge browsers*
* Agent Collector captures the underlying operating system (and version) that agents are using to assist in troubleshooting any performance issues.
*Amazon Workspace UI fix — Chrome and Edge browsers*
* UI fixes for Amazon Connect Agent Workspace environments.
*Improve Agent Start of Day testing — Chrome and Edge browsers*
* Improvements to the Agent Start of day testing features.
*Clamp Agent messenger position — Chrome and Edge browsers*
* Resolve issues where it was possible to move Agent Messenger to a position that is not visible by the user.
*Agent Start of Day testing support — Chrome and Edge browsers*
* Initial Beta support for the agent start of day process.
*Citrix HDX support — Chrome and Edge browsers*
* Initial Beta support for Citrix HDX softphone media.
*Data capture enhancements — Chrome and Edge browsers*
* Remove unneeded fields for missed call v2 payloads.
*Improved silent call tagging — Chrome and Edge browsers*
* Improvements to Call On Silence detection. Now triggers when 95% of all samples are silent, (\<300 in audio energy, over a 30s duration). This helps reduce false-positive detections of silence on the customer and agent side.
*Collection enhancements — Chrome and Edge browsers*
* Improved inbound and outbound MOS collection.
* Bug fix for VPN Agent IP data collection.
*Improved load timing — Chrome and Edge browsers*
* Change to extend the wait for JS to finish loading before attempting to initialize.
*Improved data collection and insights — Chrome and Edge browsers*
* Call ended on silence insight tagging added.
*Client collector improvements — Chrome and Edge browsers*
* Improve softphone logging capture.
*Client collector improvements — Chrome and Edge browsers*
* Enhancement to reduce excessive log messages from the agent softphone.
* Add telemetry logging to the extension.
*Audio exposure bug fix improved Agent Collector configuration poor network tolerance — Chrome and Edge browsers*
* Updated the Jabra alert — Audio Exposure default threshold raised from 75dB to 85dB.
* Resolved bug preventing the Audio exposure notification to be switched off.
* Agent Collector configuration Cache feature enabled to be more tolerant of network issues on first launch.
*Bug fix for excessive softphone logs — Chrome and Edge browsers*
* Resolved an issue with the Agent Collector generating excessive softphone logs, which impacted CCP log collection for Amazon CCP users.
*Improved Agent Messenger UI experience — Chrome browsers only*
* Improved the behavior of common Agent alerts to time-out automatically after a short period.
* Remove logging for "agent clicked end contact" button.
*Improved collection accuracy — Chrome browsers only*
* Improved the accuracy of Agent and Customer disconnection event collection.
*Telemetry updates — Chrome browsers only*
* Remove log message as creates too much noise.
* Update manifest.json.
* Add optional telemetry to agent status.
*All Agent Notification toasts to be dismissible — Chrome and Edge browsers*
* Bug resolved that prevented some of the Agent Notification toasts from being dismissible.
*Reduce Agent Collector startup time*
* Enhancement to the Agent Collector to improve the startup time to reduce the incidence of missed calls at the start of an agent session.
*Improved Telemetry Data*
* Add telemetry data to v2 summary payload to improve data collection identification.
*Telemetry added to aid coverage reporting and analysis*
* Adds telemetry to help quantify coverage reporting and analysis, specifically logging time extension was loaded, time extension is ready to start collecting calls, and number of calls captured within a single session. This data is not customer facing, but will aid in the creation of analytics that will be going forward.
*Support for secondary Operata URL to capture Agent WAN IP and ISP when using VPN*
* A new agent IP lookup service has been integrated with the chrome collector, and will do a IP lookup based on this value (if it exists).
*Updated text for AX Copilot alerts*
* The toast (pop out messages), hover text and history text will now all be consistent with the agreed customer text for AX Copilot notifications.
*Added support for Nice MAX Agent embedded into SalesForce*
* Data collection enabled for the Nice MAX Agent when embedded into a SalesForce environment.
*Added support for Nice CXone Agent*
* Data collection enabled for the Nice CXone Agent client.
*Resolved capitalization issue with Nice CXOne within Salesforce*
* capitalization of states when using the Nice CXone agent within a Salesforce environment is inconsistent, this bug fix normalizes the capitalization into Operata.
*Revert call disconnect party changes from v1.6.24*
* Revert call disconnect party changes from v1.6.24.
*Determining the hang up party*
* Determining the hang up party.
* Updated the manifest version.
*Input/output device enhancements*
* Add Settings option to the chrome collector, allowing agents to swap input/output device.
*Harmony release agent capability updates*
* UI improvements for Harmony.
*Harmony release agent capability updates*
* Change threshold for Call Ended On Hold/Mute from 180 seconds to 30 seconds.
* "End Call" support for Agent Alert toasts (Harmony).
* UI improvements and bug fixes for Agent Alert toasts (Harmony).
*Resolve Heartbeat UI issue*
* Ensure the Agent Messenger widget notifies agents when there is a Heartbeat test running.
*Update to support new Harmony features*
* A number of internal changes to support the new Harmony feature set — released in November 23.
*Update Heartbeat to support latest browser API's*
* Correctly handle changes to the underlying audio streams when echoing and playing back the file recording for Heartbeat.
*Support for AWS account migration*
* Initial support for push messages from backend services for agent alerting.
* Cloudfront invalidation cache pipeline fix.
*Support for AWS account migration*
* Internal changed to support Operata AWS account migration.
*Call Ended On Silence insight*
* Add calculator to detect and tag call records where the Call Ended On Silence.
*Call ended on Hold/Mute insights*
* Call ended on Hold/Mute data collection and insights added.
*'People experience' insights for CX Observability.*
Operata for Amazon Connect Contact Lens — New dashboards ("playbooks") provided out of the box for Contact Lens data derived from quality management, sentiment analysis, and conversational analytics.
Connectors Architecture — Foundational support for an expanding list of business data integrations with Contact Center as a Service (CCaaS), Workforce Experience Management (WEM), Quality Management (QM), Voice of the Customer (VoC), and Customer Experience (CX) solutions.
Expanded Event Streams for 3rd-Party Tooling — Expanded Operata data sets are now available with rich eventing via Amazon EventBridge to 3rd-party analytical and operational tools, and systems of record.
*Multiple softphone tagging*
* Add calculator to detect and tag call records where multiple softphones are detected.
*Improved network performance measurement*
* Add calculator to detect zero packets.
* Fallback to legacy stats collection for heartbeat.
*Resolved MOS calculation error*
* Fixed an issue with Agent MOS calculation which reported an incorrect MOS score at high packet loss (>35%).
* MOS calculation is now more reliable at when agents are experience poor network connections.
*Support for Amazon Connect Agent Workspace*
* Agent Messenger updated to support data collection and agent reporting within the AWS Agent Workspace platform.
*Agent Collector (Chrome and Edge) improvements*
* Updated the WebRTC collection method within Agent Messenger to align to standards across all browsers. This improves the compatibility and reliability of WebRTC and network metrics within Agent Messenger.
* Modern browsers manage memory more efficiently, and low-memory alerts can be triggered as a false positive with regards to CX and the agent experience. To this end memory alerts have been removed from agent messenger and the configuration UI.
*General improvements to the data collected by the Operata Chrome and Edge Agent Collector*
* Supports the latest getStats API to monitor the correct candidate pair.
*Agent Insights and Customer Insights playbooks*
Operata's Forte release introduces agent and customer insight playbooks that provide IT and operational teams with unique views into key metrics impacting customer experience and cost.
Correlating technical, agent, and customer insights across multiple calls and operational lenses provide a unified view of interactions, highlighting opportunities to enhance operational efficiency and boost customer satisfaction.
*General improvements to the data collected by the Operata Chrome and Edge Agent Collector*
* A new field has been added which covers the top level URL in which the softphone is loaded, this will allow identification of issues that are common to a specific customer softphone.
* Improvements to the data collected in Nice CXone environments.
* Standardisation of the url used to send Heartbeat, Agent side audio recordings to Operata for audio degradation scoring.
* Genesys Cloud CX collection improvements including missed calls and agent status.
*Genesys softphone enhancements*
* Fixed a Genesys softphone issue where the party who ended call was not reported correctly in Operata.
* Fixed an issue that prevented the Agent Collector from capturing Hold and Mute events for inbound calls on Genesys softphone's.
*Heartbeat Agent Audio fix*
* Resolved an issue with Agent audio not being scored as part as a Heartbeat test.
*General improvements to the Agent Collector Chrome extension*
* Hold and mute events captured with the Agent Collector will now report an associated resume and unmute event, with each hold having an associated resume and each mute having an associated unmute.
* Fixed an issue with the Agent Collector incorrectly labelling Outbound calls as Inbound calls when using a NiCE softphone.
* Fixed an issue that prevented the Agent Collector from capturing Hold and Mute events for all calls on NiCE soft phones.
* Fixed an issue with the Agent Collector where agent stats collection could fail intermittently for Genesys and AWS customers.
* Agent Collector can now capture additional data points including: granular hold / mute events, agent queue, and customer caller id. These data points are currently available for customers on AWS, with Genesys and NiCE to be supported in a future release.
* Convert Chrome Collector to Typescript.
*Agent Messenger \<> Zendesk UI improvements*
* Resolved character entry issue within Agent Issue Report comments field.
* Resolved the Agent Messenger scaling issue, when within a Zendesk CCP iFrame.
*Improved data capture*
The following fields are now captured in the `{{Summary}}` payload:
* `CustomerEndpoint`
Note: This capture can be toggled off/on by the Customer within Settings/Configs/Softphone.
*Improved data capture*
The following fields are now captured in the `{{Summary}}` payload:
* `{{serviceAgent.friendlyName}}`
* `{{contact.id.previous}}`
* `{{contact.queueName}}`
* `{{contact.events.enqueued}}`
*Improved Operata Headset controls*
Provide the ability to toggle Operata Jabra headset controls.
* Fixed an issue where Jabra Call controls interfered with custom softphone call controls.
*Improvements to EventStream data sent by Operata*
Additional data now added to EventStream from Operata.
* Headset data added to the EventBridge summary stream.
* Heartbeat Assurance test results added to the EventBridge summary stream.
*Call summary device data fix*
Minor bug resolution.
* Fixed a bug where "call summaries would occasionally include devices used in the previous call."
*WARN level log Filter*
To reduce the volume of unused WARN level logs from CCP softphone's sent to Operata, the Chrome Extension now filters out the following seven WARN log messages:
* `contact%`
* `Invalid country calling code`
* `ADVANCED_LOG`
* `WARN`
* `The user has requested to not receive notifications.`
* `Failed to get agent data.`
* `Failed to fetch agent configuration data.`
*Capability Improvements*
The latest version of the Operata Agent Collector brings with it a number of feature updates and improvements.
* **New feature** — A customer configurable note below the Agent Issue Report comment field, to provide guidance to agents on any content restrictions, for example 'do not enter customer details'.
* Improved detection and configuration to better place the Operata widget.
* Added the latest phases of support for the Genesys Cloud softphone and Nice CXone Max softphone.
*Chrome Extension improvements*
The latest version of the Operata Agent Collector brings with it a number of feature updates and improvements.
* Improved agent alerting with icons that highlight whether Network, PC performance or headset sharing issues have been detected.
* Embedded Jabra Headset call controls. Install the Jabra Integration chrome extension; actions on the headset are then captured in the softphone state.
* Enabled enhanced call analytics for the new Jabra Engage II range of headsets, with a new dedicated Playbook.
*Chrome collector improvements*
Minor bug issue resolution for Multiple agent events.
* Resolves an issue where multiple Agent Status records would be recorded when agents would be using multiple softphone's in a single session.
*Operata created message resolved*
Amazon Connect ERROR 'contact::destroyed created by the Operata Collector resolved.
* Non service impacting CCP ERROR 'contact::destroyed caused by Operata Chrome extension has been resolved.
*Amazon CCP soft-phone "Desk-phone" mode detection*
Tag calls answered by agents using Desk phone mode.
* Desk-phone mode support — Agents taking calls with their Amazon CCP soft-phone set in "Desk-phone" are now tagged in Operata as "Deskphone Mode".
*Restore CPU and Memory per second data collection*
* Resolved the issue with CPU and memory failing to report min, max and average values correctly.
*"Narrow mode" to support NiCE default soft-phone width*
* Minor user interface improvements to Operata Messenger to support narrow soft-phone screens.
*Chrome minor patch version now visible*
* Agent Messenger now correctly reports the MINOR.BUILD.PATCH version in response to Chrome's latest update that has reduced User Agent reporting.
*Multiple Agent Messenger widgets visible*
* Fixed a minor issue that displays multiple Operata Messenger panels for custom implementations that include multiple inactive softphone panels.
*Agent Messenger UI improvements*
* Resolved an issue where the Operata Agent Messenger widget would stretch too wide on larger soft-phone windows.
*Agent Messenger UI improvements*
* Fixed an issue where the Operata Messenger would reset it's position on the screen whenever the browser window was resized.
*Improved Canvas performance and Security*
* Improved security and performance of the Canvas platform within the dashboard list views.
*API data improvements*
* Added a new endpoint for retrieving call summaries in the v2 structure.
* Moved `{{contact}}` and `{{serviceAgent}}` fields higher for visibility.
* Changed from using a criteria to GET Path Attributes.
*Update Heartbeat call failed call workflow status*
* Watchdog statuses have been condensed from "Busy", "No Answer" and "Failed" into a single value — "Call Failed".
*Heartbeat triggers for "Call Failed" to be updated to support new SIP data*
* Improved call logging data for Heartbeat tests. The Heartbeat details page now includes the reason for the telephony issue within a new section of the report, including any SIP-based errors.
*Heartbeat triggers for "Agent Error" and "Call not accepted by Agent" to be trigger an event on*
* Heartbeat now supports the ability to event and trigger alerts based on when agents are in error. This includes the following Heartbeat conditions:
* Agent Error, and
* Call Not Accepted by Agent.
*Browser type identification*
* Agent Messenger can now report more details on the agent web browser environment. This includes distinguishing between Edge and Chrome. Previously the Edge browser was reported as Chrome given it is forked from the same source code.
*Heartbeat test improvements*
* The Heartbeat details page now includes the reason for the telephony issue within a new section of the report, including any SIP-based errors.
* Watchdog statuses have been condensed from "Busy", "No Answer" and "Failed" into a single value — "Call Failed".
*Heartbeat triggers for "Poor Call Quality"*
* Heartbeat now supports the ability to event and trigger alerts based on successful Heartbeat calls that are of poor call quality. This includes the following call quality conditions:
* Poor Call quality outbound from Agent
* Poor Call quality inbound to Agent
* Poor Inbound call quality
* Poor Outbound call quality
*Orchestrator Privacy Controls enhancement*
* Contact Trace Records (CTR) collected by Operata may contain sensitive data or personally identifiable information (PII). In some circumstances, customers may be required to redact certain sensitive data before it is sent to Operata.
* A new content redaction configuration managed via the API supports either whitelisting or blacklisting data, allowing customers to ensure no sensitive PII data is captured by Operata in call logs.
*Heartbeat improvement*
* Heartbeat tests with Human Agents now support the restoring of their previous status after a Heartbeat test is run. This allows you to run Heartbeat tests with any agent in any status including offline, or a custom state.
*SSO-compatible sign-in page*
* Single sign-on to support enterprise identity providers, which has been a much requested feature.
*Single sign-on (SSO)*
* Access to the Operata platform now supports Single Sign On (SSO), with support for enterprise identity providers such as Okta.
*Audio Device capture*
* Audio input and output device types are now captured in the summary report.
* An agent status 'InputDeviceChanged' will also be sent every time a change occurs.
*TimeZone*
* Operata Canvas charts now display timestamps in the browser's timezone.
* **Orchestrator CloudFormation enhancements** — Improve the configuration template to enable customer self deployment of the Orchestrator element.
* **Operata BI tool** — Phase 4 deployment (data ingestion) of the BI tool to be launched in late 2021 under the Diva release.
* **Workflow trigger history** — Add all workflow triggers to the event history tab.
* **Operata BI tool** — Phase 3 deployment (data replication) of the BI tool to be launched in late 2021 under the Diva release.
* **Speech enabled Simulate** — Enable speech prompt answer call treatments from the Operata Assurance performance testing application.
* **API v2** — Migration of the billing API to API v2 providing far more concise details.
* **Operata BI tool** — Phase 2 deployment (user access rights) of the BI tool to be launched in late 2021 under the Diva release.
* **Workflow trigger improvements** — enhanced trigger events to more accurately notify when thresholds have been reached.
* **Agent issue notification improvements** — Improve the Operata tolerance of capturing issues where there are agent network problems (causing the issues).
* **Operata BI tool** — Initial deployment of the new Operata BI tool to be launched in late 2021 under the Diva release.
* **API v2** — Migration of the call details API to API v2 providing far more concise, insightful information.
* **Heartbeat feature toggle** — Enable customer feature toggling for the Operata Heartbeat service.
* **mTLS support** — Enable data ingress support for Mutual TLS.
* **Heartbeat UI and insights improvements** — Improvements to both the UI and insights provided from the Heartbeat results.
* **API v2** — Release of a consolidated summary endpoint that will replace the current API content.
* **Allow multiple groups to whitelist the same origin** — Support for third party softphone services such as Local Measure and Salesforce where the Agent access url is common across all customers.
* **Dashboard updates** — Updated version of the Operata Dashboard released, general performance enhancements.
* **Media Path** — Detect the active media candidate pair and provide the media interface IP address in the UI/API.
* **User inactivity Logout** — Force logout if user is inactive for 60 minutes.
* **Minor UI bug issues** — General improvements to the UI focussing on user provisioning.
* **Agent Experience widget** — Usability improvements. The UI will always pop to Agent Notification when flashing and to the Agent Issue reporting if not.
* **API v2** — First phase of improving the data model exposed via the API and used by the dashboards.
* **Teammate login updates and improvements** — General improvements to the the workflow and pages presented to new Teammates as they move though the email validation and set-password process.
* **Dashboards** — Updates to the AGENT STATUS dashboard with new filters and three new tables to show agents with the most frequent MisssedCallAgent events, the most common Softphone Errors, as well as the agents with most of them.
* **Agent Experience widget** — new Config options for greater flexibility in where the Operata Extension for Chrome inserts the Agent Experience widget.
* **Deeplinks for Dashboards** — the URL for the dashboard views, now includes the specific group and filters — great for sharing Operata content.
* **Dashboards** — fix applied to the dropdown filters and callContactId filter added to the FIND OUT WHERE dashboard.
* **EventBridge** — backend changes to support AWS EventBridge integration, production release later in the quarter.
* **Heartbeat** — numerous bug fixes and improvements identified from early customer deployments.
* **Cloud Collector** — updated to address a capacity issue encountered on larger Connect deployments, all current users will be contacted to progress an update to this new version (CloudFormation template updated).
* **CX Heartbeat** — 'one click retest', Audio Analytics and Network performance features added.
* **Performance Testing** — support for complex csv updates for answer call treatment, including dedicated 'from' numbers for each call.
* **CX insights** — User Interface (UI) updated to make it easier to identify CX, AX and Network scores.
**Operata Collector for Chrome update to v1.3.11**
* **Agent issue reporting** — Improved error handling with notification should the issue notification not be passed from the Operata Widget to the client API.
* **Jabra Headset stats collection** — Support for stats collection from the Jabra Engage range of headsets (Jabra Chrome Host and Chrome plugin still required).
*Buffa release added Assurance capability:*
* CX Baseline — Quickly test and compare global and regional performance scores to inform architecture and baseline expected performance.
* CX Heartbeat — Score your agents' and customers' experience and view audio quality shifts at each step of a call. Compare against CX Baseline to quickly identify areas needing improvement.
* Performance Testing — Manage change and transform with confidence using real calls, on demand, at scale.
**Operata Collector for Chrome update to v1.3.10**
* Heartbeat — Enabled agents to become test endpoints for Heartbeat.
* Backward compatibility — Ensures interoperability with customers using JS to provide easy transition to the Chrome extension.
* Agent Experience Collector CCP Logs — CCP log collection enabled in the Chrome Extension and new config added to set the required CCP logging level.
* Agent Status Browser version — Agents browser version added to the Agent Status dashboard.
* Agent Experience Collector — Updated content security policy on the Chrome extension to address a low level vulnerability.
* Outbound Packet Loss — Add outbound packet loss to the Operata Dashboard in response to a Customer request.
* Agent Experience Collector CCP Logs — CCP log collection enabled in the Chrome Extension and new config added to set the required CCP logging level.
* Agent Status Browser version — Agents browser version added to the Agent Status dashboard.
* Agent Experience Collector — Updated content security policy on the Chrome extension to address a low level vulnerability.
* Agent Experience Collector for native CCP — update to the Operata Chrome extension to support the CCP softphone hosted by Amazon.
* Agent Experience Collector Media — add a configuration toggle to enable/disable Media where handled by the default CCP.
* Agent Experience Collector CPU/Memory — Memory and CPU usage statistics collected by the Chrome Extension.
Aria release — Changes to the Operata platform to support the new Aria release of Operata which includes support for a raft of new features:
* Agent Experience Collector — A browser based data collector and agent messenger for alerting and reporting issues.
* Agent Experience Monitor — Capture environmental data including browser, hardware, network and noise. Help agents resolve issues in their control.
* Rapid Deployment Toolkit — No-code and low-code toolkit for flexible and rapid deployment of Operata.
* Streams and connect-rtc updates — updates to the versions pulled into the Chrome browser when using the Operata JS embedded into the Amazon Connect softphone (CCP) — Streams version 1.6.0 and connect-rtc version 1.1.7.
* Available CPU and Memory added to the Per Second Stats — the per second call detail now includes available CPU and Memory.
* CCP logs added to the public API — download of the CCP logs possible from the Operata API.
* Chrome Extension — Platform changes needed to support the new Agent Chrome extension that enables full data collection, agent issue reporting and agent notification with no changes needed to the softphone deployment (native, custom or embedded).
* CCP Logging — UI and platform changes to support CCP log collection at levels ranging from Trace to Critical logs only.
* Outbound and Inbound logging — Data network collection now split into TX and RX performance. Auto-Answer flag — 'Get the Details' now includes whether the call was auto-answered. Support Button — new Icon added for one touch launch of the Operata help center, to raise issues, access documentation and even see this Change Log!
* Bug fixes and enhancements — numerous minor bug fixes and platform enhancements.
* Workflow Email enhancements — Added the capability to include any data captured from the impacted call into the body of the email, for example the impacted agent, callContactId and the MOS score.
* Agent Reported Issues — Customers can create a UI element within their softphone that pushes Agent Reported Issues to a client side 'EventBus' this data is captured and is visible in the new Agent Status dashboard panel.
* Bug fixes and enhancements — numerous minor bug fixes and platform enhancements.
* Content Control — Added the capability for Customers to filter the data elements sent to Operata from within their AWS Environment (Conductor), with a code element that is accessible only by the Customer.
* POLQA v3 — The Operata platform now uses the latest POLQA version 3 which has been developed specifically for full band audio analysis which provides improved voice quality scoring for the OPUS codec used by Amazon Connect.
* Agent Status bug fixes — fixes to ContactId and CustomerBusy reporting.
* Jabra Headset performance statistics — productionise the integration of Jabra headset performance data into the Operata platform.
* Agent events collection — extend Operata JS collector application to capture agent events and error messages from the softphone (CCP).
* Agent status dashboard — Add 'Agent Status' dashboard to the main UI and API data set.
* Simulate compliance notification — AWS load test compliance notification when creating or running a campaign that exceeds defined thresholds.
* API access to Operata Data — Secure (API Secret) Access to Operata statistics using API.
* Conductor CloudFormation — Customer creation of Operata conductor using Cloudformation.
* Time Synchronization — Operata time synchronization to enable accurate event measurement.
* Additional call timestamp events from agent softphone — Detailed events from Agent softphone added to the call summary.
* Display timeline of events on a call — Graphical representation of Interaction events added to the 'GET THE DETAILS' Dashboard.
* Implement Operata collector for ServiceNow — Operata collector created to sit within a Connect softphone embedded into ServiceNow.
* Implement Operata collector for Salesforce — Operata collector created to sit within a Connect softphone embedded into Salesforce.
* Wizard Layout improvements — Added explainer text to the Wizard options in Simulate.
* Operata filters moved to local time-zone — Browser time-zone used to convert UTC to local time.
* Improved scalability and availability of agent CCP data collection into Operata.
* Conductor production release — Production release of the Operata AWS data aggregator (Conductor).
* RollingUpdate to prevent downtime — Change to method of delivering updates to remove any customer downtime.
* Ignore RTT and MOS measures for on-hold period — Connect introduces non-service impacting latency.
* Softphone white-listing — To improve security whitelist the origin(s) for use of the Operata softphone.
* Agent browser version detection — Collect and display the type and version of Agent Browser.
* Support for Amazon Connect Streams 1.4.7.
* Collect client-side logs/errors — To improve the support Operata provides for customer issues.
* Answer treatment CSV — Allow complex answer call treatment through csv upload.
* AWS Marketplace integration — Allow customers to subscribe to Operata from AWS Marketplace.
* Support for Amazon Connect Streams 1.4.6.
* Min call duration calculation — Automatically calculate the minimum call duration.
* Logging format to JSON — Expose the raw JSON details via the 'GET THE DETAILS' call records.
* Simulate Call Answer treatment 'w' abbreviation — Simplify answer call treatment.
* Email validation and welcome email — New Teammates to be sent an email validation email.
* Connect-rtc-js v1.1.6 — Support for the latest rtc js.
* NETWORK PERFORMANCE dashboard updates — Add average figures for all collected data types (MOS, RTT, Packet Loss and Jitter).
* 'Forgot my password' support on login page — Enable users to reset their own password from the main page.
* CSV exports — Ability to export softphone/network records from `Get the Details` dashboard UI.
* Conductor prototype release — Prototype release of the Operata AWS data aggregator (Conductor) to expose the performance of interactions within Connect.
* Simulate 'whitelist' — Enable Admin users to limit the 'To' numbers used in Simulate Campaigns to 'Whitelist numbers only'.
* NPM Package — Enable customers to use NPM on-line repository to pull the Operata collector into their Connect softphone browser.
# Install the Chrome extension
Source: https://docs.operata.com/docs/chrome-extension
Install the Agent Collector on Google Chrome via the Chrome Web Store or enterprise deployment, so every agent contact captures machine, network, and softphone telemetry.
Install the Agent Collector on Google Chrome so every agent contact captures machine, network, and softphone telemetry and streams it to Operata.
## Before you start
* An [Operata account](/docs/get-started-overview) and your Operata Group ID.
* Google Chrome on a supported version. See [Browser compatibility](/docs/browser-compatibility) for the current list.
* For enterprise deployments: admin access to your Chrome Enterprise policy or device-management tool.
## Steps
### 1. Install the extension
Open the [Operata browser extension listing](https://chrome.google.com/webstore/detail/operata-browser-extension/efhlocglafmcfhkpojjbckpbonbfbgdb) in the Chrome Web Store and click **Add to Chrome**.
For packaged enterprise deployments on Windows and macOS, follow [Google's guide to managing Chrome extensions](https://support.google.com/chrome/a/answer/7532015?hl=en) and push extension ID `efhlocglafmcfhkpojjbckpbonbfbgdb` through your existing policy.
### 2. Confirm the extension is loaded
Open `chrome://extensions/` in the agent's browser. The Operata Collector appears in the list with the toggle in the on position. Chrome maintains the extension automatically; the [Chrome Web Store listing](https://chrome.google.com/webstore/detail/operata-browser-extension/efhlocglafmcfhkpojjbckpbonbfbgdb) shows the current version.
### 3. Place a test contact
Have the agent open the contact center softphone in the same browser profile and place a test contact end to end.
## Verify
In the Operata console, open **Contacts** and filter to the last 10 minutes. Your test contact appears with the `serviceAgent` field populated — `browser.name` reads `Chrome` and `operataChromeExtVersion` matches the version shown in `chrome://extensions/`.
## Related
* [Edge extension](/docs/edge-extension) — Install the Collector on Microsoft Edge for agents on that browser.
* [VPN bypass URL](/docs/vpn-bypass) — Configure when agents work behind a corporate VPN.
* [Browser compatibility](/docs/browser-compatibility) — Supported Chrome versions.
* [Agent Collector overview](/docs/collector-overview) — What the Collector captures across all browsers.
# What cloud collection adds
Source: https://docs.operata.com/docs/cloud-collection-benefits
Browser collection alone misses how a contact originated, how it was delivered, and where it was transferred. Cloud collection fills those gaps and unlocks coverage reporting, agent grouping, Data Teams, and customer experience metrics.
The [Agent Collector](/docs/collector-overview) sees a contact from the agent's browser. That data is accurate, but it starts when the contact reaches the agent and ends when it leaves. Cloud collection brings in your platform's own contact records, which cover everything either side of that window.
## How it works
[Cloud collection](/docs/concepts-cloud-collection) reads contact records from your contact center platform's own event stream. Operata joins each record to the browser-side observations for the same contact, so one contact carries both views.
## What you get
### Data completeness
Browser data misses how a contact originated, how it was delivered, and when it was transferred. Cloud records carry all three, so the contact record is complete rather than agent-shaped.
### Coverage reporting
You only get the full picture when every agent runs the Agent Collector. Cloud collection gives you a second, independent count of contacts, so the Collection Coverage dashboard can compare cloud against browser and show you which agents are missing.
### Agent grouping
Contact center platforms let you tag agents with business structure — team, site, line of business. Cloud collection pulls those values in as Agent Groups, and every Operata dashboard becomes filterable by them.
### Data Teams
Most people should see only the dashboards and metrics their role needs. [Data Teams](/docs/help/data-teams) scopes visibility using Agent Groups and contact record attributes, so it needs cloud collection to work.
### Customer experience metrics
Cloud records complete the Customer Experience and Agent Interactions dashboards:
* **Queue and IVR** — queue, IVR (interactive voice response), and connection durations.
* **Transfers** — internal and external transfer detail, with a transfer map.
* **Initiation and disconnection** — how each contact started and how it ended.
* **Repeat contacts** — the pattern of interactions over time for one caller. Needs optional phone number capture.
## Platform specifics
What cloud collection adds beyond this depends on your platform.
* [Amazon Connect: what the AWS integration adds](/docs/help/aws-integration-benefits) — CTR (Contact Trace Record) and conversational analytics detail, with screenshots.
## Related
* [Collect](/docs/signal-overview) — the collectors and what each one emits.
* [Cloud collection](/docs/concepts-cloud-collection) — how the cloud side works on each platform.
* [Collection coverage](/docs/help/collection-coverage-user-guide) — reading the coverage dashboard.
* [Privacy and redaction](/docs/privacy-and-redaction-overview) — controlling what cloud collection sends.
# Agent Collector
Source: https://docs.operata.com/docs/collector-overview
The Agent Collector gives you the agent-side truth no central service can see — headset audio, network quality, microphone state, page focus, and softphone CTI events, per contact.
The Agent Collector gives you the agent-side truth no central service can see. It captures headset audio levels, network quality at the agent's desk, microphone state, page focus, and softphone CTI events — per contact, whether a human or an AI agent is handling it.
No central cloud service can observe what happens on the agent's endpoint. The Agent Collector runs as a browser extension alongside the contact center softphone and emits signals directly to Operata. Those signals become observations you query in the console and the API.
The Collector works inside applications that embed the softphone — Salesforce, ServiceNow, Zendesk — and keeps deployment under endpoint-management control rather than requiring desktop installers.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role and your Operata Group ID.
* Permission to install browser extensions on each agent endpoint, or the equivalent enterprise deployment access on Windows or macOS.
## What the Collector captures
* **Machine and browser metrics** — CPU and memory usage, browser version, software resource consumption.
* **Network telemetry** — interface details, IP addresses, ISP, and geolocation. See [VPN bypass](/docs/vpn-bypass) when agents work behind a corporate VPN.
* **Softphone signals** — WebRTC session statistics, headset events, call quality metrics.
* **Agent feedback** — issues agents raise from the Collector toolbar.
## Install the Collector
Operata ships the Agent Collector for Chrome and Microsoft Edge. Install the one that hosts your agents' softphone.
Install on Google Chrome via the Chrome Web Store or enterprise deployment.
Install on Microsoft Edge via Microsoft Edge Add-ons or enterprise deployment.
## Configure VPN bypass
If your agents work behind a corporate VPN — Zscaler, Cisco AnyConnect, Palo Alto GlobalProtect — configure the [VPN bypass URL](/docs/vpn-bypass) before agents place their first contact. Without it, the Collector reports the VPN provider's IP and ISP instead of the agent's actual network, making ISP-specific issues invisible.
## Verify the Collector is active
In the Operata console, open **Contacts** and filter to the last 10 minutes after a test contact. Your test contact appears with the `serviceAgent` field populated — the Collector captures machine, browser, softphone, network, and device data. If `serviceAgent` is empty, see [AWS troubleshooting](/docs/aws-troubleshooting) for Amazon Connect or contact [Operata Support](mailto:support@operata.com) for other platforms.
## Related
* [Chrome extension](/docs/chrome-extension) — Install on Google Chrome via the Chrome Web Store or enterprise policy.
* [Edge extension](/docs/edge-extension) — Install on Microsoft Edge via Microsoft Edge Add-ons or enterprise policy.
* [VPN bypass URL](/docs/vpn-bypass) — Route the Operata lookup endpoint outside the VPN tunnel.
* [Browser compatibility](/docs/browser-compatibility) — Supported Chrome and Edge versions.
* [Agent](/docs/agent) — The Amazon Connect data shape the Collector populates per contact.
* [Concept: Signals and observations](/docs/concepts-signals-and-observations) — How the Collector's measurements become Operata observations.
# Feature matrix
Source: https://docs.operata.com/docs/compatibility-feature-matrix
Feature availability by edition — Core, Enterprise, Enterprise+ — across Amazon Connect, Genesys Cloud, NICE CXOne, and other verified platforms.
Operata ships features across three editions: Core, Enterprise, and Enterprise+. Availability varies by edition and by platform. This page covers verified platforms — those that have completed Operata's certification. For the full list of supported integrations, see the [integrations hub](/docs/integrations-overview).
## Core edition features
All verified platforms include the following Core edition features.
### Data collection
| Feature | Description |
| - | - |
| Agent Experience Telemetry | Browser-based collection of agent workspace performance, network metrics, and device information |
| WebRTC Metrics | Real-time audio quality metrics including jitter, packet loss, and MOS scores |
| Agent State Tracking | Agent availability, status changes, and session duration |
| Network and ISP Information | Agent network performance, latency, and ISP details |
| Agent Machine Profile | CPU, memory, and system information from agent workstations |
| Call Metadata | Basic call attributes including duration, queue, phone numbers, and timestamps |
### Observability
| Feature | Description |
| - | - |
| Customer Journey Trace | Multi-platform journey visualization with flame-graph timelines showing complete customer interactions across platforms |
| Journey Explorer | Search, filter, and explore customer journeys with detailed span information |
| Insights | Automated detection of audio quality, network, and performance issues |
| Calls & Logs Explorer | Search and filter call records with detailed event logs |
| Dashboards | Pre-built performance dashboards with key CX metrics |
### Platform access
| Feature | Description |
| - | - |
| Web Application | Browser-based access to Operata platform |
| REST API | Programmatic access to telemetry data and insights |
| SSO Integration | Single sign-on for agent authentication |
## Enterprise edition features
Enterprise edition includes all Core edition features plus enhanced capabilities for select verified platforms.
### Enhanced data collection
Available for: **Amazon Connect**, **Genesys Cloud**, **NICE CXOne**
| Feature | Description |
| - | - |
| CRM Integration Data | Customer context from Salesforce Service Cloud Voice, Zendesk, ServiceNow |
| Advanced Call Signaling | Detailed SIP signaling and call flow analysis |
| Queue Performance Metrics | Real-time queue analytics and agent routing data |
| Conversational analytics integration | Amazon Connect conversational analytics sentiment and transcript data |
| Historical Data Retention | Extended data retention beyond Core Edition limits |
### Advanced observability
Available for: **Amazon Connect**, **Genesys Cloud**, **NICE CXOne**, **PolyAI**, **Twilio**
| Feature | Description |
| - | - |
| Cross-Platform Insights | Issue detection across platform handoffs and transfers |
| AI Agent Performance Analytics | Voice AI conversation metrics, handoff analysis, and intent tracking |
| Advanced Dashboards | Customizable dashboards with cross-platform analytics |
| Custom Journey Views | Create and save custom journey filters and visualizations |
### Proactive assurance
Available for: **Amazon Connect**
| Feature | Description |
| - | - |
| Heartbeat Human Agent | Synthetic monitoring of agent login and call flows |
| Heartbeat Virtual Agent | Automated testing of IVR and AI agent flows |
| EventBridge Integration | Real-time event streaming to AWS EventBridge for automation |
### Integrations
Available for: **Amazon Connect**, **Genesys Cloud**, **NICE CXOne**
| Feature | Description |
| - | - |
| Salesforce Integration | Deep integration with Salesforce Service Cloud Voice |
| Zendesk Integration | Ticket correlation and support context |
| ServiceNow Integration | Incident tracking and correlation with CX events |
## Enterprise+ edition features
Enterprise+ includes all Enterprise edition features plus:
| Feature | Description |
| - | - |
| Custom Integration Development | Operata engineers build integrations for custom or unlisted platforms |
| Priority Support | Dedicated Customer Success Manager and priority incident response |
| Advanced Security | Enhanced compliance controls, audit logging, and data governance |
| Increased API Rate Limits | Higher API request limits for large-scale integrations |
| White Glove Onboarding | Dedicated onboarding team and custom training |
## Feature support by verified platform
### CCaaS platforms
#### Amazon Connect
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Agent Experience Collection | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Conversational analytics integration | No | Yes | Yes |
| Heartbeat Monitoring | No | Yes | Yes |
| EventBridge Integration | No | Yes | Yes |
| Salesforce Integration | No | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### Genesys Cloud
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Agent Experience Collection | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Advanced Call Signaling | No | Yes | Yes |
| Queue Performance Analytics | No | Yes | Yes |
| Salesforce Integration | No | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### NICE CXOne
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Agent Experience Collection | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Advanced Call Signaling | No | Yes | Yes |
| Queue Performance Analytics | No | Yes | Yes |
| Salesforce Integration | No | Planned | Yes |
| Custom Integrations | No | No | Yes |
#### Amazon Lex
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Agent Experience Collection | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Intent and Utterance Tracking | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
### CPaaS platforms
#### Twilio
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Call Metadata Collection | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| SIP Signaling Analysis | No | Yes | Yes |
| Voice Quality Metrics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
### Voice AI platforms
#### PolyAI
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| AI Agent Conversation Data | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Handoff Analysis | No | Yes | Yes |
| Intent Recognition Metrics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### VAPI
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| AI Agent Conversation Data | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Voice Quality Metrics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### Bland
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| AI Agent Conversation Data | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Call Success Metrics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### LiveKit
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| Real-Time Audio Metrics | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| WebRTC Analytics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
#### Pipecat
| Feature Category | Core | Enterprise | Enterprise+ |
| - | - | - | - |
| AI Agent Conversation Data | Yes | Yes | Yes |
| Multi-Platform Journey Trace | Yes | Yes | Yes |
| Pipeline Performance Metrics | Yes | Yes | Yes |
| Custom Integrations | No | No | Yes |
## Additional capabilities
### Headset and device integrations
Operata supports integrations with agent hardware devices across all editions:
| Device Integration | Platforms | Edition Availability |
| - | - | - |
| Jabra Advanced Analytics | Amazon Connect, Genesys Cloud, NICE CXOne | Core, Enterprise, Enterprise+ |
| Generic WebRTC Softphone | All platforms with WebRTC | Core, Enterprise, Enterprise+ |
### Data privacy and security
All editions include:
* Data redaction and PII masking
* GDPR and CCPA compliance controls
* Encrypted data transmission (HTTPS/TLS)
* Role-based access control (RBAC)
Enterprise+ adds:
* Advanced audit logging
* Custom data retention policies
* Enhanced compliance reporting
## Notes
### Amazon Connect
* The Agent Collector installs via the Operata Chrome or Edge extension.
* The Cloud Collector installs via a CloudFormation stack in your AWS account.
* Conversational analytics integration requires Conversational analytics enabled in your Amazon Connect instance.
* Amazon EventBridge integration supports real-time event streaming and webhook delivery.
* For setup, see [Amazon Connect integration](/docs/integrations-amazon-connect-overview).
### Genesys Cloud
* The Agent Collector installs via the Operata Chrome or Edge extension.
* Multi-platform journey trace is available in all editions.
* Advanced call signaling requires Enterprise or higher.
* For setup, see [Genesys Cloud integration](/docs/genesys-overview).
### NICE CXOne
* The Agent Collector installs via the Operata Chrome or Edge extension.
* Multi-platform journey trace is available in all editions.
* Salesforce integration is planned for Enterprise edition.
* For setup, see [NICE CXOne integration](/docs/integrations-nice-cxone-overview).
### Voice AI platforms (PolyAI, VAPI, Bland, LiveKit, Pipecat)
* Multi-platform journey trace is available in all editions when combined with a CCaaS platform.
* Handoff analysis requires Enterprise, and requires both the Voice AI platform and a destination CCaaS integration.
* See [Customer Journey Trace](/docs/concepts-customer-journey-trace) for the cross-platform model.
## Related
* [Integrations hub](/docs/integrations-overview) — every platform Operata supports.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — multi-platform journey model.
* [Agent Collector](/docs/collector-overview) — browser-based data collection.
* [Platform compatibility](/docs/compatibility-platforms) — certified CCaaS versions and softphones.
# Compatibility overview
Source: https://docs.operata.com/docs/compatibility-overview
Five dedicated reference pages covering supported CCaaS platforms, browsers, headsets, feature availability by edition, and product lifecycle status.
Operata certifies specific platforms, softphones, browsers, and headsets. Coverage varies by edition, and every product version has a defined support lifecycle.
## Reference pages
* **[Platform compatibility](/docs/compatibility-platforms)** — certified versions of Amazon Connect, Genesys Cloud, and NICE CXOne and the supported softphones for each.
* **[Browser compatibility](/docs/browser-compatibility)** — supported Chrome and Edge versions for the Agent Collector.
* **[Headset compatibility](/docs/headset-compatibility)** — supported Jabra devices, operating systems, and browsers.
* **[Feature matrix](/docs/compatibility-feature-matrix)** — which features ship in Core, Enterprise, and Enterprise+ across every verified platform.
* **[Product lifecycle](/docs/product-lifecycle)** — support phases, notice periods, and the current lifecycle status of every Operata product version.
For the full list of supported integrations beyond the verified CCaaS (Contact Center as a Service) platforms — Voice AI, CPaaS, observability backends — see the [integrations hub](/docs/integrations-overview).
## Related
* [Integrations hub](/docs/integrations-overview) — all platforms Operata connects to, beyond the certified CCaaS set.
# Platform compatibility
Source: https://docs.operata.com/docs/compatibility-platforms
Certified CCaaS versions, softphones, and clients for the Operata Agent Collector across Amazon Connect, Genesys Cloud, and NICE CXOne.
The Operata Agent Collector is certified against specific versions of each supported CCaaS (Contact Center as a Service) platform. This page lists those certified configurations for Amazon Connect, Genesys Cloud, and NICE CXOne.
For browser and headset requirements, see [Browser compatibility](/docs/browser-compatibility) and [Headset compatibility](/docs/headset-compatibility). For feature availability by edition, see the [feature matrix](/docs/compatibility-feature-matrix).
## Amazon Connect
The following versions of Amazon Connect Contact Control Panel (CCP), Streams, and RTC are certified for use with the Collector.
| CCP | Streams | RTC |
| - | - | - |
| v2 | 1.6.3 | 1.1.8 |
| v2 | 1.6.0 | 1.1.6 |
| v2 | 1.5.x | 1.1.6 |
Operata has tested older CCP, Streams, and RTC versions and may support them by prior agreement. Contact [support@operata.com](mailto:support@operata.com) to discuss your version requirements.
The Amazon Connect SDK source is hosted on GitHub:
* [amazon-connect-streams](https://github.com/amazon-connect/amazon-connect-streams)
* [connect-rtc-js](https://github.com/aws/connect-rtc-js)
For installation, see [Amazon Connect integration](/docs/integrations-amazon-connect-overview).
## Genesys Cloud
Operata supports the Genesys Cloud WebRTC Softphone (browser-based).
For installation, see [Genesys Cloud integration](/docs/genesys-overview).
## NICE CXOne
Operata supports the NICE CXOne MAX WebRTC Softphone.
For installation, see [NICE CXOne integration](/docs/integrations-nice-cxone-overview).
## Related
* [Browser compatibility](/docs/browser-compatibility) — supported Chrome and Edge versions.
* [Headset compatibility](/docs/headset-compatibility) — supported Jabra devices and operating systems.
* [Feature matrix](/docs/compatibility-feature-matrix) — feature availability by edition and platform.
* [Product lifecycle](/docs/product-lifecycle) — support phases and deprecation policy.
# Cloud collection
Source: https://docs.operata.com/docs/concepts-cloud-collection
How contact records from your contact center platform reach Operata, what path each platform takes, and where your redaction policy is applied on the way.
Cloud collection brings your contact center platform's own record of each contact into Operata. The [Agent Collector](/docs/collector-overview) reports what the agent's browser, network, and headset saw; cloud collection adds queue and IVR durations, transfers, disconnect reasons, and the contacts that never reached an agent.
## How it works
Every platform keeps a structured record of each contact. Operata reads that record and joins it to the browser-side observations for the same contact, so one contact carries both views.
The path the record takes depends on the platform.
| Platform | How the record reaches Operata |
| - | - |
| [Amazon Connect](/docs/integrations-amazon-connect-overview) | Operata deploys the Cloud Collector into your AWS account. It reads Contact Trace Records (CTRs) from Kinesis and forwards them to the Operata API. |
| [Genesys Cloud](/docs/genesys-overview) | Genesys Cloud publishes analytics and platform events to an event bus in Operata's AWS account. On conversation end, the Operata Fetcher Service calls read-only Genesys Cloud APIs for the Conversation Detail record. |
| [NICE CXOne](/docs/integrations-nice-cxone-overview) | Your CXOne tenant streams structured Interaction records to Operata, stamped with your Operata Group ID. |
No path carries call audio. Operata reads metadata and analytics records; recordings and live media stay in your platform.
Collection runs one way. A collector emits, Operata ingests, and nothing downstream reaches back to change what your platform reported.
## Where redaction runs
Your [redaction policy](/docs/privacy-and-redaction-overview) is applied on the collection path, before Operata stores anything. Where on that path depends on the platform.
* **Amazon Connect** — inside your AWS account. The Cloud Collector applies the filter before the record crosses the boundary, so a denied field never leaves your account.
* **Genesys Cloud** — in the Operata Fetcher Service, which runs in Operata's managed infrastructure. A denied field is dropped from the payload before anything is stored.
Either way, a field you deny is never stored and the API never returns it.
## Synthetic checks
Cloud collection covers real contacts. Operata also generates synthetic ones: [Heartbeat](/docs/surface-overview) places a test call through your contact flow on a schedule, and the Virtual Agent plays the caller side of it. Synthetic runs emit the same signals as real contacts and carry a flag, so you can filter them in or out of dashboards.
## Platform specifics
* [Amazon Connect: Cloud Collector](/docs/concepts-cloud-collector) — the in-account components, their IAM surface, and the redaction refresh cycle.
* [Amazon Connect: Cloud Orchestrator](/docs/concepts-cloud-orchestrator) — the runtime behind Heartbeat and the Virtual Agent.
* [Genesys Cloud integration](/docs/genesys-overview) — the event topics, REST endpoints, and OAuth scopes Operata uses.
* [NICE CXOne integration](/docs/integrations-nice-cxone-overview) — what reaches Operata from a CXOne tenant.
## Related
* [What cloud collection adds](/docs/cloud-collection-benefits) — why browser data alone leaves gaps.
* [Agent Collector](/docs/collector-overview) — the browser-side half of collection.
* [Signals and observations](/docs/concepts-signals-and-observations) — what a collected record becomes once Operata stores it.
* [Collection frequency](/docs/resources-data-collection-frequency) — how often each collector reports.
* [Privacy and redaction](/docs/privacy-and-redaction-overview) — what you can suppress, and where.
* [Choose your integration](/docs/integrations-overview) — the platforms Operata collects from.
# Amazon Connect: Cloud Collector
Source: https://docs.operata.com/docs/concepts-cloud-collector
Runs inside your AWS account to read Amazon Connect Contact Trace Records from Kinesis, apply your redaction policy, and forward the filtered result to Operata.
The Cloud Collector is the AWS-side service Operata deploys into your account to read Amazon Connect Contact Trace Records (CTRs) from Kinesis, apply your redaction policy, and ship the result to the Operata API.
This page covers the Amazon Connect path. For how contact records reach Operata on every platform, see [Cloud collection](/docs/concepts-cloud-collection).
## How it works
The Cloud Collector is one of two AWS-side services Operata installs. The other is the [Cloud Orchestrator](/docs/concepts-cloud-orchestrator), which generates synthetic traffic. The Cloud Collector ingests real traffic — it sits on the path between your Amazon Connect instance and Operata, not the other way round.
Three components make up the Cloud Collector: an Amazon EventBridge Pipe that reads Contact Trace Records from the Amazon Connect Kinesis stream; a Lambda function that applies the active redaction config and enriches the record; and an EventBridge API destination that posts the filtered result to Operata. The Lambda function is the redaction enforcement point — see [Privacy and redaction](/docs/concepts-privacy-and-redaction) for the model it implements.
```mermaid theme={null}
flowchart LR
A[Amazon Connect contact ends] --> K[Kinesis stream]
K --> P[EventBridge Pipe]
P --> L[Redactor Lambda]
L --> D[EventBridge API destination]
D --> O[Operata API]
```
The Lambda caches the active redaction config and polls the Operata API every 30 minutes to refresh it. If a refresh fails, the Lambda falls back to the mandatory minimum so a network outage cannot expand what the Cloud Collector ships. Each CTR passes through the Lambda once; allowed fields are forwarded, dropped fields stay in your AWS account.
The Cloud Collector runs under two IAM roles: an EventBridge Pipe role that reads Kinesis, invokes the Lambda, and posts to the API destination; and a Lambda service role that executes the function, reads the Operata API token from Secrets Manager, and — when configured for VPC deployment — manages its network interfaces. The default CloudFormation template creates both roles with least-privilege policies scoped to the specific Pipe, Lambda, secret, and API destination ARNs. [IAM Role and Policies](/docs/iam-policies) documents the policy contract in full.
## Why redaction runs in your account
Running ingestion and redaction inside your AWS account, not Operata's, is the structural guarantee behind the privacy model. The dropped fields are never read by anything outside your account — the filter runs before the record crosses the boundary. That guarantee only holds if the components live where the data lives, so the Cloud Collector is an in-account install rather than a service Operata operates centrally.
The split into Pipe, Lambda, and API destination follows AWS-native shapes. EventBridge Pipes handle the source-to-target plumbing; Lambda handles per-record logic; API destinations handle outbound HTTP with retry. Each component has its own IAM surface, its own CloudWatch metrics, and its own failure mode, which makes troubleshooting per-record rejections straightforward.
The 30-minute config refresh is a deliberate latency-for-safety trade. A faster refresh would react to policy changes sooner; a slower one would survive Operata API outages longer. Thirty minutes keeps the cached config fresh enough for most rollouts while leaving the Cloud Collector functional during transient upstream failures. Outside the refresh window, the Lambda enforces whatever config it last read — there is no live call to Operata per record.
## Related
* [Cloud collection](/docs/concepts-cloud-collection) — the platform-neutral parent: what cloud collection is, and the path each platform takes.
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the allow-list / deny-list model the Cloud Collector enforces.
* [Cloud Orchestrator](/docs/concepts-cloud-orchestrator) — the sibling AWS-side service that generates synthetic traffic.
* [Signals and observations](/docs/concepts-signals-and-observations) — what the filtered record becomes once Operata stores it.
* [Why Kinesis Streams](/docs/concepts-why-kinesis-streams) — why the Cloud Collector reads from a stream rather than polling.
* [Data redaction](/docs/api-data-redaction) — the reference index for the config the Cloud Collector reads.
* [Get redaction config](/docs/api-get-redaction-config) — inspects the active config the Cloud Collector caches.
* [Update redaction config](/docs/api-update-redaction-config) — replaces the config; the change propagates on the next refresh.
* [Webhooks events](/docs/api-webhooks-events) — fires once Operata has stored the filtered record as observations.
# Amazon Connect: Cloud Orchestrator
Source: https://docs.operata.com/docs/concepts-cloud-orchestrator
Runs inside your AWS account to drive synthetic Heartbeat checks and Virtual Agent calls against your Amazon Connect instance, surfacing failures before real customers see them.
Cloud Orchestrator is the AWS-side service Operata deploys into your account to run synthetic checks against Amazon Connect — placing test calls, exercising contact flows, and reporting the result back to Operata. It's the Amazon Connect runtime behind Heartbeat and the Virtual Agent.
For where synthetic checks sit alongside real-traffic collection, see [Cloud collection](/docs/concepts-cloud-collection).
## How it works
Cloud Orchestrator is distinct from the [Cloud Collector](/docs/concepts-cloud-collector). The Cloud Collector ingests real contacts; Cloud Orchestrator generates synthetic ones. They share an AWS account and an Operata account but no runtime components — they can be installed independently.
Cloud Orchestrator runs on Amazon ECS with Fargate inside a dedicated VPC. The install stack creates the VPC and isolates it from other workloads in your account; only egress to the Operata API gateway leaves the VPC, and nothing routes in. A Lambda function handles orchestration logic — picking which check to run next, when, and against which contact flow — and ECS containers place the actual calls.
Two products run on Cloud Orchestrator: **Heartbeat**, the synthetic monitoring service that exercises a contact flow on a schedule and surfaces failures before customers see them; and the **Virtual Agent**, a container-based bot that plays the caller side of a Heartbeat call. The Orchestrator also creates and reads from a Kinesis stream when one is not already configured by Amazon Connect.
```mermaid theme={null}
flowchart LR
A[Heartbeat schedule] --> B[Cloud Orchestrator Lambda]
B --> C[Virtual Agent ECS task]
C -->|Places call| D[Amazon Connect contact flow]
D --> E[Result + signals]
E --> F[Operata API]
```
## Why synthetic checks run inside your account
Synthetic monitoring needs to look exactly like a real customer to be useful. Running the Virtual Agent inside the same AWS account as your Amazon Connect instance means the call traverses the same networking, the same instance configuration, and the same regional routing — a failure detected by Heartbeat is a failure your real customers would see.
The separate VPC is deliberate. The Virtual Agent places outbound calls and holds credentials in AWS Secrets Manager; keeping it isolated from other workloads keeps the blast radius small and the IAM surface auditable. All AWS-side charges accrue to your account because the calls, containers, and Kinesis records live there.
The split between Lambda orchestration and ECS execution exists because the two have different shapes: orchestration decisions are short, infrequent, and event-driven (a good fit for Lambda), while running a voice bot in a container requires long-lived process state (a good fit for Fargate).
## Related
* [Cloud collection](/docs/concepts-cloud-collection) — the platform-neutral parent: how real and synthetic contacts reach Operata.
* [Amazon Connect: Cloud Collector](/docs/concepts-cloud-collector) — the sibling AWS-side service that ingests real contacts.
* [Signals and observations](/docs/concepts-signals-and-observations) — the data Cloud Orchestrator emits on each synthetic run.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — Heartbeat journeys are traces too, so the same cross-platform model applies.
* [EventBridge](/docs/concepts-eventbridge) — how Cloud Orchestrator delivers run results to your downstream systems.
* [Webhooks events](/docs/api-webhooks-events) — `heartbeat.run.completed` and Virtual Agent events fire on every synthetic check, with the result and timing.
* [Contact summary](/docs/api-contact-summary) — Heartbeat calls appear as contacts with a synthetic flag, so you can filter them in or out of dashboards.
* [Webhooks overview](/docs/api-webhooks-overview) — how to subscribe to the events emitted by Cloud Orchestrator.
# Contacts and interactions
Source: https://docs.operata.com/docs/concepts-contacts-and-interactions
A Contact, an Interaction, and a Conversation are platform-specific names for one customer-side record Operata observes from start to end. Operata locks one term per platform.
A Contact, an Interaction, and a Conversation are platform-specific names for one customer-side record Operata observes from start to end. Operata locks one term per platform so the API surface stays predictable.
## How it works
A **Contact** is the Amazon Connect name. It starts when a customer reaches your contact center — through inbound voice, callback, chat, or task — and ends when the platform closes the record. Amazon Connect identifies it with a `ContactId` and emits a Contact Trace Record (CTR) once the contact terminates. In Operata, a Contact carries the CTR, the headset analytics, the contact-flow modules, and the per-leg event timing for that single record.
An **Interaction** is the NICE CXOne name for the same construct. A **Conversation** is the Genesys Cloud name. Each platform models the entity differently — different identifiers, different lifecycle events, different segment vocabulary — but Operata normalizes all three into one shape so dashboards, queries, and webhooks behave the same regardless of source.
A Contact is not always the complete customer story. When a single customer flows through more than one platform — an IVR handoff into a CCaaS (Contact Center as a Service), a transfer between vendors — each platform emits its own Contact, Interaction, or Conversation, and Operata correlates them under a single [Customer Journey Trace](/docs/concepts-customer-journey-trace). The Contact is the per-platform record; the journey is the cross-platform path.
```mermaid theme={null}
flowchart LR
A[Amazon Connect Contact] -->|same customer| T[Customer Journey Trace]
B[NICE CXOne Interaction] -->|same customer| T
C[Genesys Cloud Conversation] -->|same customer| T
```
## Why Operata keeps each platform's name
Each CCaaS vendor settled on its own noun before any cross-platform observability tool existed. Forcing a single name onto all three platforms drops information — "Conversation" implies messaging in Genesys Cloud but voice in some other tools — so Operata keeps each platform's native name in the API surface that touches that platform, and reserves the journey as the abstraction that spans them.
Prose has to choose. Cross-platform pages lead with "contact" and name the per-platform synonyms once. Per-platform reference pages use the native term. The terminology lock makes the choice deterministic so the same noun never refers to different things on different pages.
## Related
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how Operata correlates per-platform Contacts into one cross-platform path.
* [Signals and observations](/docs/concepts-signals-and-observations) — the measurements Operata attaches to a Contact.
* [Insights](/docs/concepts-insights) — the per-contact detections Operata derives from the underlying observations.
* [List contact summaries](/docs/api-contact-summary) — paginates contacts in a time window with headline metrics for each.
* [Get complete contact record](/docs/api-contact-record) — returns every Operata field for one contact, including CTR, headset analytics, and per-leg event timing.
* [Contact stats](/docs/api-contact-stats) — aggregates over contacts and journeys for trend analysis.
* [Webhooks events](/docs/api-webhooks-events) — fires contact-lifecycle events as new records and updates land.
# Customer Journey Trace
Source: https://docs.operata.com/docs/concepts-customer-journey-trace
How Operata correlates every contact, transfer, and platform handoff a single customer touches into one observable trace.
Customer Journey Trace is the chain of interactions a single customer has with your contact center — every call, callback, IVR session, AI conversation, queue wait, and agent handoff — correlated under one journey identifier so you can observe outcomes across the full path, not inside one platform alone.
## How it works
A **journey** is the customer's end-to-end path across your contact center platforms. A **span** is one segment of that journey on one platform. Operata recognises span types for telephony, IVR, AI conversation, agent interaction, queue wait, and platform handoff. Each span carries timestamps, platform-native IDs, attributes, signals, and any insights detected during that segment.
Operata assembles a journey progressively as data arrives from each platform. Some platforms emit data in real time; Amazon Connect Contact Trace Records (CTRs) can land 5–20 minutes after the contact ends. Early views of a journey are intentionally partial — the trace fills in as platforms report. The journey identifier is stable across that assembly window, so a journey opened mid-flight resolves into the same record once late data arrives.
Operata correlates spans by joining native platform identifiers (`ContactId` for Amazon Connect, `CallSid` for Twilio, Conversation ID for Genesys Cloud) on transfer events, SIP headers, and CTR attributes. Operata divides the journey into legs, one per platform: leg 1 is where the journey starts, leg 2 is the first handoff destination, and so on. The leg counter tells you how many systems handled the same customer.
```mermaid theme={null}
flowchart LR
A[IVR span] --> B[AI conversation span]
B --> C[Platform handoff span]
C --> D[Queue span]
D --> E[Agent interaction span]
E --> F[Telephony span ends]
```
## Why Operata assembles journeys asynchronously
Contact-level observability misses the question developers actually have to answer: *where in the customer's path did the contact fail?* A dropped call in Amazon Connect looks identical to a normal contact-end if you only see the Amazon Connect side of the data — the cause sits in the transfer that preceded it.
Operata could withhold journeys until every platform has reported, but that delays observability by 20+ minutes for every contact, including the 95% that need no investigation. The current approach favours partial reads over slow reads: a journey is queryable the moment its first span lands, with the understanding that the rest fills in as data arrives.
Operata generates the journey identifier rather than relying on any single platform's ID because no platform sees the full path. Even when a CCaaS platform emits its own conversation ID, that ID is unique to that platform's leg of the journey, not to the journey itself.
## Related
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — what a Contact, an Interaction, and a Conversation each mean across Amazon Connect, NICE CXOne, and Genesys Cloud.
* [Signals and observations](/docs/concepts-signals-and-observations) — the unit each collector emits and how Operata stores it against a contact.
* [Insights](/docs/concepts-insights) — the per-contact and per-journey rollups that surface inside spans.
* [EventBridge](/docs/concepts-eventbridge) — how journey-level updates reach your downstream systems.
* [List contact summaries](/docs/api-contact-summary) — each contact carries the journey it belongs to and its position in the journey.
* [Complete contact record](/docs/api-contact-record) — exposes the spans, handoffs, and platform-native IDs for one contact in the journey.
* [Contact stats](/docs/api-contact-stats) — aggregates over journeys, not just contacts, so trends include cross-platform paths.
* [Webhooks overview](/docs/api-webhooks-overview) — Amazon EventBridge events fire as new spans land, so downstream systems can react to handoffs and journey-end before the full trace is assembled.
# EventBridge
Source: https://docs.operata.com/docs/concepts-eventbridge
Operata publishes every contact, agent, and Heartbeat event to a partner event bus in your AWS account via Amazon EventBridge — no HTTP endpoint required.
Operata delivers every contact, agent, and Heartbeat event to your AWS account through Amazon EventBridge — you receive events on a partner event bus and route them with standard EventBridge rules.
## How it works
Operata holds a SaaS partner registration with AWS. When you enable the integration, Operata creates a partner event source in your AWS account. You bind it to a partner event bus, and from that point every Operata-generated event lands on that bus. You then route events — to Lambda, SQS, Step Functions, Kinesis, an HTTP API destination, or any other EventBridge target — with standard EventBridge rules and event patterns.
Events carry the contact, agent, or Heartbeat run they describe, plus the signals and insights Operata attached during processing. The event envelope follows Amazon's `aws.partner/operata.io/...` source convention, so EventBridge rules match on `source` and `detail-type` exactly as they do for AWS-native events.
Delivery is at-least-once. Operata publishes each event once the corresponding observation finalizes; AWS handles delivery to your bus. Your downstream targets own idempotency — if the same event `id` appears twice, treat the second copy as a duplicate, not a state change.
```mermaid theme={null}
flowchart LR
A[Operata observation] --> B[Operata EventBridge publisher]
B --> C[Partner event source]
C --> D[Your partner event bus]
D --> E[EventBridge rule]
E --> F[Lambda / SQS / Splunk / etc.]
```
## Why Operata uses EventBridge instead of HTTP webhooks
EventBridge replaces the per-customer HTTP webhook pattern most SaaS APIs use. Instead of Operata pushing to an endpoint you operate — with the retries, signature verification, and IP allowlisting that pattern requires — AWS owns the transport into your account and you own the routing inside it.
For customers already on AWS — every Amazon Connect customer by definition — this means no public endpoint to expose, no shared-secret rotation, and no separate retry logic. EventBridge rules already cover filtering, transformation, dead-letter queues, and cross-account fan-out, so the integration inherits those capabilities instead of re-implementing them.
EventBridge events are AWS-scoped. If you need to deliver events to a destination outside AWS, terminate the event chain at an EventBridge API destination, an SQS queue polled by an external worker, or a Lambda that forwards onward. There is no separate non-AWS webhook path.
## Related
* [Webhooks overview](/docs/api-webhooks-overview) — delivery model, envelope, and example consumers.
* [Configure webhooks](/docs/api-webhooks-configure) — bind a partner event source to a partner event bus in your AWS account.
* [Event catalog](/docs/api-webhooks-events) — every `detail-type`, its payload, and when it fires.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — journeys emit events as new spans land, so downstream systems can react to handoffs before assembly completes.
* [Signals and observations](/docs/concepts-signals-and-observations) — what gets carried in an EventBridge event's `detail` payload.
* [Cloud Orchestrator](/docs/concepts-cloud-orchestrator) — Heartbeat runs publish through the same EventBridge path.
* [Cloud Collector](/docs/concepts-cloud-collector) — the AWS-side service that produces the observations EventBridge then ships.
# Insights
Source: https://docs.operata.com/docs/concepts-insights
An insight is a named detection Operata derives from the observations on a contact — a known pattern, surfaced once per contact it applies to.
An insight is a named detection Operata derives from the observations on a contact — a known pattern, surfaced once per contact it applies to.
## How it works
An insight has four parts: a **name** (for example, `audio_one_way`), a **category** (audio, network, agent, contact), a **severity** (minor, severe, terminal), and a **detection rule** that runs over the contact's observations. When the rule matches, Operata writes one insight record against the contact. That record carries the timestamps it covered, the contributing observations, and any platform-native fields the rule consulted.
Insights are derived, not collected. Collectors emit signals; Operata stores observations; the insight engine reads observations and writes insights. Because insights run after observation storage, late-arriving signals can change which insights apply — a contact that looks clean on first read may gain an insight once the Contact Trace Record (CTR) lands.
Insights are bounded to a single contact. Cross-contact analysis happens at the journey level (see [Customer Journey Trace](/docs/concepts-customer-journey-trace)), which can aggregate insights across the journey's contacts. The full catalog of every detection Operata runs — names, categories, severities, and matching conditions — lives at [Insights catalog](/docs/insights-catalog).
## Why insights are separate from observations
Raw observations answer "what happened?" Insights answer "what should I care about?" Keeping them separate means the data layer stays general — every observation is queryable — while Operata ships pattern detection without requiring every API consumer to reimplement it. New detections appear in the catalog over time; the underlying observations do not change shape when they do.
Bounding each insight to one contact keeps them composable. Joins, journey rollups, and downstream alerting all assume one insight maps to one contact, which makes the dashboard and EventBridge contracts predictable.
## Related
* [Signals and observations](/docs/concepts-signals-and-observations) — the underlying data the insight engine reads.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the record an insight attaches to.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how insights aggregate across the contacts that share a journey.
* [List contact summaries](/docs/api-contact-summary) — each summary row carries the count and severity of insights raised for the contact.
* [Get complete contact record](/docs/api-contact-record) — exposes the full insight list for one contact, with contributing observations.
* [Webhooks events](/docs/api-webhooks-events) — fires per-insight events as insights land, including late ones that follow a CTR.
# Privacy and redaction
Source: https://docs.operata.com/docs/concepts-privacy-and-redaction
The model behind Operata redaction — what runs where, what you control, and what stays raw.
Operata redacts at the edge of your AWS account, before contact data leaves for Operata, using a single allow-list or deny-list configuration that you control through the API.
## How it works
Redaction runs inside the [Cloud Collector](/docs/concepts-cloud-collector), in your AWS account, on the path between Amazon Connect and Operata. The Cloud Collector reads Contact Trace Records (CTRs) from Kinesis, applies the active redaction config, and ships only the fields that survive the filter. Operata never sees the dropped fields — they are removed before the request crosses the AWS boundary.
The redaction config is a single JSON document stored against your Operata account. There is one config per account. It is one of two shapes, distinguished by `value.type`:
* `WHITELIST` — allow-list. The Cloud Collector ships only the mandatory CTR fields plus the fields you name.
* `BLACKLIST` — deny-list. The Cloud Collector ships every CTR field except the ones you name.
A small set of mandatory CTR fields — for example `ContactId`, `InitiationTimestamp`, `Queue.Name` — ships regardless of the config. A deny-list cannot remove them; an allow-list cannot omit them. They are the minimum Operata needs to attribute a record to a Contact and place it on a timeline.
When no config exists, the Cloud Collector applies the privacy-first default and ships only the mandatory fields. Reading the config endpoint in that state returns `404`. The default is restrictive on purpose: a misconfigured or unconfigured account leaks nothing past the mandatory minimum.
```mermaid theme={null}
flowchart LR
A[Amazon Connect CTR] --> K[Kinesis stream]
K --> C[Cloud Collector in your AWS account]
C -->|allow-list or deny-list filter| F[Filtered record]
F --> O[Operata API]
C -.->|dropped fields stay in AWS| X[Never sent]
```
The Cloud Collector caches the active config and refreshes it from the Operata API on a 30-minute interval. When you change the config through the API, the new policy takes effect on the next refresh — there is a propagation window of up to 30 minutes during which contacts in flight ship under the previous policy. If a refresh fails, the Cloud Collector falls back to the mandatory minimum until it can reach Operata again.
## Why redaction runs at the edge
Running the filter inside your AWS account, before the record crosses the boundary, is the only way to give you a hard guarantee about what Operata receives. A server-side filter would still require Operata to read every field before dropping it; an edge filter does not. The trade-off is that the Cloud Collector has to run in your account, with the IAM surface that implies — see [Cloud Collector](/docs/concepts-cloud-collector) for the components, and [IAM Role and Policies](/docs/iam-policies) for the role and policy contract.
The single-config-per-account rule simplifies the propagation contract. Multiple configs would force the Cloud Collector to evaluate which one applies per record, which adds latency and a class of misconfiguration bugs. One config means one cached document and one refresh interval to reason about.
The 30-minute propagation window is the shared-responsibility line. You own the config; Operata propagates it. Until the window closes, contacts in flight can still ship fields the old config allowed. For changes that must take effect immediately, stop the EventBridge pipe, update the config, wait for a refresh, then restart — this is documented in [Configure CTR redaction](/docs/guides-configure-ctr-redaction).
## Related
* [Data redaction](/docs/api-data-redaction) — the reference index for the three config endpoints.
* [Get redaction config](/docs/api-get-redaction-config) — reads the active config. Returns `404` when the privacy-first default is in effect.
* [Update redaction config](/docs/api-update-redaction-config) — replaces the active config. `PUT` is a full replace, not a patch.
* [Delete redaction config](/docs/api-delete-redaction-config) — removes the config and reverts to the privacy-first default.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — the step-by-step rollout guide.
* [Cloud Collector](/docs/concepts-cloud-collector) — the AWS-side component that applies the filter.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the record the mandatory fields describe.
* [Signals and observations](/docs/concepts-signals-and-observations) — what gets stored once a filtered record reaches Operata.
* [EventBridge](/docs/concepts-eventbridge) — how filtered records flow from your account to Operata and onward to downstream consumers.
# Signals and observations
Source: https://docs.operata.com/docs/concepts-signals-and-observations
A signal is a single measurement a collector emits in flight. An observation is the persisted Operata record built from one or more signals and tied to a contact.
A signal is a single measurement a collector emits in flight; an observation is the persisted Operata record that ties one or more signals to a contact. Signals flow; observations are stored.
## How it works
Each collector emits a different class of signal.
* The [Agent Collector](/docs/collector-overview) emits signals for headset audio levels, network quality, microphone state, page focus, and softphone CTI events — the agent-side measurements no central service can see.
* [Cloud collection](/docs/concepts-cloud-collection) emits signals derived from your platform's own contact records — Contact Trace Records (CTRs) on Amazon Connect, Conversation Detail on Genesys Cloud, Interaction records on NICE CXOne.
* Synthetic checks emit signals from each [Heartbeat](/docs/surface-overview) run.
A signal is small, structured, and timestamped. It becomes meaningful only when joined to the contact it belongs to.
The lifecycle runs in three stages. A collector emits a signal. Operata ingests the signal, joins it to the contact, and persists it as part of an observation. Downstream consumers — the dashboard, [EventBridge events](/docs/concepts-eventbridge), and the [contact endpoints](/docs/api-contact-summary) — read observations, never raw signals. Two signals from two collectors covering the same moment of the same contact land as one observation with two contributing sources.
```mermaid theme={null}
flowchart LR
A[Agent Collector] -->|signal| O[Operata ingestion]
B[Cloud Collector] -->|signal| O
C[Cloud Orchestrator] -->|signal| O
O -->|persist| D[Observation on Contact]
D --> E[API + EventBridge consumers]
```
## Why Operata stores observations, not signals
The split keeps the wire format separate from the storage format. Redaction, deduplication, late-arrival reconciliation, and per-tenant validation all run between the two. The value a collector reports is not the value a consumer reads: a signal can be dropped, deferred, or merged; an observation is the post-processing result a consumer can rely on.
The split also makes the data model honest about latency. Some signals arrive within seconds; Amazon Connect CTRs in particular can lag the contact end by minutes. Storing observations means a query for a recent contact returns a coherent partial view that fills in as more signals arrive, instead of a stream of half-correlated events.
## Related
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the record observations attach to.
* [Insights](/docs/concepts-insights) — named detections Operata derives from the underlying observations.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — observations roll up across the contacts that share a journey.
* [List contact summaries](/docs/api-contact-summary) — each summary row is built from the observations stored against a contact.
* [Get complete contact record](/docs/api-contact-record) — exposes the per-leg observations and their contributing signal sources.
* [Webhooks events](/docs/api-webhooks-events) — fires as new observations land, including late CTR-derived ones.
# Kinesis Streams vs Firehose
Source: https://docs.operata.com/docs/concepts-why-kinesis-streams
Operata reads Amazon Connect CTRs from a Kinesis Data Stream rather than a Kinesis Data Firehose because Streams support multiple concurrent consumers and Firehose does not.
Operata reads Amazon Connect Contact Trace Records (CTRs) from a Kinesis Data Stream rather than a Kinesis Data Firehose because Streams support multiple concurrent consumers and Firehose does not.
## How it works
Amazon Connect can stream CTRs to either Kinesis Data Streams or Kinesis Data Firehose. The two services solve different problems. Firehose is a managed ETL pipeline: it batches incoming records and delivers them to one pre-configured destination — S3, Redshift, or Splunk. Streams is a durable buffer: records sit on the shard for the retention window (24 hours by default, up to 365 days) and any number of consumers read them independently.
When CTRs land on a Firehose, only the destination configured on that Firehose receives them. When CTRs land on a Stream, Operata reads them, your BI tool reads them, and any future consumer also reads them — each tracking its own position on the shard.
Operata recommends Kinesis Data Streams as the destination Amazon Connect writes to, with an optional Firehose downstream of the Stream for customers who also need Firehose's S3 or Splunk delivery. The Stream becomes the fan-out point; the Firehose becomes one consumer among several.
```mermaid theme={null}
flowchart LR
A[Amazon Connect CTRs] --> B[Kinesis Data Stream]
B --> C[Cloud Collector]
B --> D[Kinesis Firehose]
D --> E[S3 / Redshift / Splunk]
B --> F[Other consumers]
```
## Why Operata uses Streams over Firehose
Firehose is the right choice if exactly one system consumes the CTRs and that system is a destination Firehose natively supports. The moment a second consumer needs the same data, a Firehose-only setup forces either duplicate streaming configurations on the Amazon Connect instance (one per consumer) or a custom replay mechanism out of S3. Both are operationally noisy compared to placing a Stream in front.
The cost trade-off is small. A Kinesis Data Stream with on-demand capacity charges per GB ingested and per GB read — the same shape as Firehose. The added cost of running both Stream and Firehose for a single-destination use case is the Stream's ingest charge, which is the smaller of the two line items for typical CTR volumes.
The latency trade-off is also small. Operata reads from the Stream within seconds of a record landing; Firehose delivers in micro-batches with a configurable buffer (60 seconds or 1 MB by default). For real-time observability, Stream is faster. For batch delivery to S3, Firehose is still doing the right job — it just reads from a Stream now, not directly from Amazon Connect.
## Related
* [Cloud Collector](/docs/concepts-cloud-collector) — the AWS-side service that reads CTRs off the Stream.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — what Operata calls a contact once the Cloud Collector has read its CTR off the Stream.
* [Signals and observations](/docs/concepts-signals-and-observations) — the data Operata stores after processing a CTR.
* [Webhooks events](/docs/api-webhooks-events) — `contact.completed` fires once Operata has read the CTR from the Stream and processed it.
* [Contact record](/docs/api-contact-record) — the full contact record Operata builds from the CTR on the Stream.
# Contact (Amazon Connect)
Source: https://docs.operata.com/docs/contact
The contact fields Operata captures for each Amazon Connect Contact — identifiers, queue, direction, event timestamps, and CTR-derived fields when CTR collection is enabled.
The `contact` object captures identifiers, direction, queue, and key event timestamps for a single Amazon Connect Contact. The Agent Collector emits it with every contact record; the Cloud Collector merges in Contact Trace Record (CTR)-derived fields when you enable CTR collection.
## Schema
```json theme={null}
"contact": {
"id": {
"current": "b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340",
"previous": "",
"next": ""
},
"callerId": "+61402960149",
"queueName": "Operata Prod Default Queue",
"type": "VOICE",
"direction": "Inbound",
"initiation": "INBOUND",
"durationSec": 71,
"events": {
"enqueued": "2026-05-18T10:14:22.959Z",
"connectingToAgent": "2026-05-18T10:14:43.861Z",
"muted": ["2026-05-18T10:15:06.827Z"],
"unmuted": ["2026-05-18T10:15:17.042Z"],
"onHold": ["2026-05-18T10:14:51.246Z"],
"resumed": ["2026-05-18T10:15:33.481Z"]
},
"endedBy": "Agent",
"recordingUrl": "op.performance.sampling/connect/operata-prod/2026/05/18/b0c9d4d1_20260518T1014_UTC.wav",
"connectedToAgent": "2026-05-18T10:14:43Z",
"disconnectReason": "AGENT_DISCONNECT"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `id.current` | string (UUID) | yes | Amazon Connect Contact ID for this leg. | `b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340` |
| `id.previous` | string (UUID) | no | The previous Contact ID when the Contact was transferred from another contact. Empty when there's no predecessor. | `""` |
| `id.next` | string (UUID) | no | The next Contact ID when the Contact transferred to another contact. Empty when there's no successor. | `""` |
| `callerId` | string (E.164) | no | Caller's phone number as presented to Amazon Connect. Redacted when the caller-ID privacy control is enabled. | `+61402960149` |
| `queueName` | string | no | Name of the Amazon Connect queue that handled the Contact. | `Operata Prod Default Queue` |
| `type` | string | yes | Contact type. One of `VOICE`, `CHAT`, `TASK`. | `VOICE` |
| `direction` | string | yes | Contact direction from the agent's perspective. One of `Inbound`, `Outbound`. | `Inbound` |
| `initiation` | string | no | How the Contact entered Amazon Connect, from the CTR `InitiationMethod` field. One of `INBOUND`, `OUTBOUND`, `TRANSFER`, `CALLBACK`, `API`, `QUEUE_TRANSFER`, `DISCONNECT`, `MONITOR`, `EXTERNAL_OUTBOUND`. | `INBOUND` |
| `durationSec` | integer | yes | Total Contact duration in seconds, from incoming to disconnected. | `71` |
| `events` | object | yes | Timestamps of key events in the Contact lifecycle. See [Call signalling and handling events](/docs/call-events) for the full event reference. | — |
| `endedBy` | string | yes | Which party disconnected the Contact. One of `Agent`, `Customer`, `System`. | `Agent` |
| `recordingUrl` | string | no | S3 key of the call recording, when CTR collection is enabled and the Contact was recorded. | `op.performance.sampling/connect/.../b0c9d4d1.wav` |
| `connectedToAgent` | string (ISO 8601) | no | When the Contact connected to an agent, from the CTR `ConnectedToAgentTimestamp` field. | `2026-05-18T10:14:43Z` |
| `disconnectReason` | string | no | How the Contact ended, from the CTR `DisconnectReason` field. Common values: `AGENT_DISCONNECT`, `CUSTOMER_DISCONNECT`, `THIRD_PARTY_DISCONNECT`, `TELECOM_PROBLEM`, `CONTACT_FLOW_DISCONNECT`. | `AGENT_DISCONNECT` |
# Contact Flow Log redaction schema
Source: https://docs.operata.com/docs/contact-flow-log-privacy
Field tiers, mandatory keep-list, and processing order for the Contact Flow Log redaction Lambda that runs in your AWS account.
The Contact Flow Log redaction Lambda enforces this schema. The Lambda runs
inside your AWS account, applies these rules to every event read from
CloudWatch, and ships only the surviving payload to Operata.
For the model behind the schema and the rollout procedure, see
[Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction)
and [Configure Contact Flow Log redaction](/docs/guides-configure-contact-flow-log-redaction).
This schema applies to the Contact Flow Log integration only. Lex
and CTR integrations have their own schemas.
## Field tiers
Every field in an event payload belongs to exactly one of six tiers.
| Tier | Behavior | Controlled by |
| - | - | - |
| Mandatory | Key and value transmitted unchanged. Cannot be denied, hashed, encrypted, or redacted. | Operata |
| Allow | Key and value transmitted unchanged. Customer-declared. | Customer |
| Deny | Key and value removed entirely. Operata never sees the field. | Customer |
| Encrypt | Key retained, value replaced with a hash or ciphertext. | Customer |
| Transform | Key retained, value replaced with derived or calculated data. | Customer |
| Default | Key retained, value nullified. | Customer |
The four customer-configurable tiers (Allow, Deny, Encrypt, Transform)
are mutually exclusive: any one field appears in at most one tier.
Today only the Mandatory tier is enforced end to end. Allow, Deny,
Encrypt, and Transform are accepted in the config but applied as
pass-through. Follow the [Operata changelog](/docs/changelog) for
rollout.
## Processing order
The Lambda processes every event in four passes, in order.
1. **Mandatory override.** Check each field path against the mandatory
list. If a mandatory field sits under a denied parent, retain the
parent and prune all non-mandatory siblings. Mandatory always wins.
2. **Deny.** Evaluate every remaining field path against the deny
list. Mark matched fields for removal.
3. **Allow, Encrypt, Transform.** Apply the customer-declared tiers
to remaining fields.
4. **Default nullify.** Every field not covered by the previous three
passes keeps its key, value becomes `null`.
## Path notation
Both lists use dot notation.
* `Parameters` matches the entire object at the `Parameters` key.
* `Parameters.LexVersion` matches only that subfield.
Rules apply at every depth consistently. Deny-with-mandatory-preservation
works the same at any nesting depth.
## Parent-key behavior
When a deny entry targets a parent (for example, `Parameters`) and no
mandatory entry references any child of that parent, the Lambda
removes the entire `Parameters` key. The key is absent from the
output — not an empty object.
When a deny entry targets a parent and the mandatory, allow, encrypt,
or transform list references one or more children of that parent, the
Lambda retains the parent containing only those referenced children.
Every other child is removed regardless of whether it also appears
explicitly in the deny list.
## Data flow
```text theme={null}
CloudWatch (raw Contact Flow Log)
↓
Redaction Lambda (in your AWS account)
├─ Pass 1: Mandatory override
├─ Pass 2: Deny
├─ Pass 3: Allow / Encrypt / Transform
└─ Pass 4: Default nullify
↓
Operata API (filtered payload only)
```
## Mandatory keep-list
The redaction Lambda always preserves these fields, regardless of
deny, encrypt, or transform configuration.
```text theme={null}
ContactFlowId
ContactFlowModuleType
ContactFlowName
ContactId
ErrorDetails
ErrorDetails.ErrorCode
ErrorDetails.Message
ExternalResults.error
ExternalResults.status
ExternalResults.statusCode
ExternalResults.statusMessage
Identifier
ModuleExecutionStack
Parameters.AudioPrompt
Parameters.BotAliasArn
Parameters.ContactFlowId
Parameters.FlowModuleId
Parameters.FunctionArn
Parameters.InvocationType
Parameters.LexVersion
Parameters.NoInputTimeout
Parameters.Parameter.x-amz-lex:*
Parameters.Queue
Parameters.ResponseValidation
Parameters.TextLexTimeoutSeconds
Parameters.TextToSpeechType
Parameters.Timeout
Parameters.TimeoutSeconds
Parameters.Type
Parameters.ViewResourceId
Timestamp
```
## Example
Raw log emitted by Amazon Connect:
```json theme={null}
{
"ContactFlowName": "CustomerService",
"ContactId": "abc123",
"Parameters": {
"CustomerCardNumber": "4111-1111-1111-1111",
"Queue": "billing",
"TextInput": "I want to renew"
}
}
```
Customer configuration applied by the Lambda:
```text theme={null}
Deny: Parameters.CustomerCardNumber
Allow: Parameters.Queue
Encrypt: Parameters.TextInput
```
Payload Operata receives after filtering:
```json theme={null}
{
"ContactFlowName": "CustomerService",
"ContactId": "abc123",
"Parameters": {
"Queue": "billing",
"TextInput": "8d3a2f9b2c1e..."
}
}
```
## Common configurations
| Goal | Configuration |
| - | - |
| Drop agent-notes parameters. | `Deny: Parameters.AgentNotes` |
| Keep queue names, drop customer IDs. | `Allow: Parameters.Queue` and `Deny: Parameters.CustomerId` |
| Hash phone-digit inputs, keep flow analysis. | `Encrypt: Parameters.PhoneDigitsEntered`, `Allow: Parameters.Queue, Parameters.FlowName` |
## Related
* [Configure Contact Flow Log redaction](/docs/guides-configure-contact-flow-log-redaction) — step-by-step rollout.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Lex redaction schema](/docs/lex-privacy) — the sibling schema for Amazon Lex conversation logs.
* [Install Contact Flow Logs collection](/docs/contact-flow-logs) — the integration this schema applies to.
# Install Contact Flow Logs collection
Source: https://docs.operata.com/docs/contact-flow-logs
Deploy the CloudFormation stack that streams Amazon Connect Contact Flow Logs from CloudWatch into Operata.
Deploy the CloudFormation stack so Amazon Connect contact-flow logs stream from
CloudWatch into Operata — a test contact through a logged flow appears against
its Contact Trace Record (CTR) in the Operata console within five minutes of
contact end.
## Before you start
* An [Amazon Connect integration](/docs/integrations-amazon-connect-overview)
already streaming Contact Trace Records to Operata.
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* AWS [IAM permissions](/docs/iam-policies) to deploy CloudFormation in
the region hosting your Amazon Connect instance.
* [Contact Flow Logging enabled](https://docs.aws.amazon.com/connect/latest/adminguide/contact-flow-logs.html)
on each contact flow you want to monitor. Enable it in the Amazon
Connect console under each flow's settings, or by adding a **Set
logging behavior** block to the flow.
* The CloudWatch log group name where Amazon Connect delivers your
contact-flow logs.
## Steps
### 1. Send Operata the install details
Contact [Operata Support](mailto:support@operata.com) with:
* **AWS region** hosting your Amazon Connect instance.
* **CloudWatch log group name** — for example, `/aws/connect/operata-prod`.
* **Operata Group ID** — Operata can confirm yours if you do not have
it on hand.
* **Amazon Connect instance alias** — 32 characters or fewer (for
example, `operata-prod`).
Operata returns a quick-create CloudFormation link pre-filled with
your configuration.
### 2. Open the quick-create link
Click the link to open the [CloudFormation
console](https://console.aws.amazon.com/cloudformation). Every
parameter is pre-populated except the API key.
### 3. Enter your Operata API token
Paste an Operata API token into the **API key** parameter. Create one
in the Operata console under **Settings → Config → API**. See [Authentication](/docs/api-authentication)
for the full lifecycle.
### 4. Deploy the stack
Acknowledge the IAM resource creation and click **Create stack**. The stack
reaches `CREATE_COMPLETE` in around five minutes. CloudFormation
provisions:
| Resource | Quantity | Purpose |
| - | - | - |
| [EventBridge Pipe](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) | 1 | Streams log events from CloudWatch to the Operata API destination. |
| [API Destination](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-api-destinations.html) | 1 | The Operata API endpoint. |
| [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) | 1 | Service-execution role for the Pipe. |
| [IAM Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) | 2 | CloudWatch source access and API destination invocation. |
| [Secrets Manager Secret](https://docs.aws.amazon.com/secretsmanager/) | 1 | The Operata API key. |
### 5. (Optional) Tag the new resources
Apply your cost-allocation and ownership tags. See [Tag your AWS
resources](/docs/aws-tagging).
### 6. Place a test contact
Trigger a call through a contact flow that has logging enabled. End
the contact cleanly.
## Verify
In the [Operata console](https://app.operata.io), open **Calls and
Logs → Summary** and locate the test contact. The contact-flow log
data appears within five minutes of contact end and joins the Contact
Trace Record by `ContactId`.
If nothing appears after five minutes, see [Troubleshooting](/docs/aws-troubleshooting).
## Data collected
Each event carries the raw contact-flow log entry as Amazon Connect
emits it, including:
* Contact flow name and ID.
* Contact ID (the join key against the Contact Trace Record).
* Block type and identifier for each step.
* Block results, branches taken, and any errors.
* Timestamps per flow-execution step.
* External endpoint references — Lambda ARNs, Lex bot aliases, and
similar.
For the full schema, see the
[AWS Contact Flow Logs reference](https://docs.aws.amazon.com/connect/latest/adminguide/about-contact-flow-logs.html).
## Privacy
Raw contact-flow logs can carry customer PII in flow parameters and
external-results payloads. The integration ships a redaction Lambda
that runs in your AWS account before any log leaves AWS. See:
* [Configure Contact Flow Log redaction](/docs/contact-flow-log-privacy) — the field-tier schema and the mandatory keep-list.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — the model the redaction Lambda enforces.
Contact [Operata Support](mailto:support@operata.com) for help selecting
a redaction configuration.
## Charges
All AWS service charges from this stack appear on your AWS bill. Contact
Flow Logs collection is included in every Operata plan at no additional
Operata cost. Primary cost factors:
* Amazon EventBridge Pipe event processing.
* CloudWatch Logs data transfer out of CloudWatch.
* Secrets Manager (rolled into the API destination charge).
You may incur additional [AWS data-transfer charges](https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer)
for data leaving AWS to Operata.
## Deploying alongside other stacks
The Contact Flow Logs stack runs independently of the CTR, Contact
Lens, and Amazon Lex stacks. Add or remove any stack without affecting
the others.
## Related
* [Configure Contact Flow Log redaction](/docs/contact-flow-log-privacy) — strip PII fields before logs leave AWS.
* [Install the Amazon Lex integration](/docs/lex-integration) — pair flow logs with Lex bot intent and slot data.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the Operata-side runtime that joins flow logs to contacts.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — missing log events, IAM debugging, Amazon EventBridge Pipe failures.
# Contact Trace Records
Source: https://docs.operata.com/docs/contact-trace-records
The Contact Trace Record (CTR) fields the Cloud Collector ingests from the Amazon Connect Kinesis stream and maps onto Operata contact records — account, contact, agent, and queue data.
Amazon Connect emits a Contact Trace Record (CTR) for every Contact. The Cloud Collector reads CTRs from your Amazon Connect Kinesis stream, merges them with Agent Collector telemetry, and ships the result to Operata. CTR collection is optional and requires the [CTR installation](/docs/ctr-installation).
Use [Privacy Controls](/docs/api-data-redaction) to redact CTR fields at ingest. AWS publishes the full CTR schema in the [Amazon Connect CTR data model](https://docs.aws.amazon.com/connect/latest/adminguide/ctr-data-model.html).
## Schema
CTR fields land inside the top-level `accountProperties`, `contact`, `serviceAgent`, and `queue` objects on the Operata record. The CTR-derived projection looks like this:
```json theme={null}
{
"accountProperties": {
"service": "Amazon Connect",
"serviceAccountNumber": "012345678910",
"serviceInstanceId": "62e2306a-aaaa-bbbb-cccc-5a1508195aa5",
"region": "ap-southeast-2"
},
"contact": {
"id": {
"current": "b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340",
"previous": "",
"next": ""
},
"type": "VOICE",
"direction": "Inbound",
"initiation": "INBOUND",
"callerId": "+61402960149",
"recordingUrl": "op.performance.sampling/connect/operata-prod/2026/05/18/b0c9d4d1_20260518T1014_UTC.wav",
"connectedToAgent": "2026-05-18T10:14:43Z",
"disconnectReason": "AGENT_DISCONNECT",
"durationSec": 71
},
"serviceAgent": {
"serviceId": "23aca65c-7bc8-4ead-b9e5-9df15f06b8af",
"username": "agent_42",
"hierarchyGroups": ["Sydney", "Tier 1"]
},
"queue": {
"arn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/queue/8092a344-02bb-4fba-ac74-2176c5aa0afe",
"name": "Operata Prod Default Queue",
"duration": 21
}
}
```
## Fields
Every field below comes from the AWS CTR. Operata renames a small number of them for consistency with the rest of the data model; the **CTR source** column shows the original AWS field name.
| Name | Type | Required | Description | CTR source |
| - | - | - | - | - |
| `accountProperties.service` | string | yes | Always `Amazon Connect`. | — |
| `accountProperties.serviceAccountNumber` | string | yes | AWS account ID that owns the Amazon Connect instance. | `AWSAccountId` |
| `accountProperties.serviceInstanceId` | string (UUID) | yes | Amazon Connect instance ID. | `InstanceARN` (parsed) |
| `accountProperties.region` | string | yes | AWS region the instance runs in. | `InstanceARN` (parsed) |
| `contact.id.current` | string (UUID) | yes | Contact ID for this leg. | `ContactId` |
| `contact.id.previous` | string (UUID) | no | Previous Contact ID when the Contact was transferred in. | `PreviousContactId` |
| `contact.id.next` | string (UUID) | no | Next Contact ID when the Contact was transferred out. | `NextContactId` |
| `contact.type` | string | yes | One of `VOICE`, `CHAT`, `TASK`. | `Channel` |
| `contact.direction` | string | yes | Contact direction from the agent's perspective. | derived from `InitiationMethod` |
| `contact.initiation` | string | yes | How the Contact entered Amazon Connect. One of `INBOUND`, `OUTBOUND`, `TRANSFER`, `CALLBACK`, `API`, `QUEUE_TRANSFER`, `DISCONNECT`, `MONITOR`, `EXTERNAL_OUTBOUND`. | `InitiationMethod` |
| `contact.callerId` | string (E.164) | no | Caller's phone number. Redacted when the caller-ID privacy control is enabled. | `CustomerEndpoint.Address` |
| `contact.systemEndpoint` | string (E.164) | no | The Amazon Connect DID the caller dialled, for inbound Contacts. | `SystemEndpoint.Address` |
| `contact.recordingUrl` | string | no | S3 key of the call recording. | `Recording.Location` |
| `contact.recordingStatus` | string | no | Recording status. One of `AVAILABLE`, `DELETED`, `FAILED`. | `Recording.Status` |
| `contact.initiationTime` | string (ISO 8601) | yes | When the Contact entered Amazon Connect. | `InitiationTimestamp` |
| `contact.connectedToAgent` | string (ISO 8601) | no | When the Contact connected to an agent. | `ConnectedToAgentTimestamp` |
| `contact.connectedToSystem` | string (ISO 8601) | no | When the Contact connected to Amazon Connect. | `ConnectedToSystemTimestamp` |
| `contact.disconnectTime` | string (ISO 8601) | yes | When the Contact disconnected. | `DisconnectTimestamp` |
| `contact.disconnectReason` | string | no | How the Contact ended. Common values: `AGENT_DISCONNECT`, `CUSTOMER_DISCONNECT`, `THIRD_PARTY_DISCONNECT`, `TELECOM_PROBLEM`, `CONTACT_FLOW_DISCONNECT`, `OTHER`, `EXPIRED`, `API`. | `DisconnectReason` |
| `contact.durationSec` | integer | yes | Total Contact duration in seconds. | derived |
| `contact.scheduledTime` | string (ISO 8601) | no | Scheduled Contact time, for callback Contacts. | `ScheduledTimestamp` |
| `contact.lastUpdateTime` | string (ISO 8601) | yes | When AWS last updated the CTR. | `LastUpdateTimestamp` |
| `contact.attributes` | object | no | Custom contact attributes set in your contact flow. Key-value pairs of strings. | `Attributes` |
| `serviceAgent.serviceId` | string (UUID) | no | Amazon Connect agent ID. | `AgentInfo.Id` |
| `serviceAgent.username` | string | no | Agent username. | `AgentInfo.Username` (from Connect user lookup) |
| `serviceAgent.hierarchyGroups` | string\[] | no | Agent hierarchy-group path. | `AgentInfo.HierarchyGroups` |
| `serviceAgent.afterContactWorkDuration` | integer | no | Agent's after-contact-work time in seconds. | `AgentInfo.AfterContactWorkDuration` |
| `serviceAgent.agentInteractionDuration` | integer | no | Time in seconds the agent was interacting with the Contact. | `AgentInfo.AgentInteractionDuration` |
| `serviceAgent.customerHoldDuration` | integer | no | Time in seconds the customer was on hold. | `AgentInfo.CustomerHoldDuration` |
| `serviceAgent.longestHoldDuration` | integer | no | Longest single hold in seconds. | `AgentInfo.LongestHoldDuration` |
| `serviceAgent.numberOfHolds` | integer | no | How many times the agent placed the customer on hold. | `AgentInfo.NumberOfHolds` |
| `serviceAgent.connectionAttempts` | integer | no | How many times Amazon Connect tried to reach the agent. | `AgentInfo.AgentConnectionAttempts` |
| `queue.arn` | string (ARN) | no | Amazon Connect queue ARN. | `Queue.ARN` |
| `queue.name` | string | no | Queue name. | `Queue.Name` (resolved from ARN) |
| `queue.duration` | integer | no | Time in seconds the Contact spent in queue. | `Queue.Duration` |
| `queue.enqueueTime` | string (ISO 8601) | no | When the Contact entered the queue. | `Queue.EnqueueTimestamp` |
| `queue.disconnectTime` | string (ISO 8601) | no | When the Contact left the queue. | `Queue.DequeueTimestamp` |
For the original CTR field reference (including fields Operata does not surface, like `MediaStreams` or `TransferCompletedTimestamp`), see the [Amazon Connect CTR data model](https://docs.aws.amazon.com/connect/latest/adminguide/ctr-data-model.html).
# Conversational analytics for Amazon Connect
Source: https://docs.operata.com/docs/conversational-analytics
Deploy two CloudFormation stacks to stream Amazon Connect conversational analytics into Operata alongside your existing Contact Trace Record data.
Deploy two CloudFormation stacks to bring Amazon Connect conversational analytics — formerly Contact Lens — into Operata. You get sentiment scores, talk ratios, keyword detections, and rule-triggered events, correlated with the Contact Trace Records (CTRs) the Cloud Collector already streams.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role.
* An [Amazon Connect integration](/docs/integrations-amazon-connect-overview)
already streaming Contact Trace Records to Operata. Conversational
analytics layers onto the same data path.
* [Conversational analytics enabled](https://aws.amazon.com/products/connect/customer/conversational-analytics/) in
your Amazon Connect instance and on the contact flows you want to
analyze.
* AWS [IAM permissions](/docs/iam-policies) to deploy CloudFormation in
the region hosting your Amazon Connect instance.
* A current Operata subscription that includes Playbook 9 (Experience
Insights).
The summary includes the conversation transcript: each utterance's
text, speaker, and sentiment. By default Operata receives the
unredacted analysis files. To send only Amazon Connect's PII-redacted
output, deploy the Contact Lens Summary stack with
`processRedactedOnly` set to `true`. Transcript lines still arrive,
with personal data masked. Call recordings never leave your AWS
account.
## Steps
### 1. Pick which stack to deploy
Operata ships two independent CloudFormation stacks for conversational
analytics. Deploy one or both.
| Stack | What it collects | Use when |
| - | - | - |
| Contact Lens Summary | Sentiment scores, words-per-minute, talk and silence ratios, keyword detection, rule outcomes (real-time and post-call). | You want post-call analytics on every contact. |
| Operata Contact Lens Rules | Events from Operata-defined detection rules — for example, escalation phrases or compliance keywords. | You want pre-built rule packs without writing your own rules. |
Both stacks deliver into the same Operata account and correlate with
the Contact Trace Records the Cloud Collector already ships.
### 2. Send Operata the install details
Operata builds custom CloudFormation templates once you provide:
* **`ConnectRecordingsBucketName`** — the S3 bucket holding your
Amazon Connect call recordings. Use the bucket name only, up to the
first `/`. Find it in the AWS console under **Amazon Connect → Data
storage**.
* **Lambda VPC details** — the VPC ID and private subnet IDs the
analytics Lambda needs. Skip this if you do not require VPC
deployment.
* **Amazon Connect instance ARN** — for example,
`arn:aws:connect:ap-southeast-2:083560123456:instance/8f3b9a12-2b6b-4a07-8d33-c6f7b21a4ab0`.
Operata responds with two quick-create links and your Operata Group ID.
### 3. Deploy the Summary stack
Open the Summary quick-create link Operata sent. Paste your Operata API
token into the **API key** parameter — create one under **Settings →
Config → API** in the Operata console and label it `CL_Integration`.
Acknowledge the IAM resource creation, then **Create stack**.
The stack takes around five minutes. CloudFormation creates the Kinesis
stream that backs the integration, the EventBridge Pipe, the
S3-to-Kinesis processor Lambda, the API destination, the Secrets
Manager secret, and the IAM roles. See [IAM policies](/docs/iam-policies)
for the role contract.
### 4. Deploy the Operata Rules stack
If you also want the Operata rule pack, open the second quick-create
link. The Rules stack creates one EventBridge Rule that watches for
conversational analytics events whose `actionName` is prefixed with
`operata_` and forwards them to your Operata account.
Any rule you author later whose name starts with `operata_` flows
through this same EventBridge Rule — no additional deploy needed.
### 5. Place a test call
Make or receive a call through your Amazon Connect CCP. **Close the
contact** when the call ends — summary data is only generated on close.
Confirm the [Agent Collector](/docs/collector-overview)
extension is installed in the agent's browser and that the CCP URL
matches the instance you installed the stacks against.
## Verify
In the [Operata console](https://app.operata.io), open **Playbook 9
(Experience Insights)**. Your test contact appears with sentiment,
words-per-minute, and any triggered rules within 15 minutes
of contact close.
If nothing appears after 15 minutes, check the EventBridge Pipe and the
S3-to-Kinesis Lambda in CloudWatch Logs, then work through
[Troubleshooting](/docs/aws-troubleshooting).
## Related
* [Install conversational analytics collection](/docs/conversational-analytics-installation) — the per-stack deployment runbook with parameters and post-deploy checks.
* [Conversational analytics charges](/docs/conversational-analytics-charges) — the AWS cost components and an example bill at 1 million contacts per month.
* [Conversational analytics data reference](/docs/conversational-analytics-data) — the fields Operata stores for each contact.
* [Tag your AWS resources](/docs/aws-tagging) — apply cost-allocation tags to the analytics stacks.
# Estimate conversational analytics integration charges
Source: https://docs.operata.com/docs/conversational-analytics-charges
AWS cost components for the conversational analytics CloudFormation stacks, with worked examples at 1 million contacts per month.
The conversational analytics integration adds usage across four AWS services — all charges land on your AWS bill, not Operata's. Use the worked examples below to forecast your monthly cost before you deploy.
## What you pay for
| Service | Cost driver | Notes |
| - | - | - |
| EventBridge Pipes | Per request and per API destination invocation. | The dominant cost factor at scale. See [EventBridge pricing](https://aws.amazon.com/eventbridge/pricing/). |
| Lambda | Invocation count and execution duration. | The S3-to-Kinesis processor Lambda. Memory at 128 MB, average duration around 2 ms. |
| Kinesis Data Streams | Shard hours and PUT payload units. | One stream, sized for your contact volume. |
| Secrets Manager | One secret per stack. | The Operata API key. The cost is included in the API destination charge — see below. |
You also pay [AWS data-transfer charges](https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer)
for data leaving AWS to the Operata API. Event payloads are typically
under 10 KB.
## EventBridge example
For 1 million contacts per month in `ap-southeast-2` (prices vary by region), with the
EventBridge Pipe reading from a Kinesis source and forwarding to the
Operata API destination:
* Requests = 1,000,000.
* EventBridge requests cost = 1M × $0.40 per million = **$0.40\*\*.
* API destination cost = 1M × $0.24 per million = **$0.24\*\*.
**Total monthly EventBridge cost: USD \$0.64.**
## Lambda example
For the same 1 million contacts per month, with the S3-to-Kinesis
processor Lambda transforming each event:
* Invocations = 1,000,000.
* Memory = 128 MB.
* Average duration = 2 ms.
**Total monthly Lambda cost: USD \$0.20.**
## Secrets Manager
CloudFormation creates one secret per stack to hold the Operata API
key, prefixed with `events`. AWS bundles the storage cost of secrets
created for EventBridge API destinations into the API destination
invocation charge, so no separate Secrets Manager line item appears.
See [API destinations](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-api-destinations.html)
for the pricing detail.
Data-transfer-out costs are separate. At 1 million contacts per
month and event payloads under 10 KB, expect under \$1 per month in
data-transfer charges. Validate against your own egress rates.
## Verify the cost in AWS
Once the stack runs in production for a full billing cycle, confirm
the actual cost in **AWS Cost Explorer**:
1. Filter by the tags applied during deploy (see [AWS tagging](/docs/aws-tagging)).
2. Group by service to see the EventBridge, Lambda, and Kinesis
line items separately.
3. Compare against the worked examples above. Wide deltas usually
indicate a misconfigured logging level on the Lambda or a
higher-than-expected contact volume.
## Related
* [Install conversational analytics collection](/docs/conversational-analytics-installation) — the deployment runbook.
* [Tag your AWS resources](/docs/aws-tagging) — apply tags so Cost Explorer can break the bill out.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — debug runaway Lambda invocations or stalled Pipes.
# Conversational analytics data
Source: https://docs.operata.com/docs/conversational-analytics-data
The Amazon Connect conversational analytics fields Operata captures — real-time events, post-call events, and post-processing summaries delivered by the Cloud Collector.
Conversational analytics is Amazon Connect's speech-analytics feature, formerly Contact Lens: it scores sentiment, detects categories, and produces transcript-level analytics. The Cloud Collector ingests three conversational analytics payloads per Contact — a real-time event (per rule match), a post-call event (when the Contact ends), and a summary (when AWS finishes processing). Collection is optional and requires the [conversational analytics integration](/docs/conversational-analytics-installation).
The summary payload below includes the conversation transcript: each utterance's
text, speaker, and sentiment. By default Operata receives the
unredacted analysis files. To send only Amazon Connect's PII-redacted
output, deploy the Contact Lens Summary stack with
`processRedactedOnly` set to `true`. Transcript lines still arrive,
with personal data masked. Call recordings never leave your AWS
account.
## Schema
Amazon Connect emits three distinct conversational analytics payload shapes. The Cloud Collector forwards each to Operata as it arrives.
### Real-time event
A real-time event fires every time a conversational analytics rule matches during an active Contact.
```json theme={null}
{
"groupId": "a28453f9-abab-cdcd-efef-84d9e67ac297",
"data": {
"account": "012345678910",
"detail": {
"actionName": "TestRealTimeEvent",
"agentArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/agent/af6342c3-aaaa-bbbb-cccc-1871e5844c29",
"contactArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/contact/f5aece6d-aaaa-bbbb-cccc-232fefce309a",
"instanceArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5",
"queueArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/queue/af6342c3-aaaa-bbbb-cccc-1871e5844c29",
"ruleName": "realTimeTest",
"version": "1.0"
},
"detail-type": "Contact Lens Realtime Rules Matched",
"id": "5ea9dae1-aaaa-bbbb-cccc-3475b9b51465",
"region": "ap-southeast-2",
"resources": [],
"source": "aws.connect",
"time": "2026-05-18T10:14:33Z",
"version": "0"
}
}
```
### Post-call event
A post-call event fires once per matched rule after the Contact disconnects.
```json theme={null}
{
"groupId": "a28453f9-abab-cdcd-efef-84d9e67ac297",
"data": {
"version": "0",
"id": "33ad0712-aaaa-bbbb-cccc-0e7dd9b77c0a",
"detail-type": "Contact Lens Post Call Rules Matched",
"source": "aws.connect",
"account": "012345678910",
"time": "2026-05-18T10:27:11Z",
"region": "ap-southeast-2",
"resources": [],
"detail": {
"ruleName": "postCallTest",
"actionName": "testpostcall",
"instanceArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5",
"version": "1.0",
"contactArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/contact/b21e4aae-aaaa-bbbb-cccc-3c517e3dc922",
"agentArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/agent/af6342c3-aaaa-bbbb-cccc-1871e5844c29",
"queueArn": "arn:aws:connect:ap-southeast-2:012345678910:instance/62e2306a-aaaa-bbbb-cccc-5a1508195aa5/queue/8092a344-aaaa-bbbb-cccc-2176c5aa0afe"
}
}
}
```
### Summary
A summary payload arrives once conversational analytics finishes processing the Contact (typically within 15 minutes of disconnect).
```json theme={null}
{
"AccountId": "012345678910",
"Categories": {
"MatchedCategories": [],
"MatchedDetails": {}
},
"Channel": "VOICE",
"ContentMetadata": { "Output": "Redacted" },
"ConversationCharacteristics": {
"Interruptions": {
"InterruptionsByInterrupter": {},
"TotalCount": 0,
"TotalTimeMillis": 0
},
"NonTalkTime": {
"Instances": [],
"TotalTimeMillis": 0
},
"Sentiment": {
"OverallSentiment": { "CUSTOMER": 0 },
"SentimentByPeriod": {
"QUARTER": {
"CUSTOMER": [
{ "BeginOffsetMillis": 0, "EndOffsetMillis": 3743, "Score": 0 }
]
}
}
},
"TalkSpeed": {
"DetailsByParticipant": {
"AGENT": { "AverageWordsPerMinute": 0 },
"CUSTOMER": { "AverageWordsPerMinute": 138 }
}
},
"TalkTime": {
"DetailsByParticipant": {
"AGENT": { "TotalTimeMillis": 0 },
"CUSTOMER": { "TotalTimeMillis": 435 }
},
"TotalTimeMillis": 435
},
"TotalConversationDurationMillis": 14975
},
"CustomerMetadata": {
"InputS3Uri": "s3://op.performance.sampling/connect/operata-prod/2026/05/18/139fb487_20260518T1014_UTC.wav",
"ContactId": "139fb487-aaaa-bbbb-cccc-ea068b242bbc",
"InstanceId": "62e2306a-aaaa-bbbb-cccc-5a1508195aa5"
},
"CustomModels": [],
"JobStatus": "COMPLETED",
"LanguageCode": "en-AU",
"Participants": [
{ "ParticipantId": "CUSTOMER", "ParticipantRole": "CUSTOMER" },
{ "ParticipantId": "AGENT", "ParticipantRole": "AGENT" }
],
"Transcript": [
{
"BeginOffsetMillis": 14540,
"Content": "My account number is [PII].",
"EndOffsetMillis": 14975,
"Id": "f483ae5e-aaaa-bbbb-cccc-f1fe3b1fead3",
"LoudnessScore": [83.78],
"ParticipantId": "CUSTOMER",
"Redaction": {
"RedactedTimestamps": [
{ "BeginOffsetMillis": 14800, "EndOffsetMillis": 14975 }
]
},
"Sentiment": "NEUTRAL"
}
],
"Version": "1.1.0"
}
```
## Fields
### Real-time event and post-call event
Both events share the same outer envelope. The description column flags any per-event differences.
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `groupId` | string (UUID) | yes | Operata Group ID this event belongs to. | `a28453f9-abab-cdcd-efef-84d9e67ac297` |
| `data.account` | string | yes | AWS account ID that owns the Amazon Connect instance. | `012345678910` |
| `data.detail.actionName` | string | yes | The conversational analytics rule action name configured in your Amazon Connect instance. | `TestRealTimeEvent` |
| `data.detail.agentArn` | string (ARN) | yes | ARN of the agent assigned to the Contact at the moment the rule matched. | `arn:aws:connect:...:agent/af6342c3-...` |
| `data.detail.contactArn` | string (ARN) | yes | ARN of the Amazon Connect Contact. | `arn:aws:connect:...:contact/f5aece6d-...` |
| `data.detail.instanceArn` | string (ARN) | yes | ARN of the Amazon Connect instance. | `arn:aws:connect:...:instance/62e2306a-...` |
| `data.detail.queueArn` | string (ARN) | yes | ARN of the queue handling the Contact. | `arn:aws:connect:...:queue/af6342c3-...` |
| `data.detail.ruleName` | string | yes | The conversational analytics rule name that matched. | `realTimeTest` |
| `data.detail.version` | string | yes | Conversational analytics rule schema version. | `1.0` |
| `data.detail-type` | string | yes | Event type. `Contact Lens Realtime Rules Matched` for real-time events, `Contact Lens Post Call Rules Matched` for post-call events. | `Contact Lens Realtime Rules Matched` |
| `data.id` | string (UUID) | yes | Unique ID of the EventBridge event. | `5ea9dae1-aaaa-bbbb-cccc-3475b9b51465` |
| `data.region` | string | yes | AWS region the Amazon Connect instance runs in. | `ap-southeast-2` |
| `data.resources` | string\[] | yes | EventBridge resources array. Empty for conversational analytics events. | `[]` |
| `data.source` | string | yes | EventBridge event source. Always `aws.connect`. | `aws.connect` |
| `data.time` | string (ISO 8601) | yes | When AWS emitted the event. UTC. | `2026-05-18T10:14:33Z` |
| `data.version` | string | yes | EventBridge envelope version. | `0` |
| `contactId` | string (UUID) | no | Operata-derived Contact ID. Present only when the Cloud Collector can match the event to an existing Contact record; absent on standalone real-time events that arrive before the Contact record. | `b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340` |
| `eventId` | string (UUID) | no | Operata-assigned event identifier. Present on post-call events. | `33ad0712-aaaa-bbbb-cccc-0e7dd9b77c0a` |
| `timestamp` | string (ISO 8601) | no | Operata-assigned ingest timestamp. Present once the Cloud Collector receives the event. | `2026-05-18T10:14:34Z` |
### Summary
The summary payload mirrors the [AWS conversational analytics output schema](https://docs.aws.amazon.com/connect/latest/adminguide/contact-lens-output.html).
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `AccountId` | string | yes | AWS account ID that owns the Amazon Connect instance. | `012345678910` |
| `Categories.MatchedCategories` | string\[] | yes | Category rules matched during the Contact. Empty when no rule matched. | `["BillingComplaint"]` |
| `Categories.MatchedDetails` | object | yes | For each matched category, the points in the transcript where the match occurred. Keyed by category name; each value lists `PointsOfInterest.BeginOffsetMillis` and `EndOffsetMillis`. | `{}` |
| `Channel` | string | yes | Contact channel. One of `VOICE`, `CHAT`. | `VOICE` |
| `ContentMetadata.Output` | string | yes | Whether the analysis output is raw or redacted. One of `Raw`, `Redacted`. Set per conversational analytics configuration. | `Redacted` |
| `ConversationCharacteristics.Interruptions.InterruptionsByInterrupter` | object | yes | Per-participant interruption breakdown. Keys are participant roles (`AGENT`, `CUSTOMER`), values are lists of interruption instances with offset and duration. | `{}` |
| `ConversationCharacteristics.Interruptions.TotalCount` | integer | yes | Total number of interruptions across the Contact. | `0` |
| `ConversationCharacteristics.Interruptions.TotalTimeMillis` | integer | yes | Total interruption time in milliseconds. | `0` |
| `ConversationCharacteristics.NonTalkTime.Instances` | object\[] | yes | List of non-talk segments. Each entry has `BeginOffsetMillis`, `EndOffsetMillis`, and `DurationMillis`. | `[]` |
| `ConversationCharacteristics.NonTalkTime.TotalTimeMillis` | integer | yes | Total non-talk time in milliseconds. | `0` |
| `ConversationCharacteristics.Sentiment.OverallSentiment.CUSTOMER` | number | yes | Customer overall sentiment score across the Contact, in the range -5 (most negative) to +5 (most positive). | `0` |
| `ConversationCharacteristics.Sentiment.SentimentByPeriod.QUARTER.CUSTOMER[].BeginOffsetMillis` | integer | yes | Start of this conversation quarter in milliseconds from Contact start. | `0` |
| `ConversationCharacteristics.Sentiment.SentimentByPeriod.QUARTER.CUSTOMER[].EndOffsetMillis` | integer | yes | End of this conversation quarter in milliseconds from Contact start. | `3743` |
| `ConversationCharacteristics.Sentiment.SentimentByPeriod.QUARTER.CUSTOMER[].Score` | number | yes | Customer sentiment score for this quarter, in the range -5 to +5. | `0` |
| `ConversationCharacteristics.TalkSpeed.DetailsByParticipant.AGENT.AverageWordsPerMinute` | integer | yes | Agent's average speaking rate in words per minute. | `0` |
| `ConversationCharacteristics.TalkSpeed.DetailsByParticipant.CUSTOMER.AverageWordsPerMinute` | integer | yes | Customer's average speaking rate in words per minute. | `138` |
| `ConversationCharacteristics.TalkTime.DetailsByParticipant.AGENT.TotalTimeMillis` | integer | yes | Total time the agent was speaking, in milliseconds. | `0` |
| `ConversationCharacteristics.TalkTime.DetailsByParticipant.CUSTOMER.TotalTimeMillis` | integer | yes | Total time the customer was speaking, in milliseconds. | `435` |
| `ConversationCharacteristics.TalkTime.TotalTimeMillis` | integer | yes | Total talk time across both participants, in milliseconds. | `435` |
| `ConversationCharacteristics.TotalConversationDurationMillis` | integer | yes | Total Contact duration in milliseconds, as measured by Amazon Connect. | `14975` |
| `CustomerMetadata.InputS3Uri` | string | yes | S3 URI of the input recording that was analyzed. | `s3://op.performance.sampling/.../139fb487.wav` |
| `CustomerMetadata.ContactId` | string (UUID) | yes | Amazon Connect Contact ID this summary applies to. | `139fb487-aaaa-bbbb-cccc-ea068b242bbc` |
| `CustomerMetadata.InstanceId` | string (UUID) | yes | Amazon Connect instance ID. | `62e2306a-aaaa-bbbb-cccc-5a1508195aa5` |
| `CustomModels` | object\[] | yes | Custom-vocabulary models applied during analysis. Empty when none are configured. | `[]` |
| `JobStatus` | string | yes | Conversational analytics job status. One of `COMPLETED`, `FAILED`, `PARTIAL_SUCCESS`. | `COMPLETED` |
| `LanguageCode` | string (BCP 47) | yes | Language used to transcribe and analyze the Contact. | `en-AU` |
| `Participants[].ParticipantId` | string | yes | Participant role identifier. One of `CUSTOMER`, `AGENT`, `SYSTEM`. | `CUSTOMER` |
| `Participants[].ParticipantRole` | string | yes | Participant role. One of `CUSTOMER`, `AGENT`, `SYSTEM`. | `CUSTOMER` |
| `Transcript[].BeginOffsetMillis` | integer | yes | Start of this utterance in milliseconds from Contact start. | `14540` |
| `Transcript[].Content` | string | yes | Transcribed text for this utterance. In redacted output, personal data is replaced with `[PII]`. | `My account number is [PII].` |
| `Transcript[].EndOffsetMillis` | integer | yes | End of this utterance in milliseconds from Contact start. | `14975` |
| `Transcript[].Id` | string (UUID) | yes | Unique ID of this transcript entry. | `f483ae5e-aaaa-bbbb-cccc-f1fe3b1fead3` |
| `Transcript[].LoudnessScore` | number\[] | yes | Loudness samples (in decibels) measured across the utterance window. | `[83.78]` |
| `Transcript[].ParticipantId` | string | yes | Which participant spoke this utterance. | `CUSTOMER` |
| `Transcript[].Redaction.RedactedTimestamps` | object\[] | no | Present in redacted output only. The `BeginOffsetMillis` and `EndOffsetMillis` of each redacted span. | `[{ "BeginOffsetMillis": 14800, "EndOffsetMillis": 14975 }]` |
| `Transcript[].Sentiment` | string | yes | Sentiment classification for this utterance. One of `POSITIVE`, `NEUTRAL`, `NEGATIVE`, `MIXED`. | `NEUTRAL` |
| `Version` | string | yes | Conversational analytics output schema version. | `1.1.0` |
| `groupId` | string (UUID) | no | Operata Group ID. Operata appends this on ingest; not present in the raw AWS payload. | `a28453f9-abab-cdcd-efef-84d9e67ac297` |
| `eventId` | string (UUID) | no | Operata-assigned event identifier. Operata appends this on ingest. | `33ad0712-aaaa-bbbb-cccc-0e7dd9b77c0a` |
| `contactId` | string (UUID) | no | Operata-derived Contact ID matching `CustomerMetadata.ContactId`. Operata appends this on ingest. | `139fb487-aaaa-bbbb-cccc-ea068b242bbc` |
| `timestamp` | string (ISO 8601) | no | Operata-assigned ingest timestamp. | `2026-05-18T10:30:14Z` |
For the canonical output schema, see the [AWS conversational analytics documentation](https://docs.aws.amazon.com/connect/latest/adminguide/contact-lens-output.html). For the upstream Customer Journey Trace concept, see [Customer Journey Trace](/docs/concepts-customer-journey-trace).
# Install conversational analytics collection
Source: https://docs.operata.com/docs/conversational-analytics-installation
Deploy the Contact Lens Summary and Operata Rules CloudFormation stacks and confirm conversational analytics data appears in Operata within 15 minutes.
Deploy the Contact Lens Summary stack — and, optionally, the Operata Rules stack — so Amazon Connect conversational analytics data flows into Operata and appear in Playbook 9 (Experience Insights) within 15 minutes of contact close.
## Before you start
* An [Amazon Connect integration](/docs/integrations-amazon-connect-overview)
already streaming Contact Trace Records to Operata.
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* [Conversational analytics enabled](https://aws.amazon.com/products/connect/customer/conversational-analytics/)
on the contact flows you want to analyze.
* AWS [IAM permissions](/docs/iam-policies) to deploy CloudFormation,
or a CloudFormation service role as documented in the
[AWS guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-servicerole.html).
* The [Conversational analytics overview](/docs/conversational-analytics) read end to end — this
page is the deployment runbook for what that page describes.
## Steps
### 1. Send Operata the three install details
Operata returns two quick-create CloudFormation links once you send:
* **`ConnectRecordingsBucketName`** — the call-recordings S3 bucket,
bucket name only. For example, send `call.recordings`, not
`call.recordings/connect/acme-prod`.
* **Lambda VPC details** — VPC ID and private subnet IDs. Skip this if
you do not require VPC deployment.
* **Amazon Connect instance ARN** — for example,
`arn:aws:connect:ap-southeast-2:083560123456:instance/8f3b9a12-2b6b-4a07-8d33-c6f7b21a4ab0`.
If you encrypt call recordings with a customer-managed KMS key, the
conversational analytics Lambda needs allow-list access. See [KMS encryption](/docs/kms-encryption).
### 2. Deploy the Contact Lens Summary stack
Open the Summary quick-create link Operata sent. AWS opens the
[CloudFormation console](https://console.aws.amazon.com/cloudformation)
with every parameter pre-filled except the API key.
Paste an Operata API token into the **API key** parameter. Create the
token in the Operata console under **Settings → Config → API** and
label it `CL_Integration`. See [Authentication](/docs/api-authentication)
for the full token lifecycle.
Acknowledge the IAM resource creation, then **Create stack**. The stack
reaches `CREATE_COMPLETE` in around five minutes.
### 3. (Optional) Deploy the Operata Rules stack
To get the Operata pre-built rule pack, open the second quick-create
link and deploy the same way. The Rules stack creates one EventBridge
Rule that captures any conversational analytics event whose `actionName` starts with
`operata_` and forwards it to your Operata account.
Any conversational analytics rule you author later whose name starts with
`operata_` flows through this same EventBridge Rule — no additional
deploy needed.
### 4. Place a test contact
Make or receive a call through your Amazon Connect CCP. **Close the
contact** when the call ends — conversational analytics summary data is only
generated on contact close. Confirm:
* The [Agent Collector](/docs/collector-overview) extension
is installed in the agent's browser.
* The CCP URL matches the Amazon Connect instance you deployed the
stack against.
### 5. (Optional) Tag the new resources
Apply your cost-allocation and ownership tags. See [Tag your AWS
resources](/docs/aws-tagging) for the tag set Operata expects on the
deployed stack.
## Verify
In the [Operata console](https://app.operata.io), open **Playbook 9
(Experience Insights)** and find your test contact.
* The contact shows sentiment scores, words-per-minute, and talk and
silence ratios within 15 minutes of contact close.
* If you deployed the Rules stack, any triggered Operata rule appears
on the contact's timeline.
Conversational analytics summary data can take up to 15 minutes to appear because
Amazon Connect writes the summary file to S3 after post-call analysis
completes. If nothing appears after 15 minutes, see [Troubleshooting](/docs/aws-troubleshooting).
## Related
* [Conversational analytics charges](/docs/conversational-analytics-charges) — the AWS cost components and an example bill.
* [Conversational analytics data reference](/docs/conversational-analytics-data) — the fields Operata stores for each contact.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the runtime the conversational analytics stacks deliver into.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — missing summaries, S3 trigger failures, and IAM debugging.
# Monitor
Source: https://docs.operata.com/docs/core-overview
Core is the CX telemetry pipeline. It ingests signals, correlates them to a contact, applies redaction and validation, stores the result as observations, and derives insights and journeys from them.
Core is the CX telemetry pipeline. It turns the signals [Collect](/docs/signal-overview) collects into a single, queryable record of what happened on every contact.
## How it works
Core runs four steps on every signal it receives.
1. **Ingest** — accept the signal from the collector that emitted it.
2. **Correlate** — attach it to the [contact](/docs/concepts-contacts-and-interactions) it belongs to: `Contact` in Amazon Connect, `Interaction` in NICE CXOne, `Conversation` in Genesys Cloud.
3. **Redact and validate** — apply your account's policy and reject what does not conform.
4. **Persist** — store the result as an [observation](/docs/concepts-signals-and-observations).
The [insight engine](/docs/concepts-insights) then reads the observations on each contact and writes an [insight](/docs/insights-overview) when a known pattern matches — audio one-way, packet loss, agent inactivity, and the rest of the [insights catalog](/docs/insights-catalog). [Customer Journey Trace](/docs/concepts-customer-journey-trace) sits above contacts: when one customer crosses more than one platform, each platform's contact is one span of a single journey.
## Why Core splits signals from observations
The split isolates the wire format from the storage format. Redaction, deduplication, late-arrival reconciliation, and per-account validation all happen between the two, so the value a collector reports is not the value a consumer reads. CTRs can land 5–20 minutes after a contact ends. Storing observations means a query returns a coherent partial view that fills in as more signals arrive, instead of a stream of half-correlated events.
It also means Core can add a new collector without changing anything above it. A new platform emits signals in its own shape, and the observations that reach [Assure](/docs/surface-overview), [Tenor](/docs/guides-mcp-intro), and the [API](/docs/api-getting-started) keep the shape consumers already build against.
## Related
* [Signals and observations](/docs/concepts-signals-and-observations) — what each collector emits and how Operata stores it.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the per-platform record observations attach to.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how Operata links contacts across platforms.
* [Insights](/docs/concepts-insights) — the named detections Operata derives from observations.
* [How Operata works](/docs/get-started-architecture) — the full layer map.
# Install CTR collection for Amazon Connect
Source: https://docs.operata.com/docs/ctr-installation
Deploy the Cloud Collector CloudFormation stack to stream Amazon Connect Contact Trace Records into Operata.
Deploy the Cloud Collector CloudFormation stack so your Amazon Connect instance
streams Contact Trace Records (CTRs) to Operata — a test contact you place
appears in the Operata console within five minutes of contact end.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* An AWS account with the [IAM permissions](/docs/iam-policies)
required to deploy CloudFormation in your Amazon Connect region.
* An Amazon Connect instance with CTRs enabled to a Kinesis stream.
Firehose-only setups need a Kinesis stream first; see
[Why Kinesis Streams, not Firehose](/docs/concepts-why-kinesis-streams).
* Familiarity with the [Cloud Collector](/docs/concepts-cloud-collector)
data path.
## Steps
### 1. Send Operata the install details
Operata generates a custom CloudFormation template per integration.
Send Operata Support these three values:
* **CTR Kinesis stream ARN** — for example,
`arn:aws:kinesis:ap-southeast-2:083560123456:stream/Connect_CTR_Prod`.
* **Amazon Connect instance alias** — 32 characters or fewer (for
example, `operata-prod`).
* **Redaction enablement** — whether the redactor Lambda runs. If yes,
provide the VPC ID and private subnet IDs to deploy it into.
Operata returns a quick-create CloudFormation link and your Operata
Group ID.
### 2. Open the quick-create link
Click the link Operata sent. AWS opens the
[CloudFormation console](https://console.aws.amazon.com/cloudformation)
with the template pre-filled.
### 3. Enter your Operata API token
Paste an Operata API token into the **API key** parameter. Create a
token in the Operata console under **Settings → Config → API** and
label it `AWS_Integration`.
This is the only parameter you fill in by hand. Every other field is
pre-populated.
### 4. (Optional) Configure CTR upsert
To enrich CTRs with agent-hierarchy or other lookup data before delivery,
set the two upsert parameters:
* `agentDataS3BucketName` — S3 bucket holding JSON-line or JSON-array
data files. Format: `bucket-name/prefix`.
* `agentLookupKey` — the CTR field used to look up enrichment data
(for example, `USERNAME` or `userId`).
Leave both blank to skip enrichment.
### 5. Deploy the stack
Acknowledge the IAM acknowledgement, then click **Create stack**. The stack
takes around five minutes to deploy. CloudFormation creates the
Amazon EventBridge Pipe, the redactor Lambda (if enabled), the API
destination, the Secrets Manager secret, and the IAM roles.
### 6. Place a test contact
Make or receive a call through your Amazon Connect CCP. Make sure:
* The [Agent Collector](/docs/collector-overview) Chrome
extension is installed in the agent's browser.
* The CCP URL matches the Amazon Connect instance you just installed
the stack against.
* You **close the contact** when the call ends — CTRs are only emitted
on close.
## Verify
In the [Operata console](https://app.operata.io), open **Get the
Details** and filter to the last five minutes. Your test contact
appears with a `traceRecord` payload similar to:
```json theme={null}
{
"traceRecord": {
"ContactId": "0772a43f-65dc-4936-a51a-bf291bced3ab",
"InitiationTimestamp": "2026-05-18T10:14:22Z",
"DisconnectTimestamp": "2026-05-18T10:15:08Z",
"InitiationMethod": "INBOUND",
"Channel": "VOICE",
"Queue": {
"Name": "operata-prod-queue",
"EnqueueTimestamp": "2026-05-18T10:14:23Z",
"DequeueTimestamp": "2026-05-18T10:14:25Z"
},
"Agent": {
"Username": "operataAgent",
"ConnectedToAgentTimestamp": "2026-05-18T10:14:25Z",
"AgentInteractionDuration": 33
},
"Attributes": {
"contactId": "0772a43f-65dc-4936-a51a-bf291bced3ab"
},
"AWSContactTraceRecordFormatVersion": "2017-03-10"
},
"contactDurationSummary": {
"contactDurationRoundedMin": 1,
"contactDurationActualSec": 46
}
}
```
CTRs can take up to five minutes to land. If nothing appears after
that, work through [Troubleshooting](/docs/aws-troubleshooting).
## Related
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — strip PII fields before they leave your AWS account.
* [Tag your AWS resources](/docs/aws-tagging) — apply cost-allocation and access-control tags to the deployed stack.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the runtime that processes each CTR.
* [Troubleshoot the integration](/docs/aws-troubleshooting) — missing records, CloudFormation failures, secret management.
# API — Data Privacy Controls
Source: https://docs.operata.com/docs/ctr-redaction-config
Control which Contact Trace Record fields reach Operata by configuring an allow-list or deny-list through the Operata API.
## Controlling data sent to Operata
Configure an allow-list or deny-list via the Operata API to control which Contact Trace Record (CTR) fields reach Operata. CTR data can contain sensitive information or personally identifiable information (PII); the configuration lets you redact specific fields before Operata receives them. The configuration supports either an allow-list or a deny-list.
## Privacy-first default
Operata operates on a privacy-first basis. When deployed without any redaction configuration, only the minimum required set of CTR fields is sent to Operata. You can then progressively expand the data sent by configuring an allow-list.
To send additional fields beyond the default minimum payload, configure an allow-list:
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "WHITELIST",
"fields": [
"Attributes.myCustomField"
]
}
}
```
The configuration above sends `Attributes.myCustomField` in addition to the default minimum payload.
To send the **entire CTR payload**, explicitly define an empty deny-list:
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": []
}
}
```
## Scope
Privacy controls apply to Contact Trace Record data collected by the CTR Collection stack. Data collected from other sources (Contact Flow Logs, Amazon Lex) may also contain PII — particularly in utterance text, slot values, and AI-generated responses. Contact [Operata Support](mailto:support@operata.com) to discuss the appropriate redaction configuration for these data sources.
## Using the Operata API
Configure the redaction behavior programmatically using an allow-list or deny-list:
* **Allow-list** — sends only the mandatory fields plus the fields you specify.
* **Deny-list** — sends all CTR fields except those you specify.
Only one configuration is supported at a time — **either an allow-list or a deny-list, never both**.
The following fields are mandatory and cannot be added to the deny-list or omitted from the allow-list.
**Mandatory fields**
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "WHITELIST",
"fields": [
"Agent",
"Agent.NumberOfHolds",
"Agent.DeviceInfo",
"Agent.CustomerHoldDuration",
"Agent.Username",
"Agent.LongestHoldDuration",
"Agent.AgentInteractionDuration",
"Agent.AfterContactWorkStartTimestamp",
"Agent.ConnectedToAgentTimestamp",
"Agent.AfterContactWorkDuration",
"Agent.AfterContactWorkEndTimestamp",
"Agent.HierarchyGroups",
"AgentConnectionAttempts",
"AnsweringMachineDetectionStatus",
"AWSAccountId",
"AWSContactTraceRecordFormatVersion",
"Channel",
"ConnectedToSystemTimestamp",
"ContactId",
"NextContactId",
"PreviousContactId",
"DisconnectReason",
"InitialContactId",
"InitiationMethod",
"LastUpdateTimestamp",
"DisconnectTimestamp",
"InitiationTimestamp",
"InstanceARN",
"QualityMetrics",
"Queue",
"Queue.Name",
"Queue.Duration",
"Queue.DequeueTimestamp",
"Queue.EnqueueTimestamp",
"SystemEndpoint",
"SystemEndpoint.Type",
"SystemEndpoint.Address",
"TransferCompletedTimestamp",
"TransferredToEndpoint"
]
}
}
```
Full documentation for the Contact Trace Records data model is available in the [AWS documentation](https://docs.aws.amazon.com/connect/latest/adminguide/ctr-data-model.html).
## Defining the redaction configuration
The redaction configuration payload consists of:
1. The `type` — either `BLACKLIST` or `WHITELIST`.
2. The `fields` to be either included or excluded.
Choose an allow-list or deny-list, then define the fields to include or exclude. An allow-list includes only the mandatory fields plus the fields you specify; a deny-list excludes the fields you specify. Fields are only included or excluded if they exist in the CTR.
### Example deny-list
In this example, the `CustomerDetails` field within `Attributes` contains sensitive PII data and is removed before transmission to Operata. All other fields within `Attributes` are included.
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": [
"Attributes.CustomerDetails"
]
}
}
```
### Example allow-list
In this example, `InitiationMethod` and `AnsweringMachineDetectionStatus` are the only top-level fields included within the CTR. `RoutingProfile` within `Agent` is also included, while all other fields within `Agent` are excluded.
```json theme={null}
{
"key": "REDACTION_CONFIG",
"value": {
"type": "WHITELIST",
"fields": [
"InitiationMethod",
"AnsweringMachineDetectionStatus",
"Agent.RoutingProfile"
]
}
}
```
### Updating the redaction configuration
The Operata REST API provides endpoints to fetch (`GET`), set (`PUT`), and remove (`DELETE`) the redaction configuration.
While the configuration is updated immediately, there may be up to a 30-minute delay before the change propagates across all collection points.
## Support
Contact Operata for support.
| Channel | Details |
| - | - |
| Have an issue? | In-app messenger |
| External web form | [Operata Help](https://operata.typeform.com/Operata-Help) |
# Account
Source: https://docs.operata.com/docs/cxone-account
Account properties the Agent Collector attaches to every NICE CXOne Interaction record, identifying the Operata group and source platform.
The `accountProperties` object identifies the Operata group a NICE CXOne Interaction belongs to. The Agent Collector attaches it to every Interaction record it streams from the NICE CXOne platform.
## Schema
```json theme={null}
"accountProperties": {
"operataGroupId": "a28453f9-abab-cdcd-efef-84d9e67ac297",
"operataGroupName": "Operata Demo",
"service": "NICE CXOne"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `operataGroupId` | string (UUID) | yes | Operata Group ID assigned at account creation. The credential identifier used in API requests. | `a28453f9-abab-cdcd-efef-84d9e67ac297` |
| `operataGroupName` | string | yes | Friendly name of the Operata account. | `Operata Demo` |
| `service` | string | yes | Contact-center platform the Interaction came from. Always `NICE CXOne` for pages in this group. | `NICE CXOne` |
# Agent
Source: https://docs.operata.com/docs/cxone-agent
Agent-endpoint telemetry the Agent Collector captures for each NICE CXOne Interaction — machine resources, browser, network, softphone versions, devices, and interaction metrics.
The `serviceAgent` object describes the agent endpoint's state for one NICE CXOne Interaction: machine resource usage, browser and softphone versions, network details, audio devices used, and interaction-level metrics. The Agent Collector emits it for every Interaction. For the Amazon Connect equivalent, see [Agent](/docs/agent).
## Schema
```json theme={null}
"serviceAgent": {
"username": "agent_42",
"usedDevices": [
{
"timestamp": "2026-05-18T10:14:10.733Z",
"deviceId": "default",
"groupId": "d12cdd42fcade718f5733e77413bc1caf77bc5a93a97eeaa1faa460027641456",
"kind": "audioinput",
"label": "Default - C922 Pro Stream Webcam (046d:085c)"
},
{
"timestamp": "2026-05-18T10:14:10.733Z",
"deviceId": "default",
"groupId": "17355f45f7fcc9c026f10f2211576fbbd70b646e2137b7851e73730b381b7422",
"kind": "audiooutput",
"label": "Default - C49J89x (DisplayPort)"
}
],
"machine": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz",
"idlePercentage": { "avg": 90.24 },
"utilisedPercentage": { "min": 5.72, "max": 18.5, "avg": 9.76 }
},
"memory": {
"availableGb": 64,
"utilisedPercentage": { "min": 97.61, "max": 97.63, "avg": 97.62 }
}
},
"network": {
"internetGatewayIp": "33.222.36.179",
"mediaIpAddress": "192.168.1.23",
"availableInterfaces": [
{ "address": "192.168.1.23", "type": "lan" },
{ "address": "192.168.1.18", "type": "wlan" }
],
"isp": "National ISP",
"geolocation": {
"city": "Point Cook",
"region": "Victoria",
"country": "Australia"
},
"serviceId": "ce1adf3c-1693-44e8-a278-e21429caf861"
},
"browser": {
"name": "Chrome",
"version": "115.0.5790.170"
},
"softphone": {
"softphoneUrl": "https://home-c42.niceincontact.com/agent/",
"operataCollectorVersion": "1.6.13",
"operataChromeExtVersion": "1.3.18"
},
"interaction": {
"totalDurationSec": 70,
"talkingDurationSec": 70,
"onHoldDurationSec": 0,
"onMuteDurationSec": 0
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `username` | string | yes | Agent username as configured in NICE CXOne. | `agent_42` |
| `usedDevices` | object\[] | yes | Audio input and output devices the MAX WebRTC softphone used during the session. Each entry has `timestamp`, `deviceId`, `groupId`, `kind`, `label`. | — |
| `usedDevices[].kind` | string | yes | Device kind. One of `audioinput`, `audiooutput`. | `audioinput` |
| `machine.cpu` | object | yes | Agent machine CPU utilization and availability metrics. See [System CPU and memory usage](/docs/system-resources) for the standalone CPU schema. | — |
| `machine.memory` | object | yes | Agent machine memory utilization and availability metrics. | — |
| `network` | object | yes | Agent network information: available interfaces, types, IP addresses, and which interface handled media during the Interaction. See [Machine, browser, and network data](/docs/machine-browser-network) and [Geolocation and ISP](/docs/geolocation-isp) for the standalone network schemas. | — |
| `network.isp` | string | no | Name of the internet service provider, identified from the internet interface sending data to Operata. | `National ISP` |
| `network.geolocation` | object | no | Geolocation of the ISP point of presence. | — |
| `network.serviceId` | string (UUID) | no | NICE CXOne agent ID as configured in the NICE tenant. | `ce1adf3c-1693-44e8-a278-e21429caf861` |
| `browser` | object | yes | Browser name and version reported by the Agent Collector. | — |
| `softphone` | object | yes | Softphone URL and version information, including the Agent Collector and Chrome extension versions. | — |
| `interaction` | object | yes | Key Interaction metrics captured after the Interaction connects to the agent: total duration, talking time, on-hold time, on-mute time. | — |
# Agent feedback
Source: https://docs.operata.com/docs/cxone-agent-feedback
Fields in the agent feedback payload — sent by the Agent Collector when an agent reports an issue during or after a NICE CXOne Interaction.
The `agentFeedback` object contains the structured payload the Agent Collector sends when an agent submits a feedback report during or after a NICE CXOne Interaction.
## Schema
```json theme={null}
{
"state": "AgentReportedIssue",
"timestamp": "2026-05-18T10:14:01.414Z",
"softphoneError": {
"type": "Delay in the conversation"
},
"context": {
"callContactId": "b5914891-7fdc-40af-9631-b54ead242626",
"cause": "Delay in the conversation",
"severity": "Critical",
"scenario": "Outbound",
"category": "Softphone would not work",
"message": "5 second delay at least on all calls this morning"
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `state` | string | yes | Agent state when the issue was reported. | `AgentReportedIssue` |
| `timestamp` | string (ISO 8601) | yes | When the agent submitted the report. UTC. | `2026-05-18T10:14:01.414Z` |
| `softphoneError.type` | string | yes | Issue category selected by the agent from the feedback form's category list. | `Delay in the conversation` |
| `context.callContactId` | string (UUID) | yes | NICE CXOne Interaction ID of the current or last-known Interaction. | `b5914891-7fdc-40af-9631-b54ead242626` |
| `context.cause` | string | yes | Cause of the issue as reported by the agent. | `Delay in the conversation` |
| `context.severity` | string | yes | Severity level selected by the agent. Observed values include `Critical`, `High`, `Medium`, `Low`, and `Terrible`. | `Critical` |
| `context.scenario` | string | no | Interaction direction at the time the feedback was submitted. One of `Inbound`, `Outbound`. Empty when no Interaction is active. | `Outbound` |
| `context.category` | string | yes | Issue category as displayed in the feedback form. | `Softphone would not work` |
| `context.message` | string | no | Free-text message entered by the agent describing the issue. | `Could not hear customer` |
# Headset
Source: https://docs.operata.com/docs/cxone-headset
Jabra headset device details and per-Interaction call-quality metrics captured by the Agent Collector for NICE CXOne Interactions.
The `headset` object captures Jabra headset device details and per-Interaction call-quality metrics for the agent endpoint. The Agent Collector collects headset data only when headset collection is enabled; it's off by default and supports a defined set of Jabra models. For the Amazon Connect equivalent, see [Headset logs](/docs/headset-logs).
## Schema
```json theme={null}
"headset": {
"modelName": "Jabra Engage 50",
"serialNumber": "000045dd662b",
"apiVersion": "3.0.0-beta.4",
"firmwareVersion": "2.4.0",
"metrics": {
"deviceMuteCount": 0,
"deviceVolumeAdjustCount": 0,
"misalignedBoomArmCount": 1,
"backgroundNoiseDb": { "min": 37, "max": 37, "avg": 37 },
"exposureDb": { "min": 46, "max": 46, "avg": 46 },
"speech": {
"totalSeconds": 9.33,
"txSpeechTotal": 7,
"txSpeechTotalPct": 75.02,
"rxSpeechTotal": 0.45,
"rxSpeechTotalPct": 4.82,
"crossTalkTotal": 0,
"crossTalkTotalPct": 0,
"silenceTotal": 1.88,
"silenceTotalPct": 20.16
}
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `modelName` | string | yes | Jabra headset model name. | `Jabra Engage 50` |
| `serialNumber` | string | yes | Jabra headset serial number. | `000045dd662b` |
| `apiVersion` | string | yes | Jabra SDK API version reported by the headset. | `3.0.0-beta.4` |
| `firmwareVersion` | string | yes | Jabra headset firmware version. | `2.4.0` |
| `metrics.deviceMuteCount` | integer | yes | Number of mute events triggered on the headset during the Interaction. | `0` |
| `metrics.deviceVolumeAdjustCount` | integer | yes | Number of volume adjustments on the headset during the Interaction. | `0` |
| `metrics.misalignedBoomArmCount` | integer | yes | Number of times the boom-arm microphone was detected in an incorrect position during the Interaction. | `1` |
| `metrics.backgroundNoiseDb` | object | yes | Background noise in decibels — `min`, `max`, `avg` across the Interaction. | `{ "min": 37, "max": 37, "avg": 37 }` |
| `metrics.exposureDb` | object | yes | Audio exposure in decibels — `min`, `max`, `avg` across the Interaction. | `{ "min": 46, "max": 46, "avg": 46 }` |
| `metrics.speech.totalSeconds` | number | yes | Total Interaction duration as measured by the headset, in seconds. | `9.33` |
| `metrics.speech.txSpeechTotal` | number | yes | Transmit audio time (agent speaking), in seconds. | `7` |
| `metrics.speech.txSpeechTotalPct` | number | yes | Transmit audio time as a percentage of the Interaction. | `75.02` |
| `metrics.speech.rxSpeechTotal` | number | yes | Receive audio time (customer speaking), in seconds. | `0.45` |
| `metrics.speech.rxSpeechTotalPct` | number | yes | Receive audio time as a percentage of the Interaction. | `4.82` |
| `metrics.speech.crossTalkTotal` | number | yes | Cross-talk time during the Interaction, in seconds. | `0` |
| `metrics.speech.crossTalkTotalPct` | number | yes | Cross-talk time as a percentage of the Interaction. | `0` |
| `metrics.speech.silenceTotal` | number | yes | Silence time during the Interaction, in seconds. | `1.88` |
| `metrics.speech.silenceTotalPct` | number | yes | Silence time as a percentage of the Interaction. | `20.16` |
# Insights
Source: https://docs.operata.com/docs/cxone-insights
Insight detections Operata raises per NICE CXOne Interaction — including type, severity, measured value, and detection timestamp.
The `insights` object lists every insight detection Operata raised for one NICE CXOne Interaction. Each entry maps to a named detection in the [insights catalog](/docs/insights-catalog); see [Insights](/docs/concepts-insights) for the underlying concept.
## Schema
```json theme={null}
"insights": {
"count": 2,
"tags": [
{
"id": "ins_01HXYZ8K3M7Q4R2P6T9V0W",
"type": "high_agent_connection_time",
"description": "Very High Agent connection time",
"severity": "Severe",
"value": 14.2,
"unit": "seconds",
"contactId": "b5914891-7fdc-40af-9631-b54ead242626",
"detectedAt": "2026-05-18T10:14:43Z"
},
{
"id": "ins_01HXYZ8K3M7Q4R2P6T9V0X",
"type": "high_rtt",
"description": "High RTT",
"severity": "Minor",
"value": 280,
"unit": "milliseconds",
"contactId": "b5914891-7fdc-40af-9631-b54ead242626",
"detectedAt": "2026-05-18T10:15:02Z"
}
]
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `count` | integer | yes | Number of insights raised on this Interaction. | `2` |
| `tags` | object\[] | yes | Insights raised on this Interaction. Empty array when no insights were raised. | — |
| `tags[].id` | string | yes | Unique insight ID. Stable across queries; safe to use as a primary key. | `ins_01HXYZ8K3M7Q4R2P6T9V0W` |
| `tags[].type` | string | yes | Insight type, matching an entry in the [insights catalog](/docs/insights-catalog). | `high_agent_connection_time` |
| `tags[].description` | string | yes | Human-readable description of the insight. | `Very High Agent connection time` |
| `tags[].severity` | string | yes | Severity level. One of `Minor`, `Severe`, `Terminal`. | `Severe` |
| `tags[].value` | number | no | Measured value that triggered the insight. Absent for insights that don't carry a numeric measurement. | `14.2` |
| `tags[].unit` | string | no | Unit of measurement for `value`. Common values: `seconds`, `milliseconds`, `percent`, `count`. | `seconds` |
| `tags[].contactId` | string (UUID) | yes | NICE CXOne Interaction ID this insight applies to. | `b5914891-7fdc-40af-9631-b54ead242626` |
| `tags[].detectedAt` | string (ISO 8601) | yes | When Operata raised the insight. UTC. | `2026-05-18T10:14:43Z` |
# Interaction
Source: https://docs.operata.com/docs/cxone-interaction
Core fields for each NICE CXOne Interaction — identifiers, direction, type, key event timestamps, recording URL, and disconnect reason — captured by the Agent Collector.
The `contact` object captures identifiers, direction, type, recording URL, key event timestamps, and disconnect reason for one NICE CXOne Interaction. It's the NICE CXOne native record for a customer contact — the platform equivalent of the Amazon Connect [Contact](/docs/contact). See [Contacts and Interactions](/docs/concepts-contacts-and-interactions) for the cross-platform concept.
## Schema
```json theme={null}
"contact": {
"id": {
"current": "b5914891-7fdc-40af-9631-b54ead242626",
"previous": "",
"next": ""
},
"events": {
"incomingToPlatform": "2026-05-18T10:14:18.65Z",
"connectingToAgent": "2026-05-18T10:14:22.80Z",
"connectedToAgent": "2026-05-18T10:14:25.10Z",
"disconnected": "2026-05-18T10:15:35.00Z"
},
"direction": "Outbound",
"type": "VOICE",
"initiation": "OUTBOUND",
"durationSec": 70,
"endedBy": "Customer",
"recordingUrl": null,
"disconnectReason": "CUSTOMER_DISCONNECT"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `id.current` | string (UUID) | yes | NICE CXOne Interaction ID for this leg. | `b5914891-7fdc-40af-9631-b54ead242626` |
| `id.previous` | string (UUID) | no | The previous Interaction ID when the Interaction was transferred from another. Empty when there's no predecessor. | `""` |
| `id.next` | string (UUID) | no | The next Interaction ID when the Interaction transferred to another. Empty when there's no successor. | `""` |
| `events` | object | yes | Timestamps of key events in the Interaction lifecycle. See the per-field rows for the four events captured. | — |
| `events.incomingToPlatform` | string (ISO 8601) | yes | When the Interaction arrived at the NICE CXOne platform. UTC. | `2026-05-18T10:14:18.65Z` |
| `events.connectingToAgent` | string (ISO 8601) | yes | When NICE CXOne started routing the Interaction to an agent. UTC. | `2026-05-18T10:14:22.80Z` |
| `events.connectedToAgent` | string (ISO 8601) | yes | When the Interaction connected to the agent. UTC. | `2026-05-18T10:14:25.10Z` |
| `events.disconnected` | string (ISO 8601) | yes | When the Interaction disconnected. UTC. | `2026-05-18T10:15:35.00Z` |
| `direction` | string | yes | Interaction direction from the agent's perspective. One of `Inbound`, `Outbound`. | `Outbound` |
| `type` | string | yes | Interaction type. CXOne reports `VOICE` for voice Interactions. | `VOICE` |
| `initiation` | string | yes | Original Interaction direction. One of `INBOUND`, `OUTBOUND`. | `OUTBOUND` |
| `durationSec` | integer | yes | Total Interaction duration in seconds, from `incomingToPlatform` to `disconnected`. | `70` |
| `endedBy` | string | yes | Which party disconnected the call. One of `Agent`, `Customer`, `System`. | `Customer` |
| `recordingUrl` | string | no | URL of the Interaction recording, when CXOne provides one. `null` when recording is disabled or unavailable. | `null` |
| `disconnectReason` | string | no | System-generated reason for disconnection, using NICE CXOne's disconnect-reason values. | `CUSTOMER_DISCONNECT` |
# WebRTC session
Source: https://docs.operata.com/docs/cxone-webrtc-session
WebRTC (Web Real-Time Communication) session metrics the Agent Collector captures for each NICE CXOne Interaction — signalling, ICE collection, media quality, and event-failure flags.
The `webRTCSession` object describes the WebRTC (Web Real-Time Communication) session for one NICE CXOne Interaction handled by the MAX WebRTC softphone. It covers the signalling endpoint, event timers, inbound and outbound media metrics, media endpoint, and per-stage failure flags. For the Amazon Connect equivalent, see [WebRTC session](/docs/webrtc-session).
## Schema
```json theme={null}
"webRTCSession": {
"signallingEndpoint": {
"fqdn": "wss://sydacwrtc01.niceincontact.com"
},
"eventTimer": {
"initializationTimeMillis": 49,
"preTalkingTimeMillis": 324,
"handshakingTimeMillis": 268,
"signallingConnectTimeMillis": 2,
"gumTimeMillis": 36,
"cleanupTimeMillis": 5,
"iceCollectionTimeMillis": 103
},
"metrics": {
"mos": { "min": 4.39, "max": 4.43, "avg": 4.41 },
"rtt": { "max": 121, "avg": 74 },
"jitter": { "max": 6, "avg": 2 },
"inbound": {
"packetsReceived": 2336,
"packetsLost": 0,
"packetsLostPercentage": 0,
"bytesReceived": 169788,
"audioLevel": { "max": 10, "avg": 3.71 },
"jitterBufferMils": { "min": 0, "max": 1, "avg": 0.31 }
},
"outbound": {
"packetsSent": 2470,
"packetsLost": 0,
"packetsLostPercentage": 0,
"bytesSent": 202087,
"audioLevel": { "max": 2449, "avg": 392.79 },
"jitterBufferMils": { "min": 0, "max": 5, "avg": 1.76 }
}
},
"mediaEndpoint": {
"fqdn": "",
"destinationPort": "3478",
"sourcePort": "63921",
"transport": "",
"privateIp": "10.4.3.213"
},
"eventFailure": {
"iceCollectionFailure": false,
"setLocalDescriptionFailure": false,
"signallingConnectionFailure": false,
"gumTimeoutFailure": false,
"createOfferFailure": false,
"noRemoteIceCandidateFailure": false,
"setRemoteDescriptionFailure": false,
"gumOtherFailure": false,
"userBusyFailure": false,
"handshakingFailure": false,
"invalidRemoteSDPFailure": false
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `signallingEndpoint.fqdn` | string | yes | NICE CXOne WebRTC signalling endpoint FQDN. | `wss://sydacwrtc01.niceincontact.com` |
| `eventTimer.initializationTimeMillis` | integer | yes | WebRTC initialization duration in milliseconds. | `49` |
| `eventTimer.preTalkingTimeMillis` | integer | yes | Time from session start to first audio in milliseconds. | `324` |
| `eventTimer.handshakingTimeMillis` | integer | yes | DTLS handshake duration in milliseconds. | `268` |
| `eventTimer.signallingConnectTimeMillis` | integer | yes | Signalling connection duration in milliseconds. | `2` |
| `eventTimer.gumTimeMillis` | integer | yes | `getUserMedia` call duration in milliseconds. | `36` |
| `eventTimer.cleanupTimeMillis` | integer | yes | Session teardown duration in milliseconds. | `5` |
| `eventTimer.iceCollectionTimeMillis` | integer | yes | ICE candidate collection duration in milliseconds. | `103` |
| `metrics.mos` | object | yes | Estimated Mean Opinion Score — `min`, `max`, `avg`. Range 1 (worst) to 5 (best). | `{ "min": 4.39, "max": 4.43, "avg": 4.41 }` |
| `metrics.rtt` | object | yes | Round-trip time in milliseconds — `max` and `avg`. | `{ "max": 121, "avg": 74 }` |
| `metrics.jitter` | object | yes | Jitter in milliseconds — `max` and `avg`. | `{ "max": 6, "avg": 2 }` |
| `metrics.inbound.packetsReceived` | integer | yes | Total RTP packets received from NICE CXOne during the Interaction. | `2336` |
| `metrics.inbound.packetsLost` | integer | yes | Total inbound RTP packets lost. | `0` |
| `metrics.inbound.packetsLostPercentage` | number | yes | Inbound packet loss as a percentage. | `0` |
| `metrics.inbound.bytesReceived` | integer | yes | Total inbound bytes received. | `169788` |
| `metrics.inbound.audioLevel` | object | yes | Inbound audio level range — `max` and `avg`. | — |
| `metrics.inbound.jitterBufferMils` | object | yes | Inbound jitter-buffer delay in milliseconds — `min`, `max`, `avg`. | — |
| `metrics.outbound.packetsSent` | integer | yes | Total RTP packets sent to NICE CXOne during the Interaction. | `2470` |
| `metrics.outbound.packetsLost` | integer | yes | Total outbound RTP packets lost. | `0` |
| `metrics.outbound.packetsLostPercentage` | number | yes | Outbound packet loss as a percentage. | `0` |
| `metrics.outbound.bytesSent` | integer | yes | Total outbound bytes sent. | `202087` |
| `metrics.outbound.audioLevel` | object | yes | Outbound audio level range — `max` and `avg`. | — |
| `metrics.outbound.jitterBufferMils` | object | yes | Outbound jitter-buffer delay in milliseconds — `min`, `max`, `avg`. | — |
| `mediaEndpoint.fqdn` | string | no | NICE CXOne TURN service FQDN. Empty when the media endpoint is referenced only by IP. | `""` |
| `mediaEndpoint.destinationPort` | string | yes | Destination port on the NICE CXOne TURN service. | `3478` |
| `mediaEndpoint.sourcePort` | string | yes | Source port used on the agent endpoint. | `63921` |
| `mediaEndpoint.transport` | string | no | Transport protocol. One of `udp`, `tcp`, `tls`. Empty when CXOne does not report a value. | `""` |
| `mediaEndpoint.privateIp` | string (IPv4) | yes | Private IP the agent endpoint used for media. | `10.4.3.213` |
| `eventFailure` | object | yes | Per-stage WebRTC failure flags. Each property is a boolean; `true` means the named failure occurred during session setup or teardown. | — |
# Proxies and the agent softphone
Source: https://docs.operata.com/docs/diagnose-proxies-and-softphones
A proxy between the agent's browser and your contact center cloud can delay softphone traffic enough to drop calls and freeze softphone controls. Here's how to recognize it and prove it.
A proxy sits between the agent's softphone and your contact center cloud, inspecting traffic and passing or blocking it. When it's loaded, misconfigured, or simply in the path of real-time media, calls degrade in ways that look like a platform fault.
## How it works
The proxy acts as an intermediary between the agent's browser and the cloud. Which traffic goes through it is usually set by a desktop **Proxy Auto-Configuration (PAC)** file.
Real-time media is where it bites. Signaling and media between the softphone and the cloud are latency-sensitive, so a proxy that adds delay — or that terminates and re-establishes connections — breaks calls that would otherwise be fine.
## Symptoms
* Dropped calls, with no matching fault on the platform side.
* Softphone controls that don't respond, so agents can't answer and fall into a missed-call state.
* Clustered signaling and handshake errors across every agent behind the same proxy.
* Agents on one network affected while agents elsewhere are fine.
## Prove it
Take a sample of affected agents and do one of these:
1. Put proxy bypass rules in place for the softphone's media, signaling, and API traffic.
2. Move them to a network that doesn't apply the same proxy rules.
If the symptoms stop, the proxy is the cause. Extend the bypass to every agent permanently, or fix the proxy's performance.
## Platform specifics
Which endpoints must bypass the proxy depends on your platform.
* [Amazon Connect: proxy bypass rules](/docs/help/amazon-connect-proxy-bypass) — the four CCP (Contact Control Panel) endpoints, which of them must bypass, and the AWS networking constraints that go with them.
## Related
* [Softphone issues](/docs/diagnose-softphone-issues) — reading the errors a proxy produces.
* [Which URLs and protocols to allow](/docs/help/which-urls-and-protocols-will-i-need-to-allow-so-i-can-use-operata) — Operata's own network requirements.
* [RTC session failure and ICE timeout](/docs/help/rtc-session-failure-and-ice-timeout-causes-and-troubleshooting) — when media can't establish at all.
# Softphone issues
Source: https://docs.operata.com/docs/diagnose-softphone-issues
Softphone errors come from the agent's browser, not your contact center platform's cloud. Here's where Operata surfaces them and how to work out which ones matter.
A softphone error is the agent's browser reporting that it couldn't do something — reach a media endpoint, get microphone permission, or hold a signaling connection. Cloud-side records rarely show these, because from the platform's point of view the contact was delivered.
## How it works
In the browser, the [Agent Collector](/docs/collector-overview) captures the softphone's log entries and attaches each one to the contact that was active at the time. That makes every error answerable: which agent, which contact, which moment.
## Where to look
* [Logs and Errors dashboard](/docs/help/logs-and-errors-user-guide) — error counts by type, agent, and time. Start here when several agents report the same symptom.
* [Agent Overview dashboard](/docs/help/agent-overview-user-guide) — errors for one agent, alongside their network and device data.
* [Calls and logs](/docs/help/calls-and-logs) — the raw log entries for a single contact.
## Reading the counts
One error on one contact is noise. The same error across many agents at the same time is infrastructure — a proxy, a firewall rule, or a network path. Sort by error type first, then by how many distinct agents it touches.
## Platform specifics
Error names come from the softphone, so they differ by platform.
* [Amazon Connect: CCP error and agent state reference](/docs/help/amazon-connect-what-do-softphone-errors-mean) — every CCP (Contact Control Panel) error and agent state, with likely causes.
## Related
* [Proxies and the agent softphone](/docs/diagnose-proxies-and-softphones) — the most common cause of clustered signaling errors.
* [Why missed-call data varies with collector coverage](/docs/help/missedcallagent) — reading missed calls when not every agent runs the Agent Collector.
* [Tools and logs](/docs/diagnose-tools-and-logs) — getting the raw logs out of Operata.
* [CCP error logs](/docs/ccp-error-logs) — the field schema Operata stores.
# Tools and logs
Source: https://docs.operata.com/docs/diagnose-tools-and-logs
When the dashboards aren't enough, Operata gives you the raw logs and a set of diagnostic tools. Here's what's available and when to reach for each.
Dashboards tell you what happened. Logs tell you why. When an error count or an insight points at a problem you can't explain from a chart, pull the logs for that agent and that contact.
## When to use logs
* A dashboard shows an error you don't recognize.
* One agent behaves differently from everyone else on the same network and device.
* Operata is missing data you expected, and you need to prove where collection stopped.
## Getting logs out of Operata
Open [Calls and logs](/docs/help/calls-and-logs), filter to the agent and time range you need, and download. Use the absolute time filter — it runs on the UTC clock, which matters when you're lining logs up against platform-side timestamps.
Downloads are capped, so narrow the time range rather than widening it.
## Platform specifics
Log formats, and the tools that read them, are platform-specific.
* [Amazon Connect: CCP log parser](/docs/help/amazon-connect-log-parser) — load a downloaded CCP (Contact Control Panel) log file into a browser-based viewer.
* [Amazon Connect: capture WebRTC diagnostics](/docs/help/dump-function-amazon-connect) — dump the live WebRTC session from the agent's browser console when Operata is missing collection data.
* [Amazon Connect: screen recording observability](/docs/screen-recording) — read the screen recording lifecycle out of the CCP logs to find contacts that were flagged but never recorded.
## Related
* [Softphone issues](/docs/diagnose-softphone-issues) — what the errors in those logs mean.
* [Get help and report issues](/docs/help/getting-help-and-reporting-issues) — what to send Operata support.
* [Check service status](/docs/help/checking-operata-service-status-and-reporting-platform-issues) — rule out a platform incident before you dig.
# Install the Edge extension
Source: https://docs.operata.com/docs/edge-extension
Install the Agent Collector on Microsoft Edge via Microsoft Edge Add-ons or enterprise deployment, so every agent contact captures machine, network, and softphone telemetry.
Install the Agent Collector on Microsoft Edge so every agent contact captures machine, network, and softphone telemetry and streams it to Operata.
## Before you start
* An [Operata account](/docs/get-started-overview) and your Operata Group ID.
* Microsoft Edge on a supported version. See [Browser compatibility](/docs/browser-compatibility) for the current list.
* For enterprise deployments: admin access to your Microsoft Edge policy or device-management tool.
## Steps
### 1. Install the extension
Open the [Operata Collector listing](https://microsoftedge.microsoft.com/addons/detail/operata-collector/ghgkknhlginpepabafckbejbpfmdppjk) in Microsoft Edge Add-ons and click **Get**.
For packaged enterprise deployments on Windows and macOS, follow [Microsoft's guide to managing Edge extensions](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-manage-extensions) and push extension ID `ghgkknhlginpepabafckbejbpfmdppjk` through your existing policy.
### 2. Confirm the extension is loaded
Open `edge://extensions/` in the agent's browser. The Operata Collector appears in the list with the toggle in the on position. Edge maintains the extension automatically; the [Microsoft Edge Add-ons listing](https://microsoftedge.microsoft.com/addons/detail/operata-collector/ghgkknhlginpepabafckbejbpfmdppjk) shows the current version.
### 3. Place a test contact
Have the agent open the contact center softphone in the same browser profile and place a test contact end to end.
## Verify
In the Operata console, open **Contacts** and filter to the last 10 minutes. Your test contact appears with the `serviceAgent` field populated — `browser.name` reads `Edg` (Edge's user-agent identifier) and `operataChromeExtVersion` matches the version shown in `edge://extensions/`. (The field name keeps the Chrome prefix because the Edge extension shares the build pipeline with the Chrome version.)
## Related
* [Chrome extension](/docs/chrome-extension) — Install the Collector on Google Chrome for agents on that browser.
* [VPN bypass URL](/docs/vpn-bypass) — Configure when agents work behind a corporate VPN.
* [Browser compatibility](/docs/browser-compatibility) — Supported Edge versions.
* [Agent Collector overview](/docs/collector-overview) — What the Collector captures across all browsers.
# Amazon Connect enablement
Source: https://docs.operata.com/docs/enablement-amazon-connect
The Amazon Connect-specific steps in Operata enablement — CTR collection, conversational analytics, EventBridge, and Heartbeat.
Work through the [generic enablement stages](/docs/help/service-enablement) first. This page covers the steps that only apply if you run Amazon Connect.
Enablement takes minutes. Approvals sometimes take longer — we'll help here.
## Foundation
### Connect Amazon Connect to Operata
Bring contact trace record (CTR) and agent data into Operata.
* [AWS integration benefits](/docs/help/aws-integration-benefits)
* [Connect Amazon Connect to Operata](/docs/integrations-amazon-connect-overview)
* [Install CTR collection](/docs/ctr-installation)
* [Send your first observation](/docs/guides-send-first-observation)
### Permissions and encryption
* [IAM policies](/docs/iam-policies)
* [KMS encryption](/docs/kms-encryption)
* [AWS tagging](/docs/aws-tagging)
### Redaction
Configure what is stripped before Amazon Connect data reaches Operata.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction)
* [Contact flow log redaction](/docs/guides-configure-contact-flow-log-redaction)
* [Lex redaction](/docs/guides-configure-lex-redaction)
## Stage 2
### Amazon Connect conversational analytics integration
Enablement takes minutes, approvals sometimes longer. Operata does not capture the call recordings or transcripts. This enables the Conversational Analytics dashboard.
* [Conversational Analytics](/docs/help/videos/conversational-analytics)
* [Conversational analytics installation](/docs/conversational-analytics-installation)
* [Conversational analytics charges](/docs/conversational-analytics-charges)
### Contact flow logs and Lex
Add routing and virtual agent context to the journey.
* [Contact flow logs](/docs/contact-flow-logs)
* [Lex integration](/docs/lex-integration)
### EventBridge
Push Operata data into other systems in real time.
* [Amazon EventBridge for Operata](/docs/concepts-eventbridge)
## Stage 3
### Heartbeat
Synthetic monitoring of agent login, call flows, and virtual agents.
* [Heartbeat setup](/docs/heartbeat-setup)
* [Virtual agent](/docs/virtual-agent)
### Cloud Orchestrator
* [Orchestrator installation](/docs/orchestrator-installation)
## Troubleshooting
* [AWS troubleshooting](/docs/aws-troubleshooting)
* [Virtual agent troubleshooting](/docs/virtual-agent-troubleshooting)
## Related
* [Enablement](/docs/help/service-enablement)
* [Amazon Connect data reference](/docs/resources-data-collection-amazon-connect)
# Genesys Cloud enablement
Source: https://docs.operata.com/docs/enablement-genesys
The Genesys Cloud-specific steps in Operata enablement — OAuth client, EventBridge source, and redaction policy.
Work through the [generic enablement stages](/docs/help/service-enablement) first. This page covers the steps that only apply if you run Genesys Cloud.
## Foundation
### Connect Genesys Cloud to Operata
Set up the OAuth client and Amazon EventBridge source so Conversations stream into Operata.
* [Genesys Cloud integration overview](/docs/genesys-overview)
* [Install the Genesys Cloud integration](/docs/genesys-installation)
### Redaction
Configure what the Operata Fetcher Service strips before Conversation data reaches Operata.
* [Genesys Cloud redaction schema](/docs/genesys-privacy)
* [Configure Genesys Cloud redaction](/docs/guides-configure-genesys-redaction)
## Related
* [Enablement](/docs/help/service-enablement)
* [Genesys Cloud data reference](/docs/genesys-data-reference)
* [What's collected from Genesys Cloud](/docs/resources-data-collection-genesys)
* [Feature matrix](/docs/compatibility-feature-matrix)
# NICE CXOne enablement
Source: https://docs.operata.com/docs/enablement-nice-cxone
The NICE CXOne-specific steps in Operata enablement — tenant connection and Agent Collector tagging.
Work through the [generic enablement stages](/docs/help/service-enablement) first. This page covers the steps that only apply if you run NICE CXOne.
## Foundation
### Connect NICE CXOne to Operata
Connect your tenant so Interaction records stream in, and tag the Agent Collector on each agent endpoint with your Operata Group ID.
* [NICE CXOne integration overview](/docs/integrations-nice-cxone-overview)
* [Install the NICE CXOne integration](/docs/integrations-nice-cxone-install)
* [How to find my Operata Group ID](/docs/help/how-to-find-my-operata-group-id)
## Related
* [Enablement](/docs/help/service-enablement)
* [NICE CXOne data reference](/docs/cxone-interaction)
* [Feature matrix](/docs/compatibility-feature-matrix)
# Genesys Cloud
Source: https://docs.operata.com/docs/genesys-data-reference
Field-level data reference for Genesys Cloud is in progress. Until it lands, see what Operata collects from Genesys Cloud and how to redact it.
Field-level reference tables for Genesys Cloud data are in progress. The Amazon Connect and NICE CXOne field references are complete; the Genesys Cloud tables land in a later release.
In the meantime, these pages cover what Operata collects from Genesys Cloud and how the data is shaped:
* [What's collected — Genesys Cloud](/docs/resources-data-collection-genesys) — the data groups Operata collects from Genesys Cloud and how often.
* [Genesys Cloud privacy and redaction](/docs/genesys-privacy) — the fields Operata retains and the redaction model.
* [Connect Genesys Cloud](/docs/genesys-overview) — how the integration streams Conversation analytics into Operata.
Need a field documented sooner? Contact [Operata Support](mailto:support@operata.com).
# Install the Genesys Cloud integration
Source: https://docs.operata.com/docs/genesys-installation
Set up the OAuth client, Amazon EventBridge source, and Operata configuration to stream Genesys Cloud Conversations into Operata.
Connect your Genesys Cloud organization to Operata so that every Conversation streams into Operata — a test interaction you end cleanly appears in the Operata console within five minutes of conversation end.
This guide covers manual integration. Automatic integration is available
via [AppFoundry](https://appfoundry.genesys.com/filter/genesyscloud/listing/cf45f658-f4a8-4e78-aef7-5e0f97482a51).
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role and your Operata Group ID. The Group ID is the UUID immediately after the hostname in your Operata console URL — for example, on `https://app.operata.io/41ba528c-cef7-400f-ab08-cc5aba33527f` the Group ID is `41ba528c-cef7-400f-ab08-cc5aba33527f`. Contact [Operata Support](mailto:support@operata.com) if you cannot locate it.
* A Genesys Cloud organization with admin access to **Account Settings**, **User Management**, and **IT and Integrations**.
* The [Genesys Cloud integration overview](/docs/genesys-overview) read end to end — the OAuth scopes you grant in step 2 map to the data Operata reads.
## Steps
### 1. Capture the Organization ID
In the Genesys Cloud admin console, go to **Account > Organization Settings > Organization Details** and copy the **Organization ID**. Operata configures Amazon EventBridge and Secrets Manager against this ID.
Save the Organization ID alongside your Operata Group ID. You need both in step 4.
### 2. Create the OAuth client
Genesys Cloud uses role-based access control. Create an access role with the permissions Operata needs, then assign that role to an OAuth client.
**Create the access role:**
In the Genesys Cloud admin console, go to **User Management > Roles and Permissions > Add Role**. On the **Roles** tab, enter:
* **Name:** `OPERATA_Role`
* **Description:** `RBAC for Operata OAuth Client`
Switch to the **Permissions** tab. Search for and select:
* Analytics > Conversation Aggregate > View
* Analytics > Conversation Detail > View
* Routing > Queue > View
* Users > customAttributesSchema > View
* Users > ruleDependents > View
* Users > Rules > View
* Users > ruleUsers > View
Click **Save**.
**Create the OAuth client:**
Navigate to **IT and Integrations > OAuth > Add Client**. Enter:
* **App Name:** `OPERATA_OAuth Client`
* **Description:** `Generated Client that's passed to the App Backend`
* **Grant Types:** Client Credentials
Click **Next**. On the role-assignment screen, toggle the **Assigned** column for the `OPERATA_Role` you created above and click **Next**.
Leave the default token duration of `86400` seconds (24 hours) and click **Save**.
Genesys Cloud now displays the **Client ID** and **Client Secret**.
Genesys Cloud displays the Client Secret exactly once. Copy both values into a secure location before clicking **Finish**. Operata needs the Client ID and Client Secret in step 4; you cannot retrieve the secret afterwards.
Click **Finish** once both values are saved.
### 3. Configure the Amazon EventBridge source
Operata reads Genesys Cloud events from Amazon EventBridge. Each Operata group supports exactly one Genesys Cloud Amazon EventBridge integration; if you already have one set up, skip to step 4.
Navigate to **IT and Integrations > Integrations > Add Integration**. Click **Install** on the **Amazon EventBridge** Source tile.
On the **Details** tab, set:
* **Integration Name:** `Operata AWS EventBridge`
Click **Save**.
Switch to the **Configuration** tab and enter:
* **AWS account ID:** `287581919123`
* **AWS account region:** `ap-southeast-2` or `us-east-2`, matching your Operata group region.
* **Event source suffix:** your Operata Group ID from the Before you start section.
* **Topic filtering:** `v2.detail.events.conversation.{id}.user.end`
Use the AWS account ID and region exactly as shown above — these are Operata's values, not yours. Substituting your own AWS account ID or Genesys-side region breaks the integration; the events never reach Operata.
Click **Save and Activate**. Genesys Cloud now sends conversation-end events to Operata's AWS account.
If you create a second event source with the same Operata Group ID, Genesys Cloud returns **Event Source Suffix value must be unique**. Each Operata group supports only one Genesys Cloud Amazon EventBridge integration; reuse the existing source rather than creating a new one.
### 4. Configure Operata
In the Operata console, go to **Group Settings > Genesys Softphone Configuration > Org Id**. Enter the Organization ID you copied in step 1, leave the remaining fields as they are, and click **Save**.
Operata completes the AWS-side configuration (Amazon EventBridge rules, Secrets Manager entry for the OAuth credentials) for you. Open a support ticket with [Operata Support](mailto:support@operata.com) including:
* Organization ID from step 1.
* OAuth Client ID and Client Secret from step 2.
* Genesys Cloud AWS region (so Operata picks the correct API URL for the Fetcher Service).
Operata confirms once the integration is active.
## Verify
Place a test interaction through your Genesys Cloud organization and end the Conversation cleanly. In the Operata console, open **Contacts** and filter to the last 10 minutes. The Conversation appears within five minutes of conversation end, with the `conversationId` matching the Genesys Cloud value.
## Related
* [Configure Genesys Cloud redaction](/docs/genesys-privacy) — Allow or deny fields the Fetcher Service forwards to Operata.
* [Genesys Cloud integration overview](/docs/genesys-overview) — The Amazon EventBridge topics and REST endpoints Operata uses, plus the mandatory observability fields.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — The model the Fetcher Service applies.
* [Genesys data glossary](/docs/resources-data-collection-genesys) — The fields Operata can deliver from Genesys Cloud.
# Genesys Cloud integration
Source: https://docs.operata.com/docs/genesys-overview
Connect Genesys Cloud to Operata and get real-time CX observability over every Conversation — quality signals, analytics, and insights in one place.
Connect Genesys Cloud to Operata and get real-time visibility over every Conversation — whether a human agent or an AI agent handled it — so you can see why call quality, routing outcomes, and customer results are what they are. Operata is CX observability for cloud contact centers.
The integration runs without touching call audio or agent desktops. Genesys Cloud streams analytics and platform events to Operata via Amazon EventBridge (the primary ingestion path), and a read-only OAuth client lets Operata fetch the canonical Conversation Detail record on each conversation end. Operata stitches those signals into observations, derives insights, and surfaces them in the Operata console and over the API.
The Genesys Cloud integration shares the redaction model with the [Cloud Collector](/docs/concepts-cloud-collector) on Amazon Connect — field-level deny policies you define apply consistently across both platforms.
## How it works
Operata reads Genesys Cloud through two channels.
* **Amazon EventBridge** is the primary ingestion path. Genesys Cloud publishes analytics, operational, and platform events to an EventBridge event bus in Operata's AWS account. Amazon EventBridge rules forward the events to the Operata ingestion endpoint over HTTPS.
* **Genesys Cloud REST APIs** provide the enrichment path. On conversation end, Operata calls a small set of read-only endpoints to fetch the canonical Conversation Detail record and any optional enrichment data you have enabled.
Operata does not access call audio, agent desktops, or screen recordings. The integration uses OAuth 2.0 client credentials with least-privilege scopes; you can revoke access from the Genesys Cloud admin console at any time.
```mermaid theme={null}
flowchart LR
G[Genesys Cloud] -->|EventBridge| B[Operata event bus]
B -->|HTTPS| I[Operata ingestion endpoint]
F[Operata Fetcher Service] -->|read-only REST| G
I --> F
```
## Amazon EventBridge topics Operata subscribes to
Operata subscribes to the following topics. These are metadata and analytics events only; no media flows through Amazon EventBridge.
| Category | Topic pattern | Purpose |
| - | - | - |
| Conversation analytics and lifecycle | `v2.detail.events.conversation.{conversationId}.*` | Per-interaction lifecycle, IVR and flow timeline, routing outcomes, call disposition. |
| Conversation end | `v2.detail.events.conversation.{id}.user.end` | Triggers the Operata Fetcher Service to retrieve full conversation details. |
| Conversation metrics | `v2.analytics.conversation.{conversationId}.metrics` | Per-interaction metrics (handle, queue, talk, hold, ACD). |
| Queue and agent real-time state | `v2.analytics.queues.{queueId}.observations`, `v2.users.{userId}.routingStatus`, `v2.users.{userId}.activity` | Real-time queue depth, staffing, agent routing availability. |
| Platform and operational health | `v2.operations.events.{eventId}` | Telephony or Edge issues, flow failures, degradation. |
| Speech and CX signals (optional) | `v2.speechandtextanalytics.conversation.{conversationId}.sentiment`, `v2.speechandtextanalytics.conversation.{conversationId}.empathy` | Sentiment and empathy analysis. Textual metadata only; no raw audio. |
| Analytics data availability (optional) | `v2.analytics.conversations.details.jobs.availability` | Signals availability of bulk conversation detail data for backfill or reconciliation. |
## REST APIs Operata calls
Amazon EventBridge provides signals and deltas. Operata calls REST APIs to enrich and reconcile.
**Analytics (read-only):**
* `POST /api/v2/analytics/queues/aggregates/query` — queue KPIs (ASA, service level, abandons, volume).
* `POST /api/v2/analytics/users/aggregates/query` — agent KPIs (AHT, handled, occupancy).
* `POST /api/v2/analytics/conversations/aggregates/query` — KPIs across interactions.
* `GET /api/v2/analytics/conversations/{conversationId}/details` — the canonical Conversation Detail record (CDR equivalent).
* `POST /api/v2/analytics/conversations/details/query` — bulk query for backfill and reconciliation.
**Configuration and reference data (read-only):**
* `GET /api/v2/routing/queues` — queue name and config lookup.
* `GET /api/v2/flows` — flow and IVR name resolution.
* `GET /api/v2/users` — user and agent identity resolution.
* `GET /api/v2/telephony/providers/edges`, `GET /api/v2/telephony/siptrunks` — telephony context.
**Optional enrichment:**
* `GET /api/v2/conversations/calls/{conversationId}` — additional Conversation metadata.
* `GET /api/v2/recordings/conversations/{conversationId}` — recording metadata only, never audio.
* `/api/v2/speechandtextanalytics/*` — sentiment, topics, and transcript-derived analytics (when enabled).
* `/api/v2/quality/evaluations` — QM scores (when enabled).
* `GET /api/v2/audit/organization/configuration` — configuration change history.
Genesys Cloud does not expose a single CDR or CTR object. The Conversation Detail record from the Analytics Conversations API is the canonical equivalent. On every `v2.detail.events.conversation.*.user.end` event, the Fetcher Service calls `GET /api/v2/analytics/conversations/{conversationId}/details` to load the full record.
## OAuth scopes required
Operata uses client-credentials OAuth with least-privilege scopes. No write permissions are required.
**Core required:**
* `analytics:read`
* `routing:read`
* `users:read`
**Common optional enrichment:**
* `conversations:read`
**Optional, feature-dependent:**
* `speechTextAnalytics:read`
* `recording:read` (metadata only)
* `quality:read`
* `telephony:read`
* `audit:read`
## Verify
In the Operata console, open **Group Settings > Integrations**. The **Genesys Cloud** integration appears with status `Active` once the Fetcher Service receives its first conversation-end event and resolves the Conversation Detail record. Per-conversation analytics appear in the **Contacts** view within five minutes of conversation end.
## Mandatory observability fields
For Operata to deliver observability analytics on Genesys Cloud, the following fields must reach the platform. The Fetcher Service treats these as Mandatory tier; you cannot deny, encrypt, or transform them through the redaction config.
**EventBridge — conversation end event**
* `Event.Conversation.data.source`
* `Event.Conversation.data.timestamp`
* `Event.Conversation.data.conversationId`
**API — `GET /users/{id}`**
* `API.Users.username`
**API — `GET /conversations/{id}/details`**
* `API.Conversation.participants[purpose=*].sessions[*].edgeId`
* `API.Conversation.participants[purpose=agent]`
* `API.Conversation.divisionIds`
* `API.Conversations.participants[purpose=customer].sessions[*].segments[type=interact].disconnectType`
* `API.Conversations.participants[purpose=external].sessions[*].segments[type=interact].disconnectType`
* `API.Conversation.conversationId`
* `API.Conversation.originatingDirection`
* `API.Conversation.conversationStart`
* `API.Conversation.conversationEnd`
* `API.Conversation.participants[purpose=acd]`
* `API.Conversations.participants[*].sessions[*].mediaEndpointStats`
* `API.Conversation.mediaStatsMinConversationMos`
* `API.Conversation.mediaStatsMinConversationRFactor`
* `API.Conversations.participants[*].sessions[*].mediaType`
* `API.Conversation.participants[purpose=customer].sessions[*].dnis`
* `API.Conversation.participants[purpose=external].sessions[*].dnis`
## Related
* [Install the Genesys Cloud integration](/docs/genesys-installation) — Set up the OAuth client, Amazon EventBridge source, and Operata configuration.
* [Configure Genesys Cloud redaction](/docs/genesys-privacy) — Allow or deny fields the Fetcher Service forwards to Operata.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — The cross-integration model the Fetcher Service implements.
* [Mandatory observability fields](#mandatory-observability-fields) — The fields Operata always retains.
# Genesys Cloud redaction schema
Source: https://docs.operata.com/docs/genesys-privacy
Field tiers, processing order, and the mandatory keep-list the Operata Fetcher Service enforces when it ingests Genesys Cloud Conversation data.
The Operata Fetcher Service enforces these field-tier rules when it ingests Genesys Cloud Conversation data. The Fetcher Service runs in Operata's managed infrastructure, polls the Genesys Cloud API on conversation end, and ships only the surviving payload to Operata.
For the model behind the schema and the rollout procedure, see
[Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction)
and [Configure Genesys Cloud redaction](/docs/guides-configure-genesys-redaction).
This schema applies to the Genesys Cloud integration only. Amazon
Connect CTR, Contact Flow Log, and Lex integrations have their own
schemas.
## Field tiers
Every field in a Genesys Cloud event or API response belongs to exactly one of six tiers.
| Tier | Behavior | Controlled by |
| - | - | - |
| Mandatory | Key and value transmitted unchanged. Cannot be denied, hashed, encrypted, or redacted. | Operata |
| Allow | Key and value transmitted unchanged. Customer-declared. | Customer |
| Deny | Key and value removed entirely. Operata never sees the field. | Customer |
| Encrypt | Key retained, value replaced with a hash or ciphertext. | Customer |
| Transform | Key retained, value replaced with derived or calculated data. | Customer |
| Default | Key retained, value nullified. | Default |
The four customer-configurable tiers (Allow, Deny, Encrypt, Transform) are mutually exclusive: any one field appears in at most one tier.
## Processing order
The Fetcher Service processes every event in four passes, in order.
1. **Mandatory override.** Check each field path against the mandatory
list. If a mandatory field sits under a denied parent, retain the
parent and prune all non-mandatory siblings. Mandatory always wins.
2. **Deny.** Evaluate every remaining field path against the deny list.
Mark matched fields for removal.
3. **Allow, Encrypt, Transform.** Apply the customer-declared tiers to
the remaining fields.
4. **Default nullify.** Every field outside the previous three passes
keeps its key; its value becomes `null`.
## Path notation
All lists use dot notation against the JSON payload.
* A top-level key such as `conversation` matches the entire object at that key.
* A nested path such as `conversation.participants.name` matches only that specific subfield.
Rules apply at every depth consistently.
## Parent-key behavior
When a deny entry targets a parent and no mandatory entry references any child of that parent, the Fetcher Service removes the entire parent key. The key is absent from the output — not an empty object.
When a deny entry targets a parent and the mandatory, allow, encrypt, or transform list references one or more children of that parent, the Fetcher Service retains the parent containing only those referenced children. Every other child is removed regardless of whether it also appears in the deny list.
## Data flow
```text theme={null}
Genesys Cloud API
↓ (polled by Operata Fetcher Service)
Operata Fetcher Service
├─ Pass 1: Mandatory override
├─ Pass 2: Deny
├─ Pass 3: Allow / Encrypt / Transform
└─ Pass 4: Default nullify
↓ (filtered payload only)
Operata platform
```
## Policy caching
The Fetcher Service fetches the active redaction config from the Operata Config API and caches it for 30 minutes. If the API is unreachable or returns an invalid policy, the service falls back to the last valid policy in Operata's secure storage.
| Condition | Cached? | Fallback to stored policy? |
| - | - | - |
| `200 OK` plus valid policy | Yes (30 min) | No |
| `200 OK` plus empty or invalid body | No | Yes |
| `404 Not Found` | Yes | Yes |
| `5xx` server error | No | Yes |
| Network error | No | Yes |
If no valid policy exists in either location, the Fetcher Service marks the batch as failed until a valid config is available.
## Mandatory keep-list
The Fetcher Service always preserves these fields. The list is hard-coded; the redaction API rejects any rule that targets a mandatory field with `400 Bad Request`.
**EventBridge — conversation end event**
```text theme={null}
Event.Conversation.data.source
Event.Conversation.data.timestamp
Event.Conversation.data.conversationId
```
**API — `GET /users/{id}`**
```text theme={null}
API.Users.username
```
**API — `GET /conversations/{id}/details`**
```text theme={null}
API.Conversation.participants[purpose=*].sessions[*].edgeId
API.Conversation.participants[purpose=agent]
API.Conversation.divisionIds
API.Conversations.participants[purpose=customer].sessions[*].segments[type=interact].disconnectType
API.Conversations.participants[purpose=external].sessions[*].segments[type=interact].disconnectType
API.Conversation.conversationId
API.Conversation.originatingDirection
API.Conversation.conversationStart
API.Conversation.conversationEnd
API.Conversation.participants[purpose=acd]
API.Conversations.participants[*].sessions[*].mediaEndpointStats
API.Conversation.mediaStatsMinConversationMos
API.Conversation.mediaStatsMinConversationRFactor
API.Conversations.participants[*].sessions[*].mediaType
API.Conversation.participants[purpose=customer].sessions[*].dnis
API.Conversation.participants[purpose=external].sessions[*].dnis
```
## Common configurations
| Goal | Configuration |
| - | - |
| Drop customer phone numbers from the audit trail. | `Deny: customerPhone` |
| Keep queue names, drop agent emails. | `Allow: callDuration, queueName` and `Deny: agentEmail` |
| Hash customer identifiers, keep aggregates. | `Encrypt: customerId`, `Allow: queueName, callDuration` |
## Related
* [Configure Genesys Cloud redaction](/docs/guides-configure-genesys-redaction) — step-by-step rollout against the Operata Config API.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Genesys Cloud integration overview](/docs/genesys-overview) — the EventBridge topics and REST endpoints the schema applies to.
* [Install the Genesys Cloud integration](/docs/genesys-installation) — required before redaction config has any effect.
# Geolocation and ISP
Source: https://docs.operata.com/docs/geolocation-isp
City, region, country, and ISP for the agent endpoint, resolved by the Agent Collector from the public IP address detected at the start of each Amazon Connect Contact.
The geolocation and ISP (internet service provider) fields identify where the agent endpoint connected from. The Agent Collector resolves them from the agent's public IP address at the start of each Amazon Connect Contact.
## Schema
```json theme={null}
{
"agentCity": "Melbourne",
"agentRegion": "Victoria",
"agentCountry": "Australia",
"agentISP": "Bcd Networks Pty Ltd",
"agentExternalIPAddress": "103.120.49.101",
"agentIPAddress": "192.168.1.18"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `agentCity` | string | yes | City of the public IP detected for the agent endpoint. | `Melbourne` |
| `agentRegion` | string | yes | State or region of the public IP detected for the agent endpoint. | `Victoria` |
| `agentCountry` | string | yes | Country of the public IP detected for the agent endpoint. | `Australia` |
| `agentISP` | string | yes | ISP name resolved from the agent's public IP. | `Bcd Networks Pty Ltd` |
| `agentExternalIPAddress` | string (IPv4) | yes | Agent WAN IP address. | `103.120.49.101` |
| `agentIPAddress` | string (IPv4) | yes | Agent LAN IP address. | `192.168.1.18` |
## Notes
* All six fields are resolved once per Contact at connection time. If the agent's IP changes mid-contact (rare), the values reflect the IP at the moment the Contact started.
* `agentExternalIPAddress` and `agentIPAddress` also appear in the `network` object on the same contact record (see [Machine, browser, and network data](/docs/machine-browser-network)).
# How Operata works
Source: https://docs.operata.com/docs/get-started-architecture
Operata collects signals at the edge, interprets them as observations and insights in one pipeline, and exposes the result through applications, an API, and an agentic layer.
Operata does three things in order: it collects measurements where they happen, interprets them into a single record of what occurred, and exposes that record to the people and systems that act on it. Five capability layers carry those jobs.
## The five layers
| Platform layer | Type | What it is |
| - | - | - |
| [**Tenor**](/docs/guides-mcp-intro) | Agentics | The agentic layer. Tenor AI works over your CX data, and the Operata MCP Server exposes the same data to third-party AI agents. |
| [Surface](/docs/surface-overview) | Applications | Analytics, dashboards, synthetic assurance, and account controls. Where the result reaches a person. |
| [Core](/docs/core-overview) | Observability | The CX telemetry pipeline — ingestion, correlation, redaction, and the insight engine. Turns signals into observations, insights, and journeys. |
| [Signal](/docs/signal-overview) | Collection | Collectors that run at the edge — in the agent's browser and in your cloud account — and emit signals. |
| [Integrations](/docs/integrations-overview) | Sources | Connect your cloud contact center (CCaaS), Voice AI, and CX AI applications, install the collectors you need, and configure your policies. See the [full list](https://operata.com/platform/integrations). |
## Tenor — agentics
The action layer. A CX AI agent that works for people and for other AI agents, delivered where teams already are — Slack, Teams, and the Operata Platform. It splits by audience: autonomous root cause analysis and resolution for IT, plain-language analysis and charting for Ops, and readiness testing, prevention, and technical guidance for human agents. Tenor is available both in the console and through your AI assistant or your own agents.
## Signal — collection
Real-time data collection from both ends of the interaction. Cloud-side collectors pull from CX AI, Voice AI, and CCaaS platforms. Agent-side collectors capture first-party human agent data — headset, browser, network, and experience. Synthetics and assurance simulate load, round trips, and agent readiness on demand.
Four collection types feed Operata.
* The [Cloud Collector](/docs/concepts-cloud-collector) runs in your target collection environment. It collects data in real time, applies your redaction policy, and forwards the result.
* [Cloud Synthetics](/docs/concepts-cloud-orchestrator) runs synthetic Heartbeat checks and Virtual Agent calls against your application instance.
* The [Agent Collector](/docs/collector-overview) is a browser extension. It emits signals for headset audio levels, network quality, microphone state, page focus, and softphone CTI events — the agent-side measurements no central service can produce.
* [Agent Synthetics](/docs/help/agent-readiness-test) is integrated into the Agent Collector. It optionally lets human agents run Agent Readiness Tests — a real-world, end-to-end test of their environment.
The collectors run where the data lives — inside your application cloud, or in the human agent's browser — so your redaction policy runs before any data crosses the boundary to Operata.
## Surface — applications
Where CX observability becomes usable. End-to-end journey tracing, customizable dashboards and views across service elements, event-driven alerts and notifications across channels, assurance tools that continuously exercise CX apps and Voice AI agents, and a builder experience of docs, recipes, MCP servers, and APIs for humans and AI agents to build on.
* **Dashboards** in the Operata app render contacts, agents, cohorts, and the insights raised against them.
* [**Heartbeat**](/docs/heartbeat-setup) and the [**Virtual Agent**](/docs/virtual-agent) place and answer synthetic calls, so you measure the path end to end before a real customer hits the fault.
* The [API](/docs/api-getting-started) returns contacts, observations, insights, and logs, and Amazon [EventBridge](/docs/concepts-eventbridge) is the event path out. Operata publishes contact-lifecycle, insight, and Heartbeat events to a partner event bus in your AWS account, and you route them with standard EventBridge rules — to Lambda, SQS, Step Functions, or an HTTP API destination.
Downstream consumers read observations and insights — never raw signals.
## Core — observability
The CX telemetry pipeline. It traces interactions across CX platforms, monitors carriage, networks, VDI, and employee devices, captures and analyzes employee experience, and traces real-time AI agents and their handoffs. It turns all of that into CX domain insights, deviations from baseline, and the context graph of domain knowledge for IT and Ops.
Each collector emits [signals](/docs/concepts-signals-and-observations) — single timestamped measurements. Core ingests a signal, correlates it with the contact it belongs to, applies redaction and validation, and persists the result as an observation. Signals flow; observations are stored.
A [contact](/docs/concepts-contacts-and-interactions) is the per-platform record observations attach to. The [insight engine](/docs/concepts-insights) reads the observations on each contact and writes an insight when a known pattern matches — audio one-way, packet loss, agent inactivity, and the rest of the [insights catalog](/docs/insights-catalog). [Customer Journey Trace](/docs/concepts-customer-journey-trace) sits above contacts: when one customer crosses more than one platform, each platform's contact is one span of a single journey.
## Sources — integrations
The raw telemetry the platform is built on: logs, events, traces, metrics, metadata, and activity, drawn through 50+ Voice AI, CX AI, and CCaaS integrations. See the [full list](https://operata.com/platform/integrations).
## Why Operata splits signals from observations
The split isolates the wire format from the storage format. Redaction, deduplication, late-arrival reconciliation, and per-account validation all happen between the two, so the value a collector reports is not the value a consumer reads. CTRs can land 5–20 minutes after a contact ends; storing observations means a query returns a coherent partial view that fills in as more signals arrive, instead of a stream of half-correlated events.
It also means Core can add a new collector without changing anything above it. A new platform emits signals in its own shape, and the observations that reach Surface and Tenor keep the shape consumers already build against.
## Related
* [Signals and observations](/docs/concepts-signals-and-observations) — what each collector emits and how Operata stores it.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the per-platform record observations attach to.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how Operata links contacts across platforms.
* [Insights](/docs/concepts-insights) — the named detections Operata derives from observations.
* [Choose your integration](/docs/integrations-overview) — the platforms Operata collects from.
# Overview
Source: https://docs.operata.com/docs/get-started-overview
Operata is the observability control layer for CX. It connects the dots across technical, operational, and experience data from the whole customer journey, so you can improve it.
Operata is the observability control layer for CX. It collects performance data from every second of every contact across your Voice AI, CX AI, and cloud contact center platforms, then lets you monitor, assure, diagnose, and optimize from one place.
Operata joins those signals into observations against a single contact and derives insights from them. You read the result in dashboards, query it over the API, or react to it on your own event bus, such as Amazon EventBridge.
## What you can do
Three collectors gather contact records, agent-side network and headset telemetry, and synthetic test results — from the browser and from your cloud account.
Watch contacts, agents, and voice quality as they happen. Follow one customer across systems with Customer Journey Trace.
Prove the service works before agents log in. Heartbeat, Agent readiness, and Simulate test the path end to end.
Find the cause of poor audio, softphone errors, and dropped calls — down to the agent's device, network, and browser.
Rank CX risk, compare cohorts, and give agents in-the-moment guidance with Tenor.
Connect your cloud contact center, Voice AI, and CX AI platforms, install the collectors you need, and set your redaction policy.
## Build on it
Query contacts, observations, and insights. Configure redaction and receive webhooks.
Point Claude, Cursor, or ChatGPT at the Operata MCP Server and ask questions of your own contact data.
## Core concepts
* [Signals and observations](/docs/concepts-signals-and-observations) — a signal is a single timestamped measurement a collector emits; an observation is the persisted Operata record built from those signals.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the per-platform customer record Operata observes: Contact (Amazon Connect), Interaction (NICE CXOne), or Conversation (Genesys Cloud).
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how Operata stitches per-platform records into one cross-platform path.
* [Insights](/docs/concepts-insights) — named detections Operata derives from observations, surfaced in the CX Insights Graph.
## Start here
* [Choose your integration](/docs/integrations-overview) — Amazon Connect, Genesys Cloud, and NICE CXOne, plus Voice AI and CX AI vendors. See the [full list](https://operata.com/platform/integrations).
* [How Operata works](/docs/get-started-architecture) — the collection and processing path end to end.
* [Getting started](/docs/help/getting-started) — your first week in the app.
# Configure Contact Flow Log redaction
Source: https://docs.operata.com/docs/guides-configure-contact-flow-log-redaction
Apply a redaction policy to the contact-flow log Lambda so PII is stripped from every CloudWatch event before it reaches Operata.
Configure the contact-flow log redaction Lambda to apply your rules to every event it reads from CloudWatch, shipping only the surviving payload to Operata.
## Before you start
* The [Contact Flow Logs collection](/docs/contact-flow-logs) stack deployed against your Amazon Connect instance.
* An Operata API token with admin permissions. See [Authentication](/docs/api-authentication).
* The list of Contact Flow Log field paths you want to allow, deny, encrypt, or transform. The schema and the mandatory keep-list live in [Contact Flow Log redaction schema](/docs/contact-flow-log-privacy).
Today only the Mandatory tier is enforced end to end. Allow, Deny, Encrypt, and Transform rules are accepted in the config but applied as pass-through. Follow the [Operata changelog](/docs/changelog) for rollout.
## Steps
### 1. Draft your rules
Path notation is dot-delimited against the Contact Flow Log JSON payload. `Parameters` matches the entire object; `Parameters.CustomerCardNumber` matches one subfield. Rules apply at every depth.
Common drafts:
```json theme={null}
{
"rules": [
{ "type": "DENY", "field": "Parameters.CustomerCardNumber" },
{ "type": "ALLOW", "field": "Parameters.Queue" },
{ "type": "ENCRYPT", "field": "Parameters.TextInput" }
]
}
```
Rules that target a mandatory field are rejected. See [Contact Flow Log redaction schema](/docs/contact-flow-log-privacy#mandatory-keep-list) for the full list.
### 2. Send the policy to Operata Support
The customer-facing API for Contact Flow Log redaction policies is not yet public. Send your drafted ruleset to [Operata Support](mailto:support@operata.com) with the Operata Group ID you want it applied to. Operata installs the policy against your Lambda and confirms when it is live.
### 3. Wait for the Lambda to pick up the new policy
The redaction Lambda reads the active policy on each invocation. Allow up to a minute for in-flight events to drain under the previous policy. The new policy has no effect on events the Lambda already collected — redaction runs at ingest time, not retroactively.
## Result
Place a test contact through the contact flow you instrumented, then read the matching contact back through the Operata API. Denied fields drop from the response, the mandatory keep-list survives, and every other field's value is `null` until Allow, Encrypt, and Transform reach end-to-end enforcement.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-18T23:59:59Z&size=1"
```
## Related
* [Contact Flow Log redaction schema](/docs/contact-flow-log-privacy) — field tiers, mandatory keep-list, and processing order.
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Configure Lex redaction](/docs/guides-configure-lex-redaction) — the sibling rollout for Amazon Lex conversation logs.
# Configure CTR redaction
Source: https://docs.operata.com/docs/guides-configure-ctr-redaction
Strip PII from Amazon Connect Contact Trace Records before they leave your AWS account by setting an allow-list or deny-list through the Operata API.
Configure the Cloud Collector to apply your allow-list or deny-list to every Amazon Connect Contact Trace Record (CTR) before it leaves your AWS account.
## Before you start
* The [Cloud Collector CloudFormation stack](/docs/ctr-installation) deployed against your Amazon Connect instance.
* An Operata API token with admin permissions. See [Authentication](/docs/api-authentication).
* The list of CTR fields you want to allow or deny. The field names follow the [CTR data model](/docs/contact-trace-records).
## Steps
### 1. Read the active config
Confirm what the Cloud Collector is using today before you replace it. A `404` means no config exists and the privacy-first default is in effect — the Cloud Collector ships only the mandatory CTR fields.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/config/REDACTION_CONFIG/json"
```
### 2. Decide allow-list or deny-list
One config per Operata account. The two shapes are mutually exclusive.
* Use a deny-list (`BLACKLIST`) to ship the full CTR minus the fields you name. Suits accounts that already vet what Amazon Connect emits.
* Use an allow-list (`WHITELIST`) to ship only the mandatory fields plus the fields you name. Suits accounts under tight data-egress controls.
The mandatory keep-list and field semantics live in [Data redaction](/docs/api-data-redaction).
### 3. Apply the new config
`PUT /v1/config/json` is a full replace, not a patch. Send every field you want active in one body.
```bash theme={null}
curl -X PUT -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "REDACTION_CONFIG",
"value": {
"type": "BLACKLIST",
"fields": ["Attributes.CustomerDetails"]
}
}' \
"https://api.operata.io/v1/config/json"
```
A `200 OK` with body `REDACTION_CONFIG updated` confirms the new policy is durable. A `400` with `REDACTION_CONFIG not valid` means the body failed validation — see [Update redaction config](/docs/api-update-redaction-config) for the body schema.
### 4. Wait for propagation
The Cloud Collector caches the active config and refreshes it on a 30-minute interval. Contacts that end inside the propagation window may still ship under the previous policy. For changes that must take effect immediately, stop the EventBridge pipe, wait for the refresh, then restart.
## Result
Place a test contact (see [Send your first observation](/docs/guides-send-first-observation) for the procedure), then read the contact back through the API. On an allow-list, only the mandatory fields plus the fields you named appear. On a deny-list, the named fields are absent from the response payload.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-18T23:59:59Z&size=1"
```
## Related
* [Data redaction](/docs/api-data-redaction) — the reference index for the config schema, mandatory fields, and propagation contract.
* [Update redaction config](/docs/api-update-redaction-config) — every parameter and error code on the `PUT`.
* [Delete redaction config](/docs/api-delete-redaction-config) — remove the config and revert to the privacy-first default.
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the model behind allow-list, deny-list, and edge filtering.
# Configure Genesys Cloud redaction
Source: https://docs.operata.com/docs/guides-configure-genesys-redaction
Apply a redaction policy to the Operata Fetcher Service so PII is stripped from Genesys Cloud Conversation data before it reaches the Operata platform.
Configure the Operata Fetcher Service to apply your redaction policy to every Genesys Cloud Conversation it polls, shipping only the surviving payload to Operata.
## Before you start
* The [Genesys Cloud integration](/docs/genesys-installation) installed against your Operata account.
* An Operata API token with admin permissions. See [Authentication](/docs/api-authentication).
* The list of Genesys Cloud field paths you want to allow, deny, encrypt, or transform. The schema and the mandatory keep-list live in [Genesys Cloud redaction schema](/docs/genesys-privacy).
## Steps
### 1. Read the current policy
Inspect what the Fetcher Service is enforcing today before you replace it.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/config/source/genesys/gcd/redaction"
```
The response carries the full policy across all tiers — `MANDATORY`, `ALLOW`, `DENY`, `ENCRYPT`, `TRANSFORM`.
### 2. Draft your rules
The four customer-configurable tiers are mutually exclusive: any one field appears in at most one tier. Path notation is dot-delimited against the JSON payload, applied at every depth.
Each rule is a `{ "type", "field" }` pair. Common drafts:
```json theme={null}
{
"rules": [
{ "type": "DENY", "field": "customerPhone" },
{ "type": "DENY", "field": "agentEmail" },
{ "type": "ALLOW", "field": "callDuration" },
{ "type": "ALLOW", "field": "queueName" },
{ "type": "ENCRYPT", "field": "customerId" }
]
}
```
Rules that target a mandatory field cause the API to reject the policy with `400`.
### 3. Post the policy
`POST` replaces the active policy in full. Any rule you omit drops out of the policy.
```bash theme={null}
curl -X POST -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{ "type": "DENY", "field": "customerPhone" },
{ "type": "ALLOW", "field": "queueName" }
]
}' \
"https://api.operata.io/v1/config/source/genesys/gcd/redaction"
```
A `200 OK` confirms the new policy is durable. A `400` means a rule targeted a mandatory field or the body failed validation.
### 4. Wait for the cache to refresh
The Fetcher Service caches the policy for 30 minutes. Conversations that end inside that window may still ship under the previous policy. The new policy has no effect on conversations the Fetcher Service already collected — redaction runs at ingest time, not retroactively.
## Result
Wait for a real Genesys Cloud conversation to end, then read the resulting contact back through the Operata API. Denied fields are absent from the payload, encrypted fields appear as opaque ciphertext, allowed fields pass through unchanged, and every other field's value is `null`.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-18T23:59:59Z&size=1"
```
## Related
* [Genesys Cloud redaction schema](/docs/genesys-privacy) — field tiers, mandatory keep-list, processing order, and the cache-fallback table.
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Genesys Cloud integration overview](/docs/genesys-overview) — the EventBridge topics and REST endpoints the schema applies to.
# Configure Amazon Lex redaction
Source: https://docs.operata.com/docs/guides-configure-lex-redaction
Apply a redaction policy to the Amazon Lex Lambda so PII is stripped from every Lex conversation event before it reaches Operata.
Configure the Amazon Lex redaction Lambda to apply your rules to every Amazon Lex conversation event it reads from CloudWatch, shipping only the surviving payload to Operata.
## Before you start
* The [Amazon Lex integration](/docs/lex-integration) stack deployed against your Amazon Connect instance.
* An Operata API token with admin permissions. See [Authentication](/docs/api-authentication).
* The list of Amazon Lex field paths you want to allow, deny, encrypt, or transform. The schema and the mandatory keep-list live in [Lex redaction schema](/docs/lex-privacy).
Today only the Mandatory tier is enforced end to end. Allow, Deny, Encrypt, and Transform rules are accepted in the config but applied as pass-through. Follow the [Operata changelog](/docs/changelog) for rollout.
## Steps
### 1. Draft your rules
Path notation is dot-delimited against the Lex V2 conversation log JSON payload. Rules apply at every depth. A wildcard segment such as `interpretations.intent.slots.*.shape` matches every slot name.
Common drafts:
```json theme={null}
{
"rules": [
{ "type": "DENY", "field": "interpretations.intent.slots.cardNumber" },
{ "type": "ALLOW", "field": "interpretations.intent.name" },
{ "type": "ENCRYPT", "field": "transcriptions.transcript" }
]
}
```
Rules that target a mandatory field are rejected. The mandatory keep-list includes `sessionId`, `bot`, `interpretations.intent.name`, and the `x-amz-lex:*` session attributes — see [Lex redaction schema](/docs/lex-privacy#mandatory-keep-list) for the full list.
### 2. Send the policy to Operata Support
The customer-facing API for Lex redaction policies is not yet public. Send your drafted ruleset to [Operata Support](mailto:support@operata.com) with the Operata Group ID you want it applied to. Operata installs the policy against your Lambda and confirms when it is live.
### 3. Wait for the Lambda to pick up the new policy
The redaction Lambda reads the active policy on each invocation. Allow up to a minute for in-flight events to drain under the previous policy. The new policy has no effect on events the Lambda already collected — redaction runs at ingest time, not retroactively.
## Result
Place a test contact that routes through your Lex bot, then read the matching contact back through the Operata API. Denied slot or transcript fields drop from the response, the mandatory keep-list survives, and every other field's value is `null` until Allow, Encrypt, and Transform reach end-to-end enforcement.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-18T23:59:59Z&size=1"
```
## Related
* [Lex redaction schema](/docs/lex-privacy) — field tiers, mandatory keep-list, and processing order.
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Configure Contact Flow Log redaction](/docs/guides-configure-contact-flow-log-redaction) — the sibling rollout for Contact Flow Log data.
# Investigate CX incidents with AWS DevOps Agent
Source: https://docs.operata.com/docs/guides-mcp-aws-devops-agent
Register the Operata MCP Server with AWS DevOps Agent, so its investigations read live call quality and agent data alongside your AWS telemetry.
Your agents report choppy audio on inbound calls, and a CloudWatch alarm fires at the same time. AWS DevOps Agent investigates the AWS side on its own: metrics, logs, recent deployments, and your application topology. Connect it to the Operata MCP Server, and the same investigation can also see which calls degraded, on which network, for which agents, and what those agents reported.
This page is for the AWS administrator who runs DevOps Agent for a contact center team. The job is to register the Operata MCP Server once at the account level, then allowlist its tools in the Agent Space that handles CX incidents. There's no code to deploy.
## Use cases
* **An alarm fires on Amazon Connect.** The investigation checks your AWS resources, then queries Operata for the calls, queues, and sites that degraded in the same window.
* **A ticket names a bad call.** You paste the contact ID into the investigation, and the agent pulls that call's media quality, the agent's device and network, and any issue the agent reported.
* **A change goes out and you want to know if CX moved.** You ask in Chat whether mean opinion score (MOS), jitter, or round-trip time shifted after the deployment, and the agent compares before and after.
## How it works
DevOps Agent reaches Operata over MCP as the Operata user who authorized the connection. It discovers Operata's authorization server, registers its own OAuth client with Dynamic Client Registration (DCR), and stores the resulting token for you.
```mermaid theme={null}
flowchart LR
I[Alarm, ticket, or
manual investigation] --> A
subgraph aws[Your AWS account]
A[Agent Space]
R[Operata MCP Server
registration]
T[(AWS telemetry
CloudWatch, CloudTrail)]
A -->|allowlisted tools| R
A --> T
end
subgraph op[Operata]
AS[Authorization server]
O[MCP server]
end
R -.->|DCR, then OAuth sign-in once| AS
R -->|OAuth access token| O
```
Registration happens at the account level and is shared by every Agent Space in that account. Each Agent Space then chooses which Operata tools it may call.
## Before you start
* An AWS account with AWS DevOps Agent and an Agent Space. This recipe was configured in `us-east-1`.
* Permission to register capability providers and edit the Agent Space.
* An Operata user with the **Admin** or **User** role to authorize the connection. **Viewer** accounts and **RBAC users** can't use the MCP Server.
The connection runs as whoever signs in to Operata during registration, and reaches only that user's groups. To give DevOps Agent access to more than one Operata Group, sign in with a service account that Operata creates for you, not a person's own login. Contact your Customer Success Manager to have one set up before you register the server.
## Choose a connection method
DCR is the recommended way to connect. DevOps Agent registers its own client with Operata, so there's no client ID or secret to create, store, or rotate. Access follows the signed-in user's role and groups, and every call is attributable to that user.
An API key is the alternative for a single group. See [API key alternative](#api-key-alternative) below.
## Steps
### 1. Register the Operata MCP Server
1. Sign in to the AWS Management Console and open the AWS DevOps Agent console.
2. Go to **Capability Providers** in the side navigation.
3. Find **MCP Server** under **Available** providers and choose **Register**.
4. On **MCP server details**, enter:
* **Name** — `operata`
* **Endpoint URL** — `https://mcp.operata.io/mcp`
* **Description** — see below
5. Select **Enable Dynamic Client Registration**, then choose **Next**.
6. Under **Authorization flow**, select **OAuth 3LO**, then choose **Next**.
7. Review the details and choose **Submit**.
8. The Operata sign-in page opens. Sign in with the account that should own the connection, and approve access. You return to the DevOps Agent console.
DevOps Agent validates the connection, and the server appears under **Capability Providers** with the authorization method `oauth-3lo`.
The description helps the agent decide when Operata is the right source. Something like:
```text Example - server description theme={null}
Operata CX observability for the contact center. Call quality (MOS, jitter,
packet loss, round-trip time), agent softphone, device, and network
diagnostics, agent-reported issues, and end-to-end customer journey traces.
```
### 2. Add the server to your Agent Space
1. In the DevOps Agent console, select your Agent Space.
2. Open the **Capabilities** tab.
3. In **MCP Servers**, choose **Add**, then select `operata`.
4. Choose **Select specific tools** and allowlist the tools below.
5. Choose **Add**.
Every Operata tool reads data. None of them changes anything in your Operata account, so allowlist them as read-only. Check `switch_group` in particular: if it's classified as mutating, the agent needs operator approval every time it changes group.
| Tool | What the agent uses it for |
| :- | :- |
| `list_groups`, `switch_group` | Find and select the Operata Group to query. |
| `get_schema` | Learn valid services and field paths before querying. |
| `traces_list`, `traces_query`, `traces_get` | Find calls, aggregate quality metrics, and read a full trace. |
| `traces_insights`, `traces_span_logs` | Diagnose one trace and its spans. |
| `agent_logs`, `agent_status`, `agent_reported_issues` | Browser debug logs, presence changes, and issues agents reported. |
| `knowledge` | Search Operata documentation. |
See the [MCP tool reference](/docs/guides-mcp-tools) for what each tool takes and returns.
### 3. Run an investigation
Open the Agent Space web app, go to **Incident Response**, and describe the incident. Name Operata and the window so the agent knows to reach for it:
```text theme={null}
Agents on the Sydney site reported choppy audio on inbound calls from
09:00 to 10:30 UTC today. Use Operata to find which calls degraded and
what they have in common, then check our AWS networking and Amazon
Connect metrics for the same window.
```
If the connection reaches more than one group, name the group too, for example: *"Switch to the Operata Group Contact Center AU first."*
## What you get
The investigation timeline shows each Operata tool call next to the AWS evidence the agent gathered. A good run starts with `get_schema`, narrows the calls with `traces_query`, and opens the worst of them with `traces_get`. The summary then names the cause, such as degraded calls sharing one internet service provider or one agent site, with the numbers behind it.
You can steer a running or completed investigation with **Chat with investigation**, for example to ask the agent to compare against the previous week.
## API key alternative
If you only need one Operata Group and don't want the connection tied to a user, register the API-key endpoint `https://api.operata.io/v1/mcp` instead. Create the key in Operata under **Group Settings → API Management → Create New Key**.
The console's OAuth 3LO flow can't be scripted, but a bearer-token registration can:
```bash theme={null}
aws devops-agent register-service --region us-east-1 \
--service mcpserver \
--service-details '{
"mcpserver": {
"name": "operata-api-key",
"endpoint": "https://api.operata.io/v1/mcp",
"authorizationConfig": {
"bearerToken": {
"tokenName": "operata-mcp",
"tokenValue": "'"$OPERATA_API_KEY"'"
}
}
}
}'
```
The trade-offs are covered in [Choose how to connect](/docs/guides-mcp-intro#choose-how-to-connect): the key is fixed to its own group, and activity is attributed to the key rather than a person.
## Limits
* An Agent Space can allowlist up to 500 MCP tools across all MCP servers.
* A key-based connection shares 100 requests per minute across every investigation. See [Rate limits](/docs/api-rate-limits).
* An API key is fixed to its own group. `switch_group` to another group returns `403 "API key access is restricted to its own group"`.
* To remove the server, take it out of every Agent Space first, then deregister it under **Capability Providers**.
## Troubleshooting
| Symptom | Cause and fix |
| :- | :- |
| Registration fails after the Operata sign-in | The signing-in user is a **Viewer** or an **RBAC user**. Sign in with an **Admin** or **User** account. |
| `list_groups` returns only one group | The connection runs as a user with access to one group. Ask your Customer Success Manager for a multi-group service account, then re-authorize. |
| Operata calls start failing with an authorization error | The stored token is no longer valid, for example because the user's access changed. Select the server under **Capability Providers**, choose **Actions → Update**, and re-run the sign-in. Agent Space associations are kept. |
| The investigation never calls Operata | The prompt didn't point at CX data, or the tools aren't allowlisted in this Agent Space. Name Operata in the prompt and check **Capabilities → MCP Servers**. |
| `403 API key access is restricted to its own group` | The agent tried to switch groups on an API-key connection. Use the DCR connection, or keep to the key's group. |
More failure modes in [MCP troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [Operata MCP Server](/docs/guides-mcp-intro) — authentication, groups, and regions.
* [MCP tool reference](/docs/guides-mcp-tools) — what each tool takes and returns.
* [Diagnose voice incidents with Amazon Bedrock](/docs/guides-mcp-bedrock-agentcore) — the same data from your own Lambda.
* [Connecting MCP servers](https://docs.aws.amazon.com/devopsagent/latest/userguide/configuring-integrations-and-knowledge-connecting-mcp-servers.html) — AWS documentation.
* [Autonomous incident response](https://docs.aws.amazon.com/devopsagent/latest/userguide/production-operations-autonomous-incident-response.html) — AWS documentation.
# Diagnose voice incidents with Amazon Bedrock
Source: https://docs.operata.com/docs/guides-mcp-bedrock-agentcore
Build a Lambda that hands a voice quality alarm to a Bedrock model with live access to your Operata data, and gets back a diagnosis with the numbers behind it.
A voice quality alarm fires at 3am. Rather than paging an engineer to open Operata and start querying, a Lambda hands the incident to a Claude model on Amazon Bedrock. The model queries your live Operata data and comes back with the cause: 130 calls averaging a mean opinion score (MOS) of 2.93, jitter at three times the fleet baseline, and round-trip time near half a second — all of it on one internet service provider in one city.
That model reaches Operata through Amazon Bedrock AgentCore Gateway, a managed tool-access layer that holds your Operata credential and exposes the Operata MCP tools to the model. This page is for engineers running an AWS Lambda function that already orchestrates incident response. The job is to stand up the gateway, then call Operata tools from a Bedrock tool-calling loop.
The runnable version of everything on this page: the deploy scripts, the Lambda code, and a teardown. Fork it, set six values, run three scripts.
## Use cases
The shape is the same wherever something automated needs evidence from Operata:
* **A monitoring alarm fires.** The Lambda passes the alarm detail to the model, which queries traces and agent reports, and posts a diagnosis to the incident channel before anyone opens a dashboard.
* **A support ticket arrives naming a bad call.** The Lambda passes the contact ID, and the model returns that call's media quality, the agent's device and network conditions, and what the agent reported.
* **A scheduled run each morning.** The model compares yesterday against the fleet baseline and writes up the sites, carriers, or agents that moved.
Each one is the same gateway and the same tool-calling loop, with a different trigger and prompt.
## How it works
Your Lambda keeps owning the workflow. The gateway sits between it and Operata, and the Operata API key lives in the gateway rather than in your function.
```mermaid theme={null}
flowchart LR
E[Incident event] --> L
subgraph aws[Your AWS account]
L[Lambda orchestrator]
B[Bedrock Claude]
G[AgentCore Gateway]
S[(Credential provider
Secrets Manager)]
L <-->|Converse loop, toolUse blocks| B
L -->|MCP JSON-RPC, signed with SigV4| G
G -.->|reads the Operata key| S
end
subgraph op[Operata]
O[MCP server]
end
G -->|API key in the Authorization header| O
```
The gateway authenticates on both sides. Inbound is `AWS_IAM`, so the Lambda execution role signs each request with SigV4 — no Amazon Cognito user pool, no client secret, and no token cache to run. Outbound is the Operata API key, which the gateway reads from the credential provider and sends as a bearer token.
## Before you start
* An AWS account with Bedrock model access for Claude, in a region where AgentCore Gateway is available. This recipe was deployed and verified in `us-west-2`.
* Permission to create IAM roles, AgentCore gateways and targets, and a Lambda function.
* `git`, AWS CLI v2, `curl` 7.75 or later, `jq`, and `zip`. The scripts sign gateway calls with `curl --aws-sigv4`.
* An Operata API key, created in the Operata console at `app.operata.io` under **Group Settings → API Management → Create New Key**.
Use that key against the API-key MCP endpoint, `https://api.operata.io/v1/mcp`.
## Why this recipe uses an API key
Operata's authorization server advertises the `authorization_code` and `refresh_token` grant types. Every OAuth token it issues is bound to a person who consented in a browser, which does not suit a Lambda that a monitoring alarm triggers with nobody present. The API-key endpoint is the path for unattended callers.
For a Lambda, that trade is narrow: the key is fixed to one Operata group, and all activity is attributed to the key rather than to an individual. See [Choose how to connect](/docs/guides-mcp-intro#choose-how-to-connect) for how the two paths differ across clients.
## Quickstart
```bash theme={null}
git clone https://github.com/operata/operata-mcp-recipes.git
cd operata-mcp-recipes/bedrock-agentcore
cp config.env.example config.env
$EDITOR config.env # set OPERATA_API_KEY, check the region and model
./scripts/deploy-gateway.sh # role, credential provider, gateway, Operata target
./scripts/verify.sh # lists the tools and makes a live call
./scripts/deploy-lambda.sh # execution role, package, function
./scripts/run-incident.sh # invoke against the sample incident
```
`deploy-gateway.sh` checks your key against Operata before it creates anything in AWS, so a rejected key fails in the first few seconds rather than part-way through. Both deploy scripts are re-runnable: they reuse what exists and update it in place. `./scripts/teardown.sh` removes everything they made.
The rest of this page explains what those scripts build, so you can read the result or rebuild it yourself.
## What the deploy creates
Four AWS resources, in order. Each one exists for a reason worth knowing before you run it.
### A gateway service role
The gateway assumes this role to fetch your Operata key at call time. Trust `bedrock-agentcore.amazonaws.com`, and condition that trust on your own account so no other account can assume it:
```json theme={null}
"Condition": {
"StringEquals": {"aws:SourceAccount": ""},
"ArnLike": {"aws:SourceArn": "arn:aws:bedrock-agentcore:::*"}
}
```
The role's policy grants three things: `bedrock-agentcore:GetWorkloadAccessToken` and `GetResourceApiKey` to fetch the credential, `secretsmanager:GetSecretValue` on `arn:aws:secretsmanager:::secret:bedrock-agentcore*` to read where AgentCore stored it, and `SynchronizeGatewayTargets` to re-index the tool catalogue.
### A credential provider holding the Operata key
AgentCore Identity takes the key and writes it to AWS Secrets Manager under a `bedrock-agentcore` prefix, which is what that secret ARN pattern above matches.
The key never reaches your Lambda, your deployment package, or the model. Only the gateway reads it.
### The gateway
```bash theme={null}
aws bedrock-agentcore-control create-gateway \
--protocol-type MCP \
--authorizer-type AWS_IAM \
--protocol-configuration '{"mcp":{"searchType":"SEMANTIC"}}' \
--role-arn "$ROLE_ARN" --name operata-mcp-gateway
```
Two parameters carry the design. `--authorizer-type AWS_IAM` is what removes the token plumbing: callers prove who they are with SigV4, using credentials they already hold. `searchType: SEMANTIC` adds a tool the model can use to search the tool catalogue, so it carries fewer schemas in context.
The scripts also set `exceptionLevel: DEBUG`, which returns readable target errors while you build. Remove it before production, because it exposes upstream detail in responses.
### A target pointing at Operata
The target names the Operata endpoint and says where the credential goes. Operata authenticates with `Authorization: Bearer `, so the key goes in the standard header with a `Bearer` prefix:
```json theme={null}
{
"credentialProviderType": "API_KEY",
"credentialProvider": {
"apiKeyCredentialProvider": {
"providerArn": "",
"credentialLocation": "HEADER",
"credentialParameterName": "Authorization",
"credentialPrefix": "Bearer"
}
}
}
```
Creating the target makes the gateway call `tools/list` upstream and index what it finds, so the target reaching `READY` confirms the key and the endpoint agree.
The target name becomes a prefix on every tool it exposes. With the target named `operata`, the `traces_query` tool arrives as `operata___traces_query` — three underscores.
Full scripts, including the polling and the re-run handling: [`scripts/deploy-gateway.sh`](https://github.com/operata/operata-mcp-recipes/blob/main/bedrock-agentcore/scripts/deploy-gateway.sh).
## Verify
```bash theme={null}
./scripts/verify.sh
```
The gateway returns 13 tools. Twelve are Operata's, each carrying the target name as a prefix:
```text theme={null}
operata___get_schema operata___traces_list operata___agent_logs
operata___knowledge operata___traces_query operata___agent_status
operata___list_groups operata___traces_get operata___agent_reported_issues
operata___switch_group operata___traces_insights
operata___traces_span_logs
```
[MCP tool reference](/docs/guides-mcp-tools) documents what each one takes and returns.
The thirteenth, `x_amz_bedrock_agentcore_search`, comes from the gateway because `searchType` is `SEMANTIC`. It lets the model search the tool catalogue instead of carrying every schema in context.
To exercise the credential against a single tool, call one directly:
```bash theme={null}
./scripts/call.sh list_groups
./scripts/call.sh knowledge '{"query":"What is jitter?"}'
```
## Use it in your own Lambda
Three files in [`lambda/`](https://github.com/operata/operata-mcp-recipes/tree/main/bedrock-agentcore/lambda) are the whole integration:
* [`mcp_gateway_client.py`](https://github.com/operata/operata-mcp-recipes/blob/main/bedrock-agentcore/lambda/mcp_gateway_client.py) — an MCP client that signs each request with SigV4 and negotiates the protocol version from what the gateway advertises. Standard library and `botocore` only, both already in the Lambda Python runtime, so the deployment package needs no vendored dependencies.
* [`incident_agent.py`](https://github.com/operata/operata-mcp-recipes/blob/main/bedrock-agentcore/lambda/incident_agent.py) — the Bedrock Converse tool-calling loop.
* [`handler.py`](https://github.com/operata/operata-mcp-recipes/blob/main/bedrock-agentcore/lambda/handler.py) — turns an incident event into a prompt and returns the diagnosis with a trace of every tool call.
Copy the first two into an existing function and set `GATEWAY_URL` and `MODEL_ID`. The loop itself is short — hand the gateway's tools to `converse`, run whatever the model asks for, and send the results back until it stops asking:
```python theme={null}
tool_config = mcp.to_bedrock_tool_config(mcp.list_tools())
messages = [{"role": "user", "content": [{"text": incident_prompt}]}]
for _ in range(MAX_TURNS):
response = bedrock.converse(
modelId=MODEL_ID, messages=messages,
system=[{"text": SYSTEM_PROMPT}], toolConfig=tool_config,
inferenceConfig={"maxTokens": 4096},
)
message = response["output"]["message"]
messages.append(message)
if response["stopReason"] != "tool_use":
return "".join(b["text"] for b in message["content"] if "text" in b)
results = []
for block in message["content"]:
if "toolUse" not in block:
continue
use = block["toolUse"]
text, is_error = mcp.flatten_result(mcp.call_tool(use["name"], use["input"]))
results.append({"toolResult": {
"toolUseId": use["toolUseId"],
"content": [{"text": text[:100_000]}],
"status": "error" if is_error else "success",
}})
messages.append({"role": "user", "content": results})
```
Return a tool failure to the model as a `toolResult` with `status: "error"` rather than raising. The model reads the message and adjusts its next call.
Beyond writing logs, the execution role needs two statements: `bedrock:InvokeModel`, and `bedrock-agentcore:InvokeGateway` on the gateway ARN. That second one is the inbound half of `AWS_IAM` auth — the role itself is what authorizes the call.
## What you get
`run-incident.sh` prints each tool call the model makes, then its diagnosis. One run against the sample incident took 9 turns and 12 tool calls. The model chose the sequence itself, starting with `get_schema` so the fields in its later queries would exist.
Its conclusion: 130 calls averaging MOS 2.93 against a fleet baseline of 3.90, with jitter at 37.8 ms against 11.3 ms and round-trip time at 458 ms against 95 ms — all on one internet service provider in one city, which is narrow enough to raise with that provider.
These figures, and the ones in the opening, come from a single account on one day. Your turn count, token count, and numbers will differ.
## Limits
* An API key is fixed to the group it was created in. Calling `switch_group` for a different group returns `403 "API key access is restricted to its own group"`. Switching to the key's own group succeeds.
* 100 requests per minute per key, shared across every caller of the gateway. See [Rate limits](/docs/api-rate-limits).
* The gateway indexes the tool list when you create the target. After Operata changes a tool, re-run `deploy-gateway.sh` or call `SynchronizeGatewayTargets` to pick up the new schema.
* Remove `exceptionLevel: DEBUG` before production.
## Troubleshooting
| Symptom | Cause |
| :- | :- |
| `Operata returned HTTP 401 for this key` during preflight | The key came from **Settings → Config → API** instead of **Group Settings → API Management**. The MCP endpoint rejects the REST API token. |
| 401 from Operata, identical with a valid key, a bad key, and no key | Operata validates the key ahead of the application, so a rejected key returns plain HTML with no `WWW-Authenticate` header. Re-check the key itself before suspecting the endpoint. |
| `403 Insufficient permissions` on the first Lambda run | The execution role is not visible to the gateway yet. If it persists, check that `bedrock-agentcore:InvokeGateway` names the gateway ARN. |
| Target reaches `SYNCHRONIZE_UNSUCCESSFUL` | The gateway could not complete `tools/list` upstream. Read `statusReasons` on the target. |
| `temperature is deprecated for this model` | Newer Claude models reject `temperature` in `inferenceConfig`. Remove it. |
| `Unsupported protocol version` | Negotiate from what the gateway advertises rather than pinning a version. |
| `curl lacks --aws-sigv4` | curl is older than 7.75. On macOS, `brew install curl`. |
More failure modes in [MCP troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [operata/operata-mcp-recipes](https://github.com/operata/operata-mcp-recipes/tree/main/bedrock-agentcore) — the scripts, the Lambda code, and a teardown.
* [Operata MCP server](/docs/guides-mcp-intro) — authentication, groups, and regions.
* [MCP tool reference](/docs/guides-mcp-tools) — what each tool takes and returns.
* [API authentication](/docs/api-authentication) — where Operata credentials come from.
* [MCP server targets](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-MCPservers.html) — AWS documentation.
* [Bedrock Converse tool use](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html) — AWS documentation.
# Connect ChatGPT to the Operata MCP server
Source: https://docs.operata.com/docs/guides-mcp-chatgpt
Add the Operata MCP Server to ChatGPT as a custom connector over OAuth so you can query your live Operata data from a chat.
Connect ChatGPT to the Operata MCP Server as a custom connector so you can query your Operata data from a chat. ChatGPT connects over OAuth and signs in as your Operata user, so there's no key to paste.
ChatGPT uses OAuth only. Unlike Claude and Cursor, it has no API key path. For how OAuth, roles, and groups work, see the [MCP overview](/docs/guides-mcp-intro).
## Before you start
* A **ChatGPT Pro or Plus** account. Custom connectors are a beta feature enabled through Developer Mode.
* An Operata user with the **Admin** or **User** role. **Viewer** accounts and **RBAC users** can't use the MCP Server. See [Before you start](/docs/guides-mcp-intro#before-you-start).
## Enable Developer Mode
1. In ChatGPT, open **Settings**.
2. Select the **Connectors** tab.
3. Open **Advanced settings** and toggle on **Developer Mode**. This unlocks custom connectors.
## Add the Operata connector
1. In **Connectors**, click **Create**.
2. Fill in the connector:
* **Name** — `Operata`.
* **MCP server URL** — `https://mcp.operata.io/mcp`.
* **Authentication** — set to **OAuth**.
3. Confirm that you trust the application, then create the connector.
## Authorize the connection
ChatGPT redirects you to the Operata sign-in to authorize the connection. Sign in as your Operata user and approve access. ChatGPT returns to the connector, now connected.
## Select a group
Pick the group you want to query: ask ChatGPT to run `list_groups`, then `switch_group`. Your OAuth session can reach every group your account is scoped to. See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions).
## Ask ChatGPT a question that uses Operata data
Turn on the Operata connector for the chat, then ask a question that needs Operata data:
> Using Operata, what percentage of calls had poor audio quality this month?
ChatGPT calls the right Operata tool — `traces_query` for an aggregate like this, or `knowledge` for a concept question — and answers from your account.
## Result
The Operata connector shows as connected in ChatGPT's Connectors settings, and a chat with the connector enabled returns a real value from your account. If authorization fails, confirm your Operata role is **Admin** or **User** and re-run the OAuth sign-in. See [Troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Connect Claude](/docs/guides-mcp-claude) — Claude Desktop, Claude Code, and the Claude API.
* [Connect Cursor](/docs/guides-mcp-cursor) — Cursor's MCP configuration.
* [Connect OpenCode](/docs/guides-mcp-opencode) — OpenCode's MCP configuration.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the CLI.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — roles and access for the Operata MCP Server.
# Connect Claude to the Operata MCP server
Source: https://docs.operata.com/docs/guides-mcp-claude
Add the Operata MCP Server to Claude Desktop, Claude Code, or the Claude API so Claude can query your live Operata data over the Model Context Protocol.
Connect a Claude client to the Operata MCP Server so Claude can query your real Operata data. Ask "how many traces in the last 30 days" and Claude answers from your account.
OAuth is the recommended way to connect. Use an API key only for automated, non-interactive integrations. For the difference, roles, and prerequisites, see the [MCP overview](/docs/guides-mcp-intro).
## Before you start
* An Operata account. For **OAuth**, a user with the **Admin** or **User** role; for an **API key**, an [Operata API key](/docs/api-authentication). See [Before you start](/docs/guides-mcp-intro#before-you-start).
* Claude Desktop, Claude Code, or the Claude API, installed and signed in.
## Connect over OAuth
### Claude Desktop
Open the Claude Desktop configuration file:
* macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
* Windows: `%APPDATA%\Claude\claude_desktop_config.json`
Add the Operata MCP server to the `mcpServers` object:
```json claude_desktop_config.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": ["mcp-remote@latest", "https://mcp.operata.io/mcp"]
}
}
}
```
Restart Claude Desktop. On first use, a browser window opens to sign in to Operata and authorize the session.
### Claude Code
Register the server against the OAuth endpoint:
```bash theme={null}
claude mcp add --transport http operata https://mcp.operata.io/mcp
```
Run `/mcp` inside Claude Code and follow the prompt to authenticate. Use `/mcp` again at any time to reconnect or re-authenticate.
### Claude API
Pass the Operata MCP server in the `mcp_servers` field of the request body. See Anthropic's [MCP connector documentation](https://docs.claude.com/en/docs/agents-and-tools/mcp-connector) for the request shape.
## Connect with an API key
Use the API key endpoint for automated integrations. The key can only reach the single group it was created in.
### Claude Desktop
```json claude_desktop_config.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": [
"mcp-remote@latest",
"https://api.operata.io/v1/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer "
}
}
}
}
```
Replace `` with your key, then restart Claude Desktop.
### Claude Code
```bash theme={null}
claude mcp add --transport http operata https://api.operata.io/v1/mcp \
--header "Authorization: Bearer $OPERATA_API_KEY"
```
## Select a group
On an OAuth session, pick the group you want to query: run `list_groups`, then `switch_group`. An API-key session is already fixed to its own group. See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions).
## Ask Claude a question that uses Operata data
Start a new conversation and ask something that needs Operata data:
> How many traces have been recorded in my Operata account in the last 30 days?
Claude calls the right Operata tool — `traces_query` for an aggregate like this, or `knowledge` for a concept question — and cites the tool call in its response.
## Result
Claude lists `operata` under available tools. A question that needs Operata data triggers a tool call and returns a real number from your account, not a placeholder. A `401` in the tool-call trace means the credential is wrong or expired; a `403` means a group problem. See [Troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Connect Cursor](/docs/guides-mcp-cursor) — the same server, configured for Cursor.
* [Connect ChatGPT](/docs/guides-mcp-chatgpt) — a ChatGPT custom connector over OAuth.
* [Connect OpenCode](/docs/guides-mcp-opencode) — OpenCode's MCP configuration.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the CLI.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
# Microsoft Copilot Studio
Source: https://docs.operata.com/docs/guides-mcp-copilot-studio
Add the Operata MCP Server as a tool in a Copilot Studio agent, so your team can ask about call quality and customer journeys in plain language.
Connect a Copilot Studio agent to the Operata MCP Server, and it can answer questions about call quality, agent experience, and customer journeys from your live Operata data. Publish that agent to Microsoft Teams or Microsoft 365 Copilot, and your whole team can get those answers in the tools they already use every day, without opening Operata.
Unlike the other clients, you set this up once for everyone who uses the agent, not only for yourself.
For authentication, groups, and regions, start with the [Operata MCP server](/docs/guides-mcp-intro) overview.
Copilot Studio supports the **Streamable HTTP** transport only. Server-Sent Events (SSE) has not been supported since August 2025. The Operata MCP Server uses Streamable HTTP, so no change is needed on your side.
## Before you start
* An active Operata subscription and credentials for your chosen endpoint — see [Choose how to connect](/docs/guides-mcp-intro#choose-how-to-connect).
* A Microsoft Copilot Studio license.
* Maker permissions in the Power Platform environment where the agent lives.
* Confirmation from your Power Platform administrator that your data policy permits the connection. MCP access in Copilot Studio runs through Power Platform connectors, so any data loss prevention (DLP) policy that governs connectors also governs this server. If the policy blocks it, the tool won't run for anyone.
## Choose an authentication method before you build
This decision is harder here than on other clients, and it's difficult to change later. Read this section before you open the wizard.
An agent is shared and long-running, used by many people. That cuts against the usual guidance of "OAuth for people, API keys for machines".
| | OAuth 2.0 | API key |
| :- | :- | :- |
| **Endpoint** | `https://mcp.operata.io/mcp` | `https://api.operata.io/v1/mcp` |
| **Acts as** | Each user, individually | One shared API user |
| **Group access** | Every group that user can reach | The single group the key belongs to |
| **Per-user sign-in** | Yes, each user authorizes once | No |
| **Audit trail** | Attributable to the individual | All activity attributed to the key |
| **Rate limit** | Per user session | 100 requests per minute, shared across every user of the agent |
**Use an API key** when the agent serves one contact center and everyone should see the same data. It's the simplest to deploy, with no per-user sign-in. The trade-offs: one group, and a rate limit shared across every user.
**Use OAuth 2.0** when users belong to different groups, or when you need activity attributable to individuals. Each person authorizes the connection once through the Connection Manager.
An API key is permanently scoped to the group it was created in. An agent built on an API key can't serve a customer with multiple groups — `switch_group` returns `403 "API key access is restricted to its own group"`. If you may need more than one group later, use OAuth now.
## Add the server with the onboarding wizard
The wizard is the recommended route. It creates the underlying Power Platform connector for you.
1. Open your agent in Copilot Studio and go to the **Tools** page.
2. Select **Add a tool**, then **New tool**.
3. Select **Model Context Protocol**. The MCP onboarding wizard opens.
4. Fill in the server details:
* **Server name** — `Operata CX Observability`
* **Server URL** — `https://mcp.operata.io/mcp` for OAuth, or `https://api.operata.io/v1/mcp` for an API key
* **Server description** — see below
5. Select the authentication type that matches your decision above, and provide the credential.
6. Select **Create**, then create the connection when the **Add tool** dialog appears.
### Write the description carefully
The agent's orchestrator reads the server description at runtime to decide whether to call Operata at all. A vague description means the agent answers from the model's general knowledge instead of your data. Something like:
```text Example - server description theme={null}
Operata CX observability for contact centers. Query live interaction traces,
call quality metrics (MOS, jitter, packet loss, round-trip time), agent
softphone and device diagnostics, IVR flow performance, bot and AI
interactions, and end-to-end customer journeys. Also searches Operata product
documentation. Use for any question about call quality, agent experience,
queue performance, or what happened on a specific call or contact ID.
```
## Alternative: create a custom connector
If you need to customize the connector, for example to add policies or fit an existing application lifecycle management (ALM) process, create it in Power Apps instead of using the wizard. Create a new custom connector using **Create from blank**, then point it at the Operata MCP endpoint.
Most teams should use the wizard.
## Test the agent
Use the **Test** pane in Copilot Studio before publishing.
If you're using OAuth, the first query prompts you to sign in. Select **Open Connection Manager**, select **Connect**, sign in with your Operata credentials, then return to the chat and select **Retry**.
Start with a question that forces a tool call:
```text theme={null}
Which of our queues had the worst average call quality last week?
```
Then confirm the agent is reading real data rather than improvising, by asking something only your account would know:
```text theme={null}
List the Operata groups this agent can access.
```
## Publish
Once the agent answers correctly in the Test pane, publish it and add the channels you need. Microsoft Teams and Microsoft 365 Copilot are the common choices. See Microsoft's guidance on connecting an agent to Teams and Microsoft 365 for channel setup and permissions.
Each user connecting through an OAuth-backed agent establishes their own connection on first use, via the Connection Manager.
## Select a group
Every query runs against one group.
* **OAuth** — the agent can call `list_groups` and `switch_group`. Consider naming the intended group in the agent's instructions so users don't have to, for example: *"Always switch to the group named Contact Center AU before answering."*
* **API key** — the key is fixed to its own group and there's nothing to select.
See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions) for detail. For more example prompts, see [Questions to ask your AI client](/docs/guides-mcp-intro#questions-to-ask-your-ai-client).
## Governance notes
* **DLP policies apply.** Because the server is reached through a Power Platform connector, your environment's data policy governs it. Review this with your Power Platform administrator before rolling the agent out.
* **The rate limit is shared.** An API-key agent shares 100 requests per minute across every user. A busy agent can exhaust this. OAuth spreads load across per-user sessions.
* **Who can reach the agent.** A published agent can expose Operata data to everyone on its channels. Traces contain PII such as customer phone numbers, agent names, and IP addresses, so confirm the audience before you publish. See [Best practices](/docs/guides-mcp-intro#best-practices) for privacy and least-privilege guidance.
## Troubleshooting
| Symptom | Cause and fix |
| :- | :- |
| The tool can't be added, or fails immediately for all users | A DLP policy is blocking the Power Platform connector. Ask your administrator to permit it. |
| Connection error mentioning transport or SSE | The server URL is wrong or points at a non-Streamable endpoint. Confirm you used one of the two documented URLs. |
| The agent answers from general knowledge and never calls Operata | The server description is too vague. Rewrite it to name the data and the questions it answers. |
| `403 API key access is restricted to its own group` | The agent tried to switch groups on an API-key connection. Use OAuth, or restrict the agent to the key's group. |
| Users are repeatedly prompted to sign in | The connection wasn't completed in the Connection Manager. Have the user select **Connect**, sign in, then **Retry** the query. |
| Intermittent failures at busy times | The shared rate limit is exhausted. Move to OAuth, or reduce query volume. |
For more, see [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting).
## Related
* [Operata MCP server](/docs/guides-mcp-intro) — authentication, groups, and regions.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the Copilot CLI.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
* [Rate limits](/docs/api-rate-limits) — the 100 requests per minute per key limit.
# Connect Cursor to the Operata MCP server
Source: https://docs.operata.com/docs/guides-mcp-cursor
Add the Operata MCP Server to Cursor so you can query Operata data over the Model Context Protocol from inside the editor.
Connect Cursor to the Operata MCP Server so you can ask Operata-data questions from the editor's chat. Ask for yesterday's average MOS and Cursor answers from your account.
OAuth is the recommended way to connect. Use an API key only for automated, non-interactive integrations. For the difference, roles, and prerequisites, see the [MCP overview](/docs/guides-mcp-intro).
## Before you start
* An Operata account. For **OAuth**, a user with the **Admin** or **User** role; for an **API key**, an [Operata API key](/docs/api-authentication). See [Before you start](/docs/guides-mcp-intro#before-you-start).
* Cursor, installed and signed in. For Cursor's general MCP support, see [docs.cursor.com](https://docs.cursor.com/context/model-context-protocol).
## Open Cursor's MCP configuration
Cursor reads MCP servers from a per-project file at `.cursor/mcp.json` and a global file at `~/.cursor/mcp.json`. The project file overrides the global one. Open whichever scope matches how you want to use the server.
## Add the Operata MCP server
### Connect over OAuth
Add the server to the `mcpServers` object:
```json .cursor/mcp.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": ["mcp-remote@latest", "https://mcp.operata.io/mcp"]
}
}
}
```
### Connect with an API key
Use the API key endpoint for automated integrations. The key can only reach the single group it was created in.
```json .cursor/mcp.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": [
"mcp-remote@latest",
"https://api.operata.io/v1/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer "
}
}
}
}
```
Replace `` with your key.
## Reload Cursor
Reload the Cursor window (Command Palette → **Developer: Reload Window**). Open Cursor's MCP panel and confirm the `operata` server shows a green status and lists the Operata tools. On an OAuth connection, a browser window opens on first use to sign in to Operata and authorize the session.
## Select a group
On an OAuth session, pick the group you want to query: run `list_groups`, then `switch_group`. An API-key session is already fixed to its own group. See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions).
## Ask Cursor a question that uses Operata data
In Cursor's chat, ask a question that needs Operata data:
> Run a query against Operata for the average MOS across all contacts yesterday.
Cursor calls the right Operata tool — `traces_query` for an aggregate like this — and renders the result inline.
## Result
Cursor's MCP panel lists `operata` as connected, with the full Operata tool surface. A chat question that needs Operata data invokes a tool and returns a real value from your account. A `401` in the tool-call trace means the credential is wrong or expired; a `403` means a group problem. See [Troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Connect Claude](/docs/guides-mcp-claude) — Claude Desktop, Claude Code, and the Claude API.
* [Connect ChatGPT](/docs/guides-mcp-chatgpt) — a ChatGPT custom connector over OAuth.
* [Connect OpenCode](/docs/guides-mcp-opencode) — OpenCode's MCP configuration.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the CLI.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
# GitHub Copilot
Source: https://docs.operata.com/docs/guides-mcp-github-copilot
Configure GitHub Copilot in VS Code, Visual Studio, JetBrains, or the Copilot CLI to query your Operata traces over the Model Context Protocol.
GitHub Copilot can call the Operata MCP Server from agent mode, so you can ask about call quality, traces, and agent experience without leaving your editor.
This page covers the Copilot surfaces that connect to a remote MCP server directly. If you want to build an agent for non-technical colleagues instead, see [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio).
For authentication, groups, and regions, start with the [Operata MCP server](/docs/guides-mcp-intro) overview.
MCP tools only appear in **agent mode**. They're invisible in Ask and Edit modes.
## Before you start
* An active Operata subscription and credentials for your chosen endpoint — see [Choose how to connect](/docs/guides-mcp-intro#choose-how-to-connect).
* A GitHub Copilot subscription.
* One of: VS Code 1.101 or later, Visual Studio 2022 17.14 or later, a JetBrains IDE with the Copilot plugin, or GitHub Copilot CLI.
* If your organization is on Copilot Business or Copilot Enterprise, an administrator must enable the **MCP servers in Copilot** policy. Without it, the server won't load and Copilot gives no error.
## Configuration file locations
| Client | File |
| :- | :- |
| VS Code (workspace) | `.vscode/mcp.json` |
| VS Code (user) | Command Palette → **MCP: Open User Configuration** |
| Visual Studio | `mcp.json`, created by the Configure MCP server dialog |
| JetBrains IDEs | `mcp.json`, created by **Add MCP Tools** |
| Copilot CLI | `~/.copilot/mcp-config.json` |
In VS Code, Visual Studio, and JetBrains, the configuration root key is `servers`, not `mcpServers`. Cursor and Claude Desktop use `mcpServers`, so a config copied from one of those pages silently fails to load. This is the most common setup mistake. The Copilot CLI is the exception — it uses `mcpServers` (see [GitHub Copilot CLI](#github-copilot-cli)).
## Connect with OAuth
Recommended when a person is at the keyboard. OAuth signs you in as your Operata user and reaches every group your account can access.
Add the server to your configuration file:
```json .vscode/mcp.json theme={null}
{
"servers": {
"operata": {
"type": "http",
"url": "https://mcp.operata.io/mcp"
}
}
}
```
In VS Code, a **Start** button appears above the server entry. Select it. Copilot opens an Operata sign-in in your browser and stores the session for later. If the server is already running, use the **Auth** action in the CodeLens above the entry to re-authenticate.
## Connect with an API key
Use an API key only for automated, non-interactive work. The key is fixed to the single group it was created in.
Reference the key through an input variable so it's never written into the file:
```json .vscode/mcp.json theme={null}
{
"servers": {
"operata": {
"type": "http",
"url": "https://api.operata.io/v1/mcp",
"headers": {
"Authorization": "Bearer ${input:operata-api-key}"
}
}
},
"inputs": [
{
"id": "operata-api-key",
"type": "promptString",
"description": "Operata API key",
"password": true
}
]
}
```
Copilot prompts for the key the first time the server starts and keeps it for later sessions.
Never commit an API key to `.vscode/mcp.json`. If the file is in a shared repository, use the user-level configuration or an input variable as shown above.
## Client-specific setup
### VS Code
1. Open the Command Palette and run **MCP: Open User Configuration**, or create `.vscode/mcp.json` in your workspace root.
2. Add one of the configurations above.
3. Select **Start** above the server entry.
4. Open Copilot Chat and select **Agent** from the mode dropdown.
5. Select the tools icon to confirm the Operata tools are listed.
### Visual Studio
1. From the menu bar, select **View → GitHub Copilot Chat**.
2. At the bottom of the chat panel, select **Agent** from the mode dropdown.
3. Select the tools icon, then the plus icon.
4. In **Configure MCP server**, set **Server ID** to `operata`, **Type** to `HTTP/SSE`, and **URL** to `https://mcp.operata.io/mcp`.
5. Select **Save**.
### JetBrains IDEs
1. In the lower right corner, open the Copilot menu and select **Open Chat**.
2. Switch to **Agent** mode.
3. Select the tools icon, then **Add MCP Tools**.
4. Add one of the configurations above to `mcp.json`.
### GitHub Copilot CLI
The CLI uses the **`mcpServers`** root key, not `servers` like the IDEs. Add the Operata server to `~/.copilot/mcp-config.json` with `"type": "http"`:
```json ~/.copilot/mcp-config.json theme={null}
{
"mcpServers": {
"operata": {
"type": "http",
"url": "https://mcp.operata.io/mcp"
}
}
}
```
For an API key, use the API endpoint and add an `Authorization` header:
```json ~/.copilot/mcp-config.json theme={null}
{
"mcpServers": {
"operata": {
"type": "http",
"url": "https://api.operata.io/v1/mcp",
"headers": {
"Authorization": "Bearer "
}
}
}
}
```
The CLI supports both local and remote servers.
## Verify the connection
Open Copilot Chat in agent mode and ask:
```text theme={null}
List my Operata groups.
```
Copilot asks permission before calling a tool. Allow it. You should see the groups your account can reach, each with its ID and region.
Then set a group and try a real question:
```text theme={null}
Switch to the group named Demonstrata, then show me the average MOS score by queue for the last 7 days.
```
## Select a group
Every query runs against one group. Over OAuth, call `list_groups` then `switch_group`, and override on a single call with a `groupId` parameter. An API key is fixed to its own group. See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions). For more example prompts, see [Questions to ask your AI client](/docs/guides-mcp-intro#questions-to-ask-your-ai-client).
## Troubleshooting
| Symptom | Cause and fix |
| :- | :- |
| No Operata tools in the tool picker | You're in Ask or Edit mode. Switch to Agent. |
| Server does not appear at all | Wrong root key. VS Code, Visual Studio, and JetBrains use `servers`; the Copilot CLI uses `mcpServers`. |
| `MCP server "operata" has a "url" but no "type"` | Add `"type": "http"` to the entry. Without it, the client reads the entry as a local stdio server. |
| Server loads but every call fails with 401 | The API key is missing, expired, or the `Authorization` header is malformed. Confirm the value starts with `Bearer `. |
| `403 API key access is restricted to its own group` | The session is authenticated with an API key and something tried to switch groups. Use OAuth, or query the key's own group. |
| Nothing loads, no error, organization-managed device | The **MCP servers in Copilot** policy is disabled. Ask your GitHub administrator to enable it. |
| Repeated timeouts on large queries | Narrow the time range, and paginate `traces_list` with the cursor. See [Performance](/docs/guides-mcp-intro#performance). |
For more, see [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting).
## Related
* [Operata MCP server](/docs/guides-mcp-intro) — authentication, groups, and regions.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — build an agent for non-technical users.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
* [Rate limits](/docs/api-rate-limits) — the 100 requests per minute per key limit.
# Operata MCP Server
Source: https://docs.operata.com/docs/guides-mcp-intro
Connect an AI client to the Operata MCP Server to query your live traces, run analytics, and search the knowledge base over the Model Context Protocol.
The Operata MCP Server lets an AI client query your traces, run analytics, and read the Operata knowledge base over the Model Context Protocol (MCP). Ask Claude, ChatGPT, Cursor, or another MCP client a question in plain language, and it calls the right Operata tool and answers from your account.
This page covers what every client shares: how to authenticate, which clients are supported, how groups and regions work, and how to test the server.
Each client also has its own short setup guide:
* [Connect Claude](/docs/guides-mcp-claude) — Claude Desktop, Claude Code, and the Claude API.
* [Connect Cursor](/docs/guides-mcp-cursor) — Cursor's MCP configuration.
* [Connect ChatGPT](/docs/guides-mcp-chatgpt) — a ChatGPT custom connector over OAuth.
* [Connect OpenCode](/docs/guides-mcp-opencode) — OpenCode's MCP configuration.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared Copilot Studio agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the Copilot CLI.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
The Operata MCP Server is live and ready.
However, as we ship new features, the tool surface and configuration may change, guided by the [MCP specification](https://modelcontextprotocol.io) and your feedback.
Follow the [changelog](/docs/changelog) for updates.
## What is the Model Context Protocol?
MCP is an open standard that connects AI assistants to external data and tools. It gives an AI model a consistent way to reach the context it needs, so answers come from your data instead of guesswork.
## What you can do
* **Query traces with precise filters**, aggregations, and time ranges.
* **Retrieve full OpenTelemetry traces** with every span, log, and insight.
* **Run cross-service analytics** — scalar, series, table, rate, and facet queries.
* **Pull agent-side diagnostics** — browser debug logs, presence changes, and reported issues.
* **Search the knowledge base** without leaving your AI client.
* **Work across your groups**, with every query scoped to the group you choose.
## Choose how to connect
The server offers two endpoints. Pick one based on whether a person or a machine is connecting.
| | OAuth endpoint (recommended) | API key endpoint |
| :- | :- | :- |
| **URL** | `https://mcp.operata.io/mcp` | `https://api.operata.io/v1/mcp` |
| **Authenticates as** | Your Operata user, in a short-lived session | An API key, long-lived |
| **Best for** | A person using an AI client | Machine-to-machine integrations |
| **Group access** | Every group your user can reach | The single group the key belongs to |
| **SSO** | Supported | Not applicable |
Use OAuth when a person is at the keyboard. Use an API key only for automated integrations that run without anyone present.
### OAuth
OAuth signs you in as your Operata user. The session is short-lived, scoped to your role, and can reach any group your account has access to. SSO sign-in works. There's nothing to create ahead of time. The first time your client connects to `https://mcp.operata.io/mcp`, it opens an Operata sign-in in your browser to authorize the session.
### API key
An API key is a long-lived bearer credential for automated, non-interactive use. It authenticates as an API user with full API privileges and is restricted to the single group it was created in, so it can't list or switch to other groups.
To create one, sign in to Operata, open **Group Settings → API Management**, and click **Create New Key**. Give it a descriptive name such as `MCP Server — CI pipeline`, then copy and store the value. The console won't show it again. For more on Operata API keys, see [Authentication](/docs/api-authentication).
## Before you start
* An active Operata subscription.
* Credentials for your chosen endpoint:
* **OAuth** — an Operata user with the **Admin** or **User** role. **Viewer** accounts and **RBAC users** can't use the MCP Server.
* **API key** — an [Operata API key](/docs/api-authentication).
* A supported AI client, installed and signed in.
## Supported clients
| Client | Authentication | How you configure it |
| :- | :- | :- |
| Claude Desktop | OAuth or API key | MCP configuration file |
| Claude Code | OAuth or API key | CLI (`claude mcp add`) |
| ChatGPT | OAuth | Connector settings |
| OpenCode | OAuth or API key | MCP configuration file |
| Cursor | OAuth or API key | MCP configuration file |
| Microsoft Copilot Studio | OAuth or API key | Onboarding wizard (Power Platform connector) |
| GitHub Copilot | OAuth or API key | MCP configuration file (`servers` key) |
## Groups and regions
Every query runs against one group. How you select it depends on how you connected.
* **OAuth** — list the groups your account can reach with `list_groups`, then set the active one with `switch_group`. Override it on any single call with a `groupId` parameter.
* **API key** — the key is fixed to its own group, so there's nothing to select. `switch_group` to any other group returns `403 "API key access is restricted to its own group"`.
The endpoints serve all regions. Each group is hosted in a specific region (for example `ap-southeast-2` or `us-east-2`), and `list_groups` returns the region for each group you can reach.
## Recommended workflow
The trace tools are schema-driven. Learn what data is available before you query it.
1. **Select your group** — `list_groups`, then `switch_group` (OAuth only; API-key sessions are already fixed to their group).
2. **`get_schema`** — learn the services, column paths, query types, aggregate functions, and filter operators.
3. **`traces_list`** — browse and filter traces by time range, span name, or duration.
4. **`traces_query`** — run analytics: counts, averages, trends, rates, and facets.
5. **`traces_get`** — drill into a single trace for the full span tree.
6. **`traces_insights`** and **`traces_span_logs`** — deep diagnostics on a trace and its spans.
7. **`knowledge`** — documentation and troubleshooting guidance.
8. **`agent_logs`**, **`agent_status`**, and **`agent_reported_issues`** — browser debug logs, presence changes, and agent-reported issues.
For the full tool surface, see the [MCP tools reference](/docs/guides-mcp-tools).
### Questions to ask your AI client
* "Show me the average MOS score by queue for the last 7 days."
* "What percentage of calls had poor audio quality (MOS below 3.0) this month?"
* "Get the full trace for trace ID abc123 and summarize what happened."
* "Which agents had the most holds in the past week?"
* "What are the top disconnect reasons for our inbound calls?"
* "Did any agents report audio issues today?"
* "Explain how Operata's WebRTC diagnostics work."
## Test the server with curl
Before wiring up a client, confirm the server responds. These examples use the API key endpoint, since it authenticates with a single header. The OAuth endpoint uses an interactive browser sign-in that your MCP client handles, not curl. Replace `$OPERATA_API_KEY` with your key.
**List the available tools:**
```bash theme={null}
curl -sS -X POST "https://api.operata.io/v1/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $OPERATA_API_KEY" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }'
```
**Query the knowledge base:**
```bash theme={null}
curl -sS -X POST "https://api.operata.io/v1/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $OPERATA_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "knowledge",
"arguments": { "query": "What is MOS score and how is it calculated" }
}
}'
```
**Run a scalar aggregation:**
```bash theme={null}
curl -sS -X POST "https://api.operata.io/v1/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $OPERATA_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "traces_query",
"arguments": {
"startTime": "2026-05-01T00:00:00Z",
"endTime": "2026-06-01T00:00:00Z",
"queries": {
"scalar": [
{
"key": "total_calls",
"service": "agent_interaction",
"aggregates": [{ "name": "count", "fn": "count", "path": "*" }]
}
]
}
}
}
}'
```
## Best practices
### Security
* **Prefer OAuth for people.** OAuth sessions follow the signing-in user's role and groups, so access stays least-privilege. API keys carry full API privileges — reserve them for machine-to-machine use.
* **Store API keys in environment variables or a secrets vault**, never in shared config.
* **Rotate keys** on your organization's schedule.
* **Confirm the active group** with `switch_group`, or set `groupId` per call, before you query.
### Performance
* **Call `get_schema` first** so queries use valid field paths.
* **Scope the time range** to the narrowest window that answers your question.
* **Batch query types** — combine scalar, series, rate, and facet in one `traces_query` call to cut round-trips.
* **Paginate** `traces_list`, `traces_span_logs`, `agent_logs`, `agent_status`, and `agent_reported_issues` with the cursor for large result sets.
* **Respect the rate limit** of 100 requests per minute per key. Retry with exponential backoff in custom integrations.
### Privacy
* **Scope to the right group** before you query, so you never read another group's data.
* **Watch for PII** in queries and responses.
* **Follow your organization's data privacy policies.**
## Support and feedback
Share your use cases and feature requests with your Customer Success Manager. Your feedback shapes what ships next.
## Related
* [Connect Claude to the Operata MCP Server](/docs/guides-mcp-claude)
* [Connect Cursor to the Operata MCP Server](/docs/guides-mcp-cursor)
* [Connect ChatGPT to the Operata MCP Server](/docs/guides-mcp-chatgpt)
* [Connect OpenCode to the Operata MCP Server](/docs/guides-mcp-opencode)
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio)
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot)
* [MCP tools reference](/docs/guides-mcp-tools)
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
* [Rate limits](/docs/api-rate-limits) — the 100 requests per minute per key limit.
# Connect OpenCode to the Operata MCP server
Source: https://docs.operata.com/docs/guides-mcp-opencode
Add the Operata MCP Server to OpenCode so you can query Operata data over the Model Context Protocol from your editor.
Connect OpenCode to the Operata MCP Server so you can ask about call quality and customer journeys from OpenCode's chat. Ask for last week's average MOS and OpenCode answers from your account.
OAuth is the recommended way to connect. Use an API key only for automated, non-interactive integrations. For the difference, roles, and prerequisites, see the [MCP overview](/docs/guides-mcp-intro).
## Before you start
* An Operata account. For **OAuth**, a user with the **Admin** or **User** role; for an **API key**, an [Operata API key](/docs/api-authentication). See [Before you start](/docs/guides-mcp-intro#before-you-start).
* OpenCode, installed and signed in.
## Open OpenCode's MCP configuration
OpenCode reads MCP servers from its configuration file (`opencode.json` or your client's MCP configuration). Add the server to the `mcpServers` object.
## Add the Operata MCP server
### Connect over OAuth
```json opencode.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": ["mcp-remote@latest", "https://mcp.operata.io/mcp"]
}
}
}
```
### Connect with an API key
Use the API key endpoint for automated integrations. The key can only reach the single group it was created in.
```json opencode.json theme={null}
{
"mcpServers": {
"operata": {
"command": "npx",
"args": [
"mcp-remote@latest",
"https://api.operata.io/v1/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer "
}
}
}
}
```
Replace `` with your key.
## Reload OpenCode
Restart OpenCode. On an OAuth connection, a browser window opens on first use to sign in to Operata and authorize the session.
## Select a group
On an OAuth session, pick the group you want to query: run `list_groups`, then `switch_group`. An API-key session is already fixed to its own group. See [Groups and regions](/docs/guides-mcp-intro#groups-and-regions).
## Ask OpenCode a question that uses Operata data
In OpenCode's chat, ask a question that needs Operata data:
> Run a query against Operata for the average MOS across all contacts yesterday.
OpenCode calls the right Operata tool — `traces_query` for an aggregate like this — and renders the result.
## Result
OpenCode lists `operata` as a connected MCP server with the full Operata tool surface. A chat question that needs Operata data invokes a tool and returns a real value from your account. A `401` in the tool-call trace means the credential is wrong or expired; a `403` means a group problem. See [Troubleshooting](/docs/guides-mcp-troubleshooting).
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Connect Claude](/docs/guides-mcp-claude) — Claude Desktop, Claude Code, and the Claude API.
* [Connect Cursor](/docs/guides-mcp-cursor) — Cursor's MCP configuration.
* [Connect ChatGPT](/docs/guides-mcp-chatgpt) — a ChatGPT custom connector over OAuth.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the CLI.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — mint the API keys the server uses.
# Operata MCP server tools
Source: https://docs.operata.com/docs/guides-mcp-tools
Reference for the twelve tools the Operata MCP Server exposes — schema discovery, group selection, trace search, analytical queries, full-trace retrieval, span-level diagnostics, and agent data.
The Operata MCP Server exposes twelve tools over the Model Context Protocol (MCP). To connect a client and learn how authentication and groups work, start with the [MCP overview](/docs/guides-mcp-intro), then follow [Connect Claude](/docs/guides-mcp-claude), [Connect Cursor](/docs/guides-mcp-cursor), or [Connect ChatGPT](/docs/guides-mcp-chatgpt).
The Operata MCP Server is live and ready.
However, as we ship new features, the tool surface and configuration may change, guided by the [MCP specification](https://modelcontextprotocol.io) and your feedback.
Follow the [changelog](/docs/changelog) for updates.
## Endpoints and authentication
The server offers two endpoints. Use OAuth when a person is connecting, and an API key for machine-to-machine integrations.
| Property | OAuth endpoint | API key endpoint |
| - | - | - |
| Endpoint | `https://mcp.operata.io/mcp` | `https://api.operata.io/v1/mcp` |
| Authentication | Operata user session (browser sign-in) | Bearer API key in the `Authorization` header |
| Group access | Every group your user can reach | The single group the key belongs to |
| Transport | Server-Sent Events (SSE) / JSON-RPC | Server-Sent Events (SSE) / JSON-RPC |
| API version | v1 | v1 |
| Rate limit | 100 requests per minute | 100 requests per minute per key |
For the full comparison, roles, and how to mint a key, see [Choose how to connect](/docs/guides-mcp-intro#choose-how-to-connect) and [Authentication](/docs/api-authentication).
## Recommended workflow
The trace tools are schema-driven. Learn what data is available before you query it.
1. **`list_groups`** and **`switch_group`** — select the group to query (OAuth sessions; API keys are already fixed to their group).
2. **`get_schema`** — learn the services, column paths, query types, aggregate functions, and filter operators.
3. **`traces_list`** — browse and filter traces by time range, span name, or duration.
4. **`traces_query`** — run analytics: counts, averages, trends, rates, and facets.
5. **`traces_get`** — drill into a single trace for the full span tree.
6. **`traces_insights`** and **`traces_span_logs`** — deep diagnostics on a trace and its spans.
7. **`knowledge`** — documentation and troubleshooting guidance.
8. **`agent_logs`**, **`agent_status`**, and **`agent_reported_issues`** — browser debug logs, presence changes, and agent-reported issues.
## Tools
### get\_schema
Returns the complete data schema: available services, column paths, query types, aggregate functions, and filter operators.
Call this tool first so the AI client constructs valid queries.
**Parameters**
* `query_reason` (string, optional) — your reason for requesting the schema.
```json Example - exploring the agent_interaction fields in the schema theme={null}
{
"name": "get_schema",
"arguments": {
"query_reason": "understanding available fields for agent_interaction"
}
}
```
### knowledge
Retrieves information from the Operata knowledge base — Operata features, CX observability concepts, and troubleshooting guidance.
**Parameters**
* `query` (string, required) — your question about Operata features or concepts.
```json Example - asking how MOS score is calculated theme={null}
{
"name": "knowledge",
"arguments": {
"query": "What is MOS score and how is it calculated"
}
}
```
### list\_groups
Lists the groups your authenticated account can access.
* Over OAuth, this returns every group your Operata user can reach.
* With an API key, it returns only the single group the key belongs to.
Each result includes `groupId`, `groupName`, and `region`.
**Parameters**
* None.
```json Example - listing the groups you can access theme={null}
{
"name": "list_groups",
"arguments": {}
}
```
### switch\_group
Sets the active group for the session. Every later tool call uses this group unless you override it with a `groupId` parameter on the call.
**Parameters**
* `groupId` (string, required) — the group to switch to. Must be a group your account can access.
```json Example - switching to a specific group by ID theme={null}
{
"name": "switch_group",
"arguments": {
"groupId": "5bbbd17a-fd70-45ad-a048-c4674035f406"
}
}
```
An API key can only reach the group it was created in. Calling `switch_group` with any
other group on an API-key session returns
`403 "API key access is restricted to its own group"`. Connect over OAuth to
work across groups.
### traces\_list
Lists and searches traces with filtering, sorting, and cursor-based pagination. Returns trace summaries with metadata such as duration, span count, and status.
**Parameters**
* `startTime` (string, required) — ISO 8601 UTC start time.
* `endTime` (string, required) — ISO 8601 UTC end time.
* `filters` (array, optional) — filter objects, each a `path` plus an operator (`eq`, `gt`, `lt`, and so on).
* `sort` (string, optional) — `"asc"` or `"desc"`. Default `"desc"`.
* `limit` (integer, optional) — results per page, 1–1000. Default 100.
* `cursor` (object, optional) — pagination cursor from a previous response.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
Available filter fields: `SpanName`, `ServiceName`, `StatusCode`, `SpanKind`, `Duration`.
```json Example - listing recent agent-interaction traces theme={null}
{
"name": "traces_list",
"arguments": {
"startTime": "2026-05-01T00:00:00Z",
"endTime": "2026-06-01T00:00:00Z",
"filters": [
{ "path": "SpanName", "eq": "cx.interaction.agent" }
],
"sort": "desc",
"limit": 10
}
}
```
### traces\_query
Executes analytical queries against trace data. Supports five query types, which you can combine in a single request. Each query specifies a `key` (a unique identifier) and a `service`.
**Parameters**
* `startTime` (string, required) — ISO 8601 UTC start time.
* `endTime` (string, required) — ISO 8601 UTC end time.
* `queries` (object, required) — an object containing arrays for each query type.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
```json Example - combining scalar and rate queries over May 2026 theme={null}
{
"name": "traces_query",
"arguments": {
"startTime": "2026-05-01T00:00:00Z",
"endTime": "2026-06-01T00:00:00Z",
"queries": {
"scalar": [
{
"key": "agent_overview",
"service": "agent_interaction",
"aggregates": [
{ "name": "count", "fn": "count", "path": "*" },
{ "name": "avg_mos", "fn": "avg", "path": "Attributes.cx.webrtc.audio.mos_score" },
{ "name": "p90_mos", "fn": "p90", "path": "Attributes.cx.webrtc.audio.mos_score" }
]
}
],
"rate": [
{
"key": "quality_rates",
"service": "agent_interaction",
"rates": [
{ "name": "poor_mos", "filters": [{ "path": "Attributes.cx.webrtc.audio.mos_score", "lt": 3.0 }] },
{ "name": "high_jitter", "filters": [{ "path": "Attributes.cx.webrtc.audio.jitter_ms", "gt": 50 }] }
]
}
]
}
}
}
```
### traces\_get
Retrieves a single trace by ID in full OpenTelemetry JSON, with all spans and logs.
**Parameters**
* `traceId` (string, required) — the 32-character hex trace identifier.
* `includeInternal` (boolean, optional) — include internal `operata.*` spans. Default `false`.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
```json Example - fetching one trace by ID theme={null}
{
"name": "traces_get",
"arguments": {
"traceId": "8b1c0813ca3ca75494be82e036177ef1",
"includeInternal": false
}
}
```
### traces\_insights
Returns all insights (detected issues and anomalies) for a trace. Each insight carries the `spanId` it belongs to, so you can group results by span.
**Parameters**
* `traceId` (string, required) — the 32-character hex trace identifier.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
* `query_reason` (string, optional) — your reason for requesting the insights.
```json Example - getting insights for a trace theme={null}
{
"name": "traces_insights",
"arguments": {
"traceId": "8b1c0813ca3ca75494be82e036177ef1"
}
}
```
### traces\_span\_logs
Returns paginated logs for a specific span within a trace, such as softphone logs, CCP events, and other diagnostic records.
**Parameters**
* `traceId` (string, required) — the 32-character hex trace identifier.
* `spanId` (string, required) — the 16-character hex span identifier.
* `limit` (integer, optional) — max log records, 1–1000. Default 50.
* `cursor` (object, optional) — pagination cursor from a previous response.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
```json Example - paging through a span's logs theme={null}
{
"name": "traces_span_logs",
"arguments": {
"traceId": "8b1c0813ca3ca75494be82e036177ef1",
"spanId": "89faf69ce53bc085",
"limit": 100
}
}
```
### agent\_logs
Fetches raw CCP and softphone debug logs collected from the agent's browser, covering levels TRACE through ERROR across components such as `ccp`, `softphone`, and `webrtc-sdk`. Query by time window, agent, or contact ID, then narrow by component, level, or free text to troubleshoot media, connection, and CCP errors.
**Parameters**
* `startTime` (string, optional) — ISO 8601 UTC start time. Required with `endTime` unless you provide `agent` or `contactId`.
* `endTime` (string, optional) — ISO 8601 UTC end time. Required with `startTime` unless you provide `agent` or `contactId`.
* `agent` (string, optional) — agent email or username. Provide this, a timeframe, or a `contactId`.
* `contactId` (string, optional) — the contact or interaction ID (`cx.interaction.id`). Pivot from a trace or a reported issue.
* `filters` (array, optional) — AND-combined filter objects, each a `field`, `op`, and `value`.
* `limit` (integer, optional) — results per page, 1–2000. Default 500.
* `cursor` (object, optional) — pagination cursor from a previous response.
* `sort` (string, optional) — sort by time, `"asc"` or `"desc"`. Default `"desc"`.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
* `query_reason` (string, optional) — your reason for querying agent logs.
Available filter fields: `component`, `level`, `text` (full-text), `agent`, `contact_id`.
`total` stops counting at 10,000. If it comes back as exactly 10,000, the query is too broad — narrow it.
```json Example - fetching ERROR-level logs for a specific contact theme={null}
{
"name": "agent_logs",
"arguments": {
"contactId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filters": [
{ "field": "level", "op": "eq", "value": "ERROR" }
],
"limit": 100
}
}
```
### agent\_status
Searches agent status and presence changes from the softphone, such as Available, Busy, On Break, After Call Work, and custom auxiliary states. Query by time window or agent, then narrow by status value or contact ID.
**Parameters**
* `startTime` (string, optional) — ISO 8601 UTC start time. Required with `endTime` unless you provide `agent`.
* `endTime` (string, optional) — ISO 8601 UTC end time. Required with `startTime` unless you provide `agent`.
* `agent` (string, optional) — agent email or username. Provide this or a timeframe.
* `filters` (array, optional) — AND-combined filter objects, each a `field`, `op`, and `value`.
* `limit` (integer, optional) — results per page, 1–1000. Default 100.
* `cursor` (object, optional) — pagination cursor from a previous response.
* `sort` (string, optional) — sort by timestamp, `"asc"` or `"desc"`. Default `"desc"`.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
* `query_reason` (string, optional) — your reason for querying agent status.
Available filter fields: `status`, `contact_id`.
```json Example - checking an agent's status changes over the last hour theme={null}
{
"name": "agent_status",
"arguments": {
"agent": "jane.doe@example.com",
"startTime": "2026-05-01T09:00:00Z",
"endTime": "2026-05-01T10:00:00Z",
"sort": "asc"
}
}
```
### agent\_reported\_issues
Searches agent-reported issues, such as audio, softphone, or connectivity problems flagged during or after a call. Query by time window or agent, then narrow by category, severity, scenario, cause, error type, browser, or contact ID.
**Parameters**
* `startTime` (string, optional) — ISO 8601 UTC start time. Required with `endTime` unless you provide `agent`.
* `endTime` (string, optional) — ISO 8601 UTC end time. Required with `startTime` unless you provide `agent`.
* `agent` (string, optional) — agent email or username. Provide this or a timeframe.
* `filters` (array, optional) — AND-combined filter objects, each a `field`, `op`, and `value`.
* `limit` (integer, optional) — results per page, 1–1000. Default 100.
* `cursor` (object, optional) — pagination cursor from a previous response.
* `sort` (string, optional) — sort by timestamp, `"asc"` or `"desc"`. Default `"desc"`.
* `groupId` (string, optional) — group to query. Defaults to the active group you set with `switch_group`.
* `query_reason` (string, optional) — your reason for querying reported issues.
Available filter fields: `category`, `severity`, `scenario`, `cause`, `contact_id`, `error_type`, `browser_name`.
```json Example - finding audio-related issues reported in the last 24 hours theme={null}
{
"name": "agent_reported_issues",
"arguments": {
"startTime": "2026-05-14T00:00:00Z",
"endTime": "2026-05-15T00:00:00Z",
"filters": [
{ "field": "category", "op": "eq", "value": "audio" }
],
"limit": 50
}
}
```
## Services
`traces_query` and the schema operate against four services. Each is one row per interaction at a different level of the customer journey.
| Service | Granularity | Path convention | Best for |
| - | - | - | - |
| `agent_interaction` | One agent WebRTC/telephony session | `Attributes.cx.*` | Call quality, agent performance, WebRTC diagnostics |
| `node_interaction` | One IVR/contact-flow node execution | `Attributes.cx.flow.*` | IVR flow analysis and error rates |
| `ai_interaction` | One bot conversation, with agent-handoff context | `Attributes.cx.ai.*` | AI bot effectiveness and NLU analysis |
| `journey_interaction` | One complete customer journey | `Attributes.*` | End-to-end CX, transfers, and wait times |
## Query types
A single `traces_query` request can combine any of these types.
| Type | Purpose | Key fields |
| - | - | - |
| Scalar | Aggregated values (count, avg, p90, and so on) with optional grouping | `aggregates`, `grouping`, `filters` |
| Series | Time-bucketed aggregations for trends | `aggregates`, `interval` (seconds) |
| Table | Raw row data with selected columns | `columns`, `limit`, `orders` |
| Rate | Occurrence rates (for example, poor-MOS rate) | `rates` with filter definitions |
| Facet | Unique values for a field, with counts | `path`, `limit` |
## Query construction
These constraints trip up generated queries most often:
* **Service selection** drives the path convention. Use `Attributes.cx.*`
for `agent_interaction`; use `Attributes.*` directly for
`journey_interaction`.
* **Boolean fields** such as `had_agent`, `had_bot`, and `had_queue`
hold string values. Filter with `"eq": "true"`, not boolean `true`.
* **You can't use `SpanName` in `traces_query` filters.** Use
`traces_list` with a `SpanName` filter instead.
Call `get_schema` before building a complex query. Scope `startTime`/`endTime` to the narrowest range that meets your need, and combine query types in one `traces_query` call to minimize round-trips. Use cursor-based pagination on `traces_list` and `traces_span_logs` for large result sets.
## Verify
Confirm the server is reachable and returning the full tool surface. This example uses the API key endpoint, since it authenticates with a single header. The OAuth endpoint uses an interactive sign-in that your MCP client handles.
```bash theme={null}
curl -sS -X POST "https://api.operata.io/v1/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $OPERATA_API_KEY" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }'
```
The response lists all twelve tools: `get_schema`, `knowledge`, `list_groups`, `switch_group`, `traces_list`, `traces_query`, `traces_get`, `traces_insights`, `traces_span_logs`, `agent_logs`, `agent_status`, and `agent_reported_issues`. For more curl checks, see [Test the server with curl](/docs/guides-mcp-intro#test-the-server-with-curl).
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [Connect Claude](/docs/guides-mcp-claude) — Claude Desktop, Claude Code, and the Claude API.
* [Connect Cursor](/docs/guides-mcp-cursor) — Cursor's MCP configuration.
* [Connect ChatGPT](/docs/guides-mcp-chatgpt) — a ChatGPT custom connector over OAuth.
* [Connect OpenCode](/docs/guides-mcp-opencode) — OpenCode's MCP configuration.
* [Connect Microsoft Copilot Studio](/docs/guides-mcp-copilot-studio) — a shared agent for your team.
* [Connect GitHub Copilot](/docs/guides-mcp-github-copilot) — VS Code, Visual Studio, JetBrains, and the CLI.
* [Troubleshoot the MCP server](/docs/guides-mcp-troubleshooting) — common failure modes and fixes.
* [Authentication](/docs/api-authentication) — the API keys the server uses.
* [Rate limits](/docs/api-rate-limits) — the 100 requests per minute per key limit.
# Troubleshoot the Operata MCP server
Source: https://docs.operata.com/docs/guides-mcp-troubleshooting
Fixes for common Operata MCP Server problems: connection errors, missing tools, authentication failures, group access, and empty query results.
Common failure modes for the Operata MCP Server and how to fix them. For setup, start with the [MCP overview](/docs/guides-mcp-intro) or your client's guide.
## The server doesn't respond
1. Check the endpoint URL: `https://mcp.operata.io/mcp` for OAuth, `https://api.operata.io/v1/mcp` for an API key.
2. Confirm your network allows HTTPS to `mcp.operata.io` or `api.operata.io`.
3. **OAuth** — reconnect to refresh an expired session. In Claude Code, run `/mcp`.
4. **API key** — verify the key is valid, not revoked, and has the right permissions.
## Tools don't appear in your client
1. Restart the client after you change its configuration.
2. Check the MCP configuration file is valid JSON.
3. Read the client's logs for MCP errors.
4. Confirm `mcp-remote` runs: `npx mcp-remote@latest --help`.
## Authentication errors (401 or 403)
1. **OAuth** — sessions are short-lived and expire. Reconnect your client for a fresh sign-in (in Claude Code, run `/mcp`).
2. **OAuth** — confirm your user has the **Admin** or **User** role. **Viewer** accounts and **RBAC users** can't use the server.
3. **API key** — regenerate the key, update the configuration, and check the `Authorization: Bearer` header is correct and the key isn't revoked.
4. `403 "API key access is restricted to its own group"` means an API-key session tried to use another group. Connect over OAuth to work across groups.
## A group is missing, or `switch_group` is rejected
1. **API key** — keys only ever see their own group. Connect over OAuth to reach others.
2. **OAuth** — `list_groups` returns only the groups your user is scoped to. Confirm your access in Operata.
3. Confirm your role is **Admin** or **User**, and that you aren't an **RBAC user**.
## A query returns no results
1. Confirm the time range contains data — try widening it to 30 or 60 days.
2. Confirm the active group is correct with `switch_group`, or pass `groupId` on the call.
3. Use `get_schema` to check the column paths for the service you're querying.
4. For `ai_interaction` or `node_interaction`, confirm bots or IVR flow logging are configured.
5. Run `traces_list` with no filters to confirm data exists in the range.
## A trace or span isn't found
1. Confirm the trace ID is exactly 32 hex characters.
2. Confirm the span ID is exactly 16 hex characters.
3. Confirm the trace exists with `traces_list` or a `traces_query` table query first.
4. Confirm the span belongs to the trace.
## Related
* [MCP overview](/docs/guides-mcp-intro) — authentication, groups, and testing for every client.
* [MCP tools reference](/docs/guides-mcp-tools) — every tool, its parameters, and examples.
* [Authentication](/docs/api-authentication) — the API keys the server uses.
* [Rate limits](/docs/api-rate-limits) — the 100 requests per minute per key limit.
# Request SSO for your Operata account
Source: https://docs.operata.com/docs/guides-request-sso
Send Operata the SAML 2.0 metadata it needs to enable single sign-on so your team signs in with corporate credentials.
Give Operata the metadata it needs to enable SAML 2.0 single sign-on (SSO) for your account so your team signs in with corporate credentials instead of an Operata password.
## Before you start
* An [Operata account](https://app.operata.io) with admin permissions.
* A SAML 2.0 identity provider (IdP) you administer — for example Okta, Azure AD, OneLogin, or Auth0.
* The list of email domains your users sign in with. Operata routes all listed domains to the same SSO connection.
This guide covers SAML 2.0. For an OpenID Connect (OIDC) identity provider, see [Configure an OIDC identity provider for SSO](/docs/guides-sso-oidc).
## Steps
### 1. Email Operata Support
Send a request to [Operata Support](mailto:support@operata.com) stating that you want to enable SSO. Specify the Operata Group IDs you want SSO on — production, development, test, or all three. Operata replies with a connection name and the SAML configuration values you need to set on your IdP side.
### 2. Create a SAML 2.0 application on your IdP
Create a SAML 2.0 application in your identity provider using the connection name, sign-in URL, and audience restriction Operata supplies. The IdP-specific steps live in:
* [Configure Okta as an SSO identity provider](/docs/guides-sso-okta) — the only IdP with a step-by-step Operata guide today.
For other IdPs, follow the vendor's standard SAML 2.0 application setup using Operata's supplied URLs.
### 3. Export the SAML metadata
Export the SAML metadata XML from your IdP. If your IdP does not support XML export, capture the following values instead:
* Sign-in URL.
* X.509 signing certificate in PEM or CER format.
* The email domains that sign in through this connection.
### 4. Send the metadata to Operata
Reply to the support thread from step 1 with the metadata XML (or the three values from step 3). Operata creates the SSO connector and replies when it is ready to test.
### 5. Joint test with Operata
Operata schedules a call to switch your platform IdP over to the new connector and verifies SSO sign-in end to end with you on the call. Once the test passes, your users sign in through your IdP from then on.
## Result
A user whose email matches one of the domains you listed visits `https://app.operata.io`, enters their email, and is redirected to your IdP. After authenticating with corporate credentials, the user lands in the Operata console without entering an Operata password.
## Related
* [Configure Okta as an SSO identity provider](/docs/guides-sso-okta) — the IdP-specific steps for Okta.
* [Configure an OIDC identity provider for SSO](/docs/guides-sso-oidc) — SSO through Okta, Microsoft Entra ID, or PingFederate over OpenID Connect.
# Send your first observation
Source: https://docs.operata.com/docs/guides-send-first-observation
Stream a real Amazon Connect contact into Operata and confirm it appears in the Contact summary list and over the API.
Stream a real Amazon Connect contact into Operata and confirm it's visible in both the Contact summary list and the API response.
## Before you start
* An [Operata account](https://app.operata.io). Your Operata Group ID is the UUID in the console URL.
* An API token generated under **Settings → Config → API**. See [Authentication](/docs/api-authentication).
* An Amazon Connect instance you can place a test call into, with the [Cloud Collector CloudFormation stack](/docs/ctr-installation) deployed against it.
* A working softphone — Amazon Connect CCP or the [Agent Collector](/docs/collector-overview) in Chrome or Edge.
## Steps
### 1. Confirm your credentials work
Send the same call as the [Quickstart](/docs/quickstart) — one contact from yesterday's window, page size 1.
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-17T00:00:00Z&toTime=2026-05-18T00:00:00Z&size=1"
```
A `200 OK` with a `data` array — empty or otherwise — confirms the Group ID and token authenticate. A `401` means the token is wrong or revoked; regenerate it and retry.
### 2. Place a test contact
Sign in to the agent's CCP, set status to `Available`, and place an inbound call into your Amazon Connect instance. Stay on the call for at least 30 seconds, then hang up. The 30-second floor gives the Cloud Collector enough audio to compute meaningful network and MOS metrics.
Note the contact ID shown in the CCP — you use it to verify in step 4.
### 3. Wait for the observation to land
The Cloud Collector picks up the Contact Trace Record (CTR) from Kinesis within seconds of contact end, applies the active redaction config, and ships the surviving fields to Operata. Allow up to 60 seconds for the observation to appear.
```bash theme={null}
# Replace with the contact ID from the CCP.
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-18T00:00:00Z&toTime=2026-05-18T23:59:59Z&contactId=ctr_0HXYZ123456789ABCDE"
```
If the response is an empty `data` array, wait 30 seconds and retry. A populated row means the Cloud Collector filtered the CTR, the EventBridge pipe delivered it, and Operata stored it as an observation against the contact.
### 4. Open the contact in the console
In the Operata console, open **Contacts** and filter the time window to the last 10 minutes. The test contact appears as a row carrying the same contact ID you noted in step 2, an agent name, a queue, and headline metrics — MOS, jitter, round-trip time, packets lost.
## Verify
The API call in step 3 returns `200 OK` with one `data` entry whose `id` matches the contact ID from the CCP, and the same row is visible in the Contact summary list in the console. The API response and the console agree on agent, queue, and duration.
## Related
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the model behind the row you just saw.
* [Signals and observations](/docs/concepts-signals-and-observations) — what a signal is, what an observation is, and how they relate to a contact.
* [List contact summaries](/docs/api-contact-summary) — every parameter the endpoint accepts.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — strip fields from the CTR before the next contact ships.
# Configure an OIDC identity provider for SSO
Source: https://docs.operata.com/docs/guides-sso-oidc
For identity provider admins — register Operata as an OpenID Connect application so your team signs in with corporate credentials.
OpenID Connect (OIDC) single sign-on (SSO) signs your team in to the Operata Platform through your identity provider (IdP), such as Okta, Microsoft Entra ID, or PingFederate. This page is for the administrator of that IdP. You register Operata as an application, send Operata the connection details, and test sign-in with one user.
For a SAML 2.0 IdP, follow [Request SSO for your Operata account](/docs/guides-request-sso) instead.
## Before you start
* An [Operata account](https://app.operata.io) with admin permissions.
* Admin access to an OIDC IdP.
* The email domains your users sign in with, such as `acme.com`.
* The users who need access, and the Operata Group each one belongs to.
Operata matches each SSO sign-in to an Operata user by email address. Your IdP must release the `email` claim. Release `email_verified` as well if your IdP supports it.
## Steps
### 1. Request SSO from Operata
Email [Operata Support](mailto:support@operata.com) or your Customer Success Manager. Include your email domains and the users, each with their Operata Group.
### 2. Create a web application in your IdP
Create an OIDC web application with these settings:
| Setting | Value |
| - | - |
| Grant type | Authorization Code |
| Scopes | `openid profile email` |
| Sign-in redirect URIs | `https://login.operata.io/login/callback` and `https://prod-operata.au.auth0.com/login/callback` |
| Sign-out redirect URI (optional) | `https://login.operata.io` |
Register both sign-in redirect URIs. Assign the application to the users who need access.
### 3. Release the email claims
Configure the application to release `email`, and `email_verified` if available. The email must match the user's Operata account. Matching ignores case.
### 4. Send the connection details to Operata
Reply to the support thread with:
* Your issuer or discovery URL, such as `https://acme.okta.com/.well-known/openid-configuration`.
* The client ID and client secret.
* Confirmation that the application releases `email`, and whether it releases `email_verified`.
Operata creates the SSO connection and your users, then tells you when to test.
### 5. Test sign-in
Test with a user Operata has confirmed. Operata creates each user before their first SSO sign-in, so test only after Operata replies.
The user goes to `https://app.operata.io` and enters their work email. Operata redirects them to your IdP. After they authenticate, they land in their Operata account.
## Result
Users whose email matches one of your domains sign in at `https://app.operata.io` with their corporate credentials. Sign-in starts from that page. OIDC has no equivalent of SAML sign-in from a tile in your IdP dashboard.
## Troubleshooting
| Symptom | Cause | Fix |
| - | - | - |
| Entering an email shows a password field | Operata hasn't routed your email domain to your connection | Confirm the domain with Operata Support, then hard-refresh the sign-in page. |
| Your IdP returns a redirect error | A sign-in redirect URI isn't registered | Register both URIs from step 2. |
| The user signs in but sees no data | The email your IdP sent doesn't match an Operata user | Check the email your IdP releases, then contact Operata Support. |
| Sign-in fails with no email | The application doesn't release `email` or lacks the `email` scope | Release `email` and add the `email` scope. |
## Related
* [Request SSO for your Operata account](/docs/guides-request-sso) — SSO through a SAML 2.0 IdP.
* [Configure Okta as an SSO identity provider](/docs/guides-sso-okta) — SAML 2.0 setup in Okta.
# Configure Okta as an SSO identity provider
Source: https://docs.operata.com/docs/guides-sso-okta
Set up a SAML 2.0 application in Okta so Operata users sign in through your corporate directory.
Configure a SAML 2.0 application in your Okta tenant so Operata users authenticate through your corporate directory instead of an Operata password.
## Before you start
* An Okta tenant where you can administer applications.
* An [Operata SSO request open with Operata Support](/docs/guides-request-sso) and the connection name Operata supplied in the reply.
* The email domains your users sign in with.
Operata supports Service-Provider-initiated login only. IdP-initiated login is not supported.
Do not use underscores in connection names, application names, or any other identifier you create here. Auth0 rejects underscores in SAML connection metadata.
## Steps
### 1. Note the URLs Operata supplied
Operata Support replies to the SSO request with the connection name and the two URLs you set on the Okta side. Connection names follow the form `idp-type-customer-name` — for example `okta-acme`.
**Development and test**
* Single Sign-On URL: `https://login-dev.operata.io/login/callback?connection=`
* Audience Restriction: `urn:auth0:dev-operata:`
**Production**
* Single Sign-On URL: `https://login.operata.io/login/callback?connection=`
* Audience Restriction: `urn:auth0:prod-operata:`
### 2. Create a SAML 2.0 application in Okta
Sign in to your Okta admin console and create a new application. Choose **SAML 2.0** as the application type. Include "Operata" in the application name so it surfaces in audits and support handoffs.
### 3. Configure the SAML application
Set the two values from step 1 on the Okta application:
* Paste the **Single Sign-On URL** into Okta's Single Sign-On URL field.
* Paste the **Audience Restriction** into Okta's Audience URI (SP Entity ID) field.
Save the application. Okta generates an App Embed Link and an X.509 signing certificate.
### 4. Capture the app metadata
From the configured application, copy:
* The **App Embed Link** — for example `https://acme.okta.com/home/...//`.
* The **X.509 signing certificate** Okta generated, downloaded in PEM or CER format.
### 5. Send the metadata to Operata
Reply to the open Operata Support thread with:
* The App Embed Link.
* The X.509 signing certificate.
* The email domains to route to this SSO connection.
All listed domains route to the same SSO connection. Operata cannot split domains across separate Okta applications on a single Operata account.
### 6. Add test users and run a joint test
Add a test user to your Okta application under **Directory → People**. Operata configures Auth0, confirms it is ready, and schedules a joint test call. On the call you sign in from `https://app.operata.io` with the test user's email; Auth0 redirects to Okta, Okta authenticates, and you land in the Operata console.
## Result
A user whose email matches one of the domains you listed visits `https://app.operata.io`, enters their email, and is redirected to Okta. After Okta authenticates, the user lands in the Operata console without entering an Operata password.
## Related
* [Request SSO for your Operata account](/docs/guides-request-sso) — the generic SSO request workflow this guide plugs into.
# Headset compatibility
Source: https://docs.operata.com/docs/headset-compatibility
Jabra headsets, operating systems, and browsers the Operata Agent Collector supports for headset telemetry.
The Operata Agent Collector reads headset telemetry from professional Jabra devices via the Jabra browser integration. This page lists the supported devices, operating systems, and browsers.
## Supported devices
All professional Jabra headsets and Jabra speakerphones are supported:
* Jabra Evolve series.
* Jabra Pro series.
* Jabra Biz series.
* Jabra Speak series.
* Jabra Engage series.
## Supported operating systems
| Operating system | Version |
| - | - |
| Windows (64-bit) | Windows 7 or newer |
| Windows (32-bit) | Windows 7 or newer |
| macOS | El Capitan or newer |
## Supported browsers
| Browser | Version |
| - | - |
| Google Chrome | Last three stable versions |
## Related
* [Browser compatibility](/docs/browser-compatibility) — supported Chrome and Edge versions.
* [Platform compatibility](/docs/compatibility-platforms) — certified CCaaS (Contact Center as a Service) versions.
* [Headset logs](/docs/headset-logs) — the data Operata collects from headsets.
* [Jabra JavaScript SDK](https://developer.jabra.com/sdks-and-tools/javascript) — the source library Operata uses to read headset telemetry.
# Headset logs
Source: https://docs.operata.com/docs/headset-logs
Audio analytics, device details, and call-quality status from a Jabra headset, captured by the Agent Collector for each Amazon Connect Contact.
The `headset` object contains Jabra headset analytics, device details, and per-Contact call-quality status captured by the Agent Collector. Headset collection is optional, off by default, and supports a defined set of headset models — see [Headset compatibility](/docs/headset-compatibility).
## Schema
```json theme={null}
{
"analytics": {
"crossTalkTotal": "0.00",
"crossTalkTotalPct": 0,
"rxSpeechTotal": "0.00",
"rxSpeechTotalPct": 0,
"silenceTotal": "9.42",
"silenceTotalPct": 100,
"totalSeconds": "9.42",
"txSpeechTotal": "0.00",
"txSpeechTotalPct": 0
},
"deviceInfo": {
"deviceConnection": "USB",
"deviceName": "Jabra Evolve 75",
"errStatus": 0,
"firmwareVersion": "1.12.0",
"serialNumber": "501AA5D6ABC9"
},
"status": {
"audioExposure": { "avg": 0, "max": 0, "min": 0 },
"backgroundNoise": { "avg": 0, "max": 0, "min": 0 },
"boomArm": {},
"muteCount": 0,
"volUpDownCount": 0
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `analytics.crossTalkTotal` | string (seconds) | yes | Cross-talk time during the Contact. | `11.41` |
| `analytics.crossTalkTotalPct` | number | yes | Cross-talk time as a percentage of the Contact. | `11.99` |
| `analytics.rxSpeechTotal` | string (seconds) | yes | Receive audio time (customer speaking). | `5.78` |
| `analytics.rxSpeechTotalPct` | number | yes | Receive audio time as a percentage of the Contact. | `11.41` |
| `analytics.silenceTotal` | string (seconds) | yes | Silence time during the Contact. | `60.47` |
| `analytics.silenceTotalPct` | number | yes | Silence time as a percentage of the Contact. | `63.56` |
| `analytics.totalSeconds` | string (seconds) | yes | Total Contact duration as measured by the headset. | `95.14` |
| `analytics.txSpeechTotal` | string (seconds) | yes | Transmit audio time (agent speaking). | `17.48` |
| `analytics.txSpeechTotalPct` | number | yes | Transmit audio time as a percentage of the Contact. | `18.37` |
| `deviceInfo.deviceConnection` | string | yes | Jabra headset connection type. One of `USB`, `Bluetooth`, `DECT`. | `USB` |
| `deviceInfo.deviceName` | string | yes | Jabra headset model name. | `Jabra Evolve 75` |
| `deviceInfo.errStatus` | integer | yes | Jabra headset error status code. `0` means no error. | `0` |
| `deviceInfo.firmwareVersion` | string | yes | Jabra headset firmware version. | `1.12.0` |
| `deviceInfo.serialNumber` | string | yes | Jabra headset serial number. | `501AA5D6ABC9` |
| `status.audioExposure` | object | yes | Audio exposure in decibels — `min`, `max`, `avg` across the Contact. | `{ "avg": 65, "max": 71, "min": 60 }` |
| `status.backgroundNoise` | object | yes | Background noise in decibels — `min`, `max`, `avg` across the Contact. | `{ "avg": 41, "max": 55, "min": 28 }` |
| `status.boomArm` | object | no | Boom-arm position events. Empty when no incorrect-position events occurred. | `{}` |
| `status.muteCount` | integer | yes | Number of mute events during the Contact. | `3` |
| `status.volUpDownCount` | integer | yes | Number of volume adjustments during the Contact. | `14` |
## Notes
* `analytics.*Total` fields are strings formatted as seconds with two decimal places (e.g. `"11.41"`); the corresponding `*TotalPct` fields are numbers.
* `status.boomArm` is optional and is absent or empty (`{}`) when no incorrect boom-arm position events occurred during the Contact.
* `deviceInfo.errStatus` of `0` means no error. Non-zero values reflect Jabra SDK error codes.
* Headset data appears only when the Agent Collector's headset integration is enabled and the connected device is a supported Jabra model.
# Set up Heartbeat
Source: https://docs.operata.com/docs/heartbeat-setup
Create the Amazon Connect routing profile, contact flow, Lambda binding, and phone number that drive Heartbeat synthetic test calls.
Configure your Amazon Connect instance with the routing profile, Heartbeat contact
flow, and dedicated phone number the Cloud Orchestrator dials to place synthetic
test calls — after these steps the Virtual Agent can answer them and Heartbeat
runs can begin.
## Before you start
* [Cloud Orchestrator installed](/docs/orchestrator-installation) in
the same AWS region as your Amazon Connect instance. The Orchestrator
CloudFormation stack creates the Lambda function this guide binds
into Amazon Connect.
* Amazon Connect administrator access — you sign in using emergency
access throughout this guide.
* An Operata-supplied `HeartbeatContactFlow.json` file. Contact
[Operata Support](mailto:support@operata.com) for the link.
* The [Cloud Orchestrator concept](/docs/concepts-cloud-orchestrator)
read end to end — Heartbeat is one of two products that runs on the
Orchestrator.
## Steps
### 1. Create the `Operata_Heartbeat_RP` routing profile
Sign in to the Amazon Connect console using emergency access. Open
**Routing → Routing profiles** and click **Add new profile**.
* **Name:** `Operata_Heartbeat_RP` — the exact name Cloud Orchestrator
expects.
* **Channels:** select the **Voice** checkbox.
* **Queues:** add any inbound and outbound queue so the Virtual Agent
can make and take a call.
Save the profile. The name must match the
`OperataHeartbeatRoutingProfile` parameter you set when you deployed
the Orchestrator stack.
### 2. Add the Cloud Orchestrator Lambda to Amazon Connect
In the Amazon Connect console, open **Contact flows** and scroll to
the **AWS Lambda** section.
In the dropdown, find the Lambda created by the Cloud Orchestrator
CloudFormation stack. Its name lives in the **Resources** tab of the
Orchestrator stack. Click **+ Add Lambda Function**.
The Lambda is now selectable inside any contact flow in this Amazon
Connect instance.
### 3. Import the Heartbeat contact flow
Download `HeartbeatContactFlow.json` from the link Operata supplied,
then follow the [AWS guide to import a contact flow](https://docs.aws.amazon.com/connect/latest/adminguide/contact-flow-import-export.html)
into your Amazon Connect instance.
### 4. Bind the Heartbeat Lambda inside the contact flow
In the Amazon Connect console, open **Contact flows** and select the
contact flow you just imported.
Click the **Invoke AWS Lambda function** block, choose the Cloud
Orchestrator Lambda from the dropdown, then **Save**. Click
**Publish**.
### 5. Claim and route the Heartbeat phone number
In the Amazon Connect console, open **Channels → Phone numbers**.
Either **Claim a number** or **Edit phone number**, and associate it
with the Heartbeat contact flow you imported. Save.
Send the number to [Operata Support](mailto:support@operata.com) so
Operata can configure it on the platform side — the Orchestrator
dials this number on each Heartbeat run.
## Verify
In the Amazon Connect console, open the Heartbeat contact flow and
confirm the **Invoke AWS Lambda function** block points at the Cloud
Orchestrator Lambda and the flow is published. In **Phone numbers**,
confirm the Heartbeat number routes to that contact flow.
The first Heartbeat run completes once a Virtual Agent is in place —
see [Heartbeat Virtual Agent](/docs/virtual-agent) for the next step.
A test call placed manually to the Heartbeat number from the agent
side rings the configured contact flow and invokes the Lambda.
## What the agent sees
Here's the end-to-end sequence for an Amazon Connect agent on a Heartbeat run.
For the agent-facing version of this, see [Heartbeat: what the agent sees](/docs/help/amazon-connect-cx-heartbeat-agent-experience).
## Related
* [Heartbeat Virtual Agent](/docs/virtual-agent) — deploy the
containerized agent that answers Heartbeat calls.
* [Virtual Agent troubleshooting](/docs/virtual-agent-troubleshooting) —
confirm the Virtual Agent is running and logged in.
* [Concept: Cloud Orchestrator](/docs/concepts-cloud-orchestrator) —
how the Lambda, ECS service, and Virtual Agent fit together.
* [EventBridge](/docs/concepts-eventbridge) — receive each Heartbeat
run's result on your event bus.
# Tenor for human agents
Source: https://docs.operata.com/docs/help/agent-copilot
The agent interface to report issues and to get self-fix CX notifications.
Tenor for human agents helps you report issues in a couple of clicks and gives you a heads-up when something's gone wrong that you can fix yourself.
***
## Moving and positioning Tenor
You can move Tenor up, down, left, or right - wherever it sits best for you.
It remembers the spot next time you open your softphone.
#### Move Tenor up and down
Drag the three dots (or icon edge) to move up or down.
#### Move Tenor left and right
Open Tenor and select the solid bar on the top right hand corner to toggle between left and right - select X when done.
***
### Report Issue
Click the icon to open a quick form where you can pick from a list of common issues, set how serious it is, and add any notes that will help identify the cause.
***
### Technology performance Alerts
Tenor can give you a heads-up when there's a technology issue that might affect your calls or softphone - things like a flaky network or a headset that's stopped behaving.
Tap **Read more** on any alert and you'll get step-by-step advice for fixing it yourself.
#### What you might be alerted about
**Your connection and computer**
* **Network performance** - your connection quality has dropped far enough to affect call audio.
* **Computer performance** - your CPU is under sustained heavy load, which can degrade the softphone.
* **Microphone not shared** - your browser doesn't have access to your microphone.
**Your headset**
These alerts need a compatible Jabra headset with the Jabra client software installed. See the [Jabra quick start](/docs/help/jabra-quick-start) if you're not sure whether yours is set up.
* **Not using your Jabra device** - audio is running through a different device than expected.
* **Talking on mute** - you're speaking while muted.
* **Frequent muting** - you've muted several times within a single call.
* **Background noise** - there's excessive noise around you, including cases where you've turned your volume up or muted repeatedly to work around it.
* **Crosstalk** - you and the customer are talking over each other, sometimes caused by high network latency.
* **Audio exposure** - your headset volume has been high enough for long enough to be worth reducing.
* **Battery level** - your headset battery is low, or very low.
Your administrator chooses which of these are switched on for your team and sets the thresholds that trigger them, so you may not see all of them. Alerts can also appear as a pop-out toast banner if that's been enabled - see [Group Settings](/docs/help/group-settings) for the configuration behind this.
# Agent Readiness Test
Source: https://docs.operata.com/docs/help/agent-readiness-test
Agents score the playback quality of their test recording, while technical performance metrics are captured in Operata.
## What is it?
The Agent Readiness Test automatically runs a test sequence that measures audio quality, prompts agents with self-fix solutions and sends metrics to Operata to aid investigation into repeated test failures.
***
## What is it for?
Agents can self elect to run this test before taking the first customer call, or can run the test after experiencing an issue (to confirm any repeating issue and exclude a customer audio issue)
To resolve repeated test failures, detailed metrics for all Agent Tests are captured in Operata.
***
## How do I enable it?
Create a new Agent Status called '**Agent Test**'
***
## How does it work?
When agents move to an 'Agent Test' agent state they are prompted to **Run Test**.
This automatic sequence makes and outbound call and prompts the agents to:
1. Record some audio - we suggest '*their name and I'm ready to start my day*'
2. Audio playback - their recording is played back to them - *they hear how they sound to customers*.
3. Self '**assess**' their view of audio quality (1 for good, 2 for bad).
4. Be prompted when something is detected that may have caused an issue, for example, not using a headset.
Once the test has completed and the call has ended (the test takes no more than one minute) then:
* The agent score, Operata '**measured**' audio quality score and all the technical performance data is captured in a dedicated **Agent Readiness Test** dashboard.
***
## What to the results tell me?
Once the full test results have been processed by Operata (this can take up to 15 minutes) all the fields in the Agent Readiness Test dashboard will be populated.
Each test falls into one of four categories:
1. **Pass - All Good**: agent assessment and measured audio quality is good.
2. **Fail - Poor Audio:** both the agent assessed the call as poor and the measured audio quality was poor.
3. **Fail - Agent audio assessment**: the agent assessed the call as poor.
4. **Fail - Measured Audio assessment:** the measured audio quality was poor.
5. **No test** - the test failed to fully execute for some reason.
The time-line view shows the frequency and results of the tests over time
The detail of each call is shown in the table.
***What to the fields show\...***
* **agent\_readiness\_risk\_level** - the overall assessment of the agent test.
* **connecting\_time** - when the agent test happened.
* **Agent** - the agent that made the test.
* **Links**
* ***Agent*** - the 28-day view of the agents calls and technical metrics
* ***Call*** - summary details of the test call
* ***Details*** - per-second view of the test call with all metrics and error logs
* **Agent Assessment** - the agents view of audio quality, they selected (1 for Pass and 2 for Fail).
* **Operata Quality Score** - The measured audio quality (\<3.5 is poor)
* **Network (Min / Avg)** - The worst case (1 second ) and average network quality using the MOS score (Min \<3.5 and Average \<3 is poor)
* **Peak CPU** - The peak percentage of CPU used during the call.
* **Audio Levels** - Customer (the agent audio playback) and Agent audio detection.
* **Headset** - Headset Microphone (good) or Internal Microphone (bad) detction
* **Hold/Mute** - Hold / Mute used during the test
* **%Music** - Music detected during the test.
* **Test Length** - overall test duration
* **contact\_id** - Call ID for the call to enable investigation and playback is needed.
***
# Amazon Connect - data network capacity used for Monitoring and CCP log collection
Source: https://docs.operata.com/docs/help/amazon-connect-data-network-capacity-used-for-monitoring-and-ccp-log-collection
With the Chrome Extension is installed and Log collection enabled, Operata passes data and CCP logs to Operata, but how much data is passed?
## **Operata Collector for Chrome**
Agent softphone and PC performance data collected then securely sent over the network and/or internet connection to the Operata platform.
* Every 30-seconds, call performance details are sent to Operata ***(400 bytes)***
* At the end of a call, the call performance summary is sent to Operata ***(400 bytes)***
* Whenever an agent changes state Operata is updated ***(400 bytes)***
* Every minute ccp log files are sent to Operata - the file size will depend on the log level set within Operata and critically the number of errors, see below.
As the file sizes are so small a good estimate is that 3,000 concurrent agents will use less than 50Kbps of data network bandwidth sending data to Operata.
## **CCP Log Collection**
If CCP log collection is enabled, then they are buffered locally and sent to Operata every 60-seconds.
Two factors impact the amount of CCP log data that is passed to Operata every minute:
1. **The configured log level** - There are seven log levels, from Trace (the most data, capturing everything that happens) to Critical (the least data, only sent if there is a Critical issue)
2. **The number errors and events** - The more events and errors the more CCP log data is generated to be passed to Operata.
The table below details the typical volume of data passed to Operata at each log level.
| Operata Log Level | Typical CCP log data, captured per agent each minute. |
| - | - |
| **TRACE** – the most fine-grained information only used in rare cases where full visibility of what is happening in your application and inside the third-party libraries that you use is needed. You can expect the TRACE logging level to be very verbose. | 3.5KB |
| **DEBUG** – less granular compared to the TRACE level. The DEBUG log level should be used for information that may be needed for diagnosing issues and troubleshooting or when running application in the test environment for the purpose of making sure everything is running correctly | 2.5KB |
| **INFO** – the standard log level indicating that something happened, the application entered a certain state, etc. The information logged using the INFO log level should be purely informative and not looking into them on a regular basis shouldn’t result in missing any important information. | 1KB |
| **LOG** - AWS recommended default level of logging | 1KB |
| **WARN** – the log level that indicates that something unexpected happened in the application, a problem, or a situation that might disturb one of the processes. But that doesn’t mean that the application failed. The WARN level should be used in situations that are unexpected, but the code can continue the work. | `<1`KB |
| **ERROR** – the log level that should be used when the application hits an issue preventing one or more functionalities from properly functioning. | `<1`KB |
| **CRITICAL** – the log level that tells that the application encountered an event or entered a state in which one of the crucial business functionality is no longer working. | `<1`KB |
# Amazon Connect - Heartbeat test results (new)
Source: https://docs.operata.com/docs/help/amazon-connect-heartbeat-test-results-new
What the results pages will look like when updated..
Heartbeat Test Results
What do the results mean?
Selecting a result from the scatter graph or via the results dial list, displays results of the tests in five sections:
***Note:*** *the **Operata Audio Quality** score is a measurement between 5 (excellent) and 1 (poor)*
[Operata Audio Quality score explained](/docs/help/what-is-mos)
## 1. Test Run Details
A summary of the test and highlights of any issues found:
* **Agent Type:** Human/Virtual.
* **Start:** The time the test run started, not necessarily the time the test happened.
* **End:** The time the test run ended.
* **Date:** The date of the test run (Date/Month/Year)
* **Heartbeat Id:** The Operata test identifier (not the Amazon Connect callContactID).
* **Top Insights:** Highlights of the issues detected during the test run.
## 2. Telephony
The results show the performance of the Telephone network used to connect the customer to Amazon Connect.
\[LHS] Details
* **Dialled Number:** The number dialled for the test (could be a toll-free number)
* **Answer Point DID:** The Amazon Connect number the call was delivered to.
\[Centre] Results
**Status:** The status of the test call made by the Virtual Customer to the Call Center \[has be one of these five]
* ***Completed:*** The test call connected and the test completed
* ***Failed:*** The test call could not be made.
* ***Busy:*** The test call received busy tone.
* ***No Answer:*** The test call was not answered by the Contact Center.
* ***Call Disconnected Prematurely*:** The test call was answered, but disconnected before the test completed.
* ***Remove its an insight \[High Ringing Time:*** The test call took longer to answer than expected (answer time)]
* **Post Dial Delay:** The time in ms (1,000 ms = 1 seconds) it took the test call to receive ringtone from Contact Center once it had completed dialling.
* **Ringing Time** \[currently Answer Time]: The time in ms \[seconds] it took from when the test call received ringtone to it being answered by the Contact Center.
## 3. Customer - Contact Center
words
\[LHS] Results
* **Customer to Contact Center - Audio Loss:** The percentage drop in the quality of the audio received by Amazon Connect from the Virtual Customer.
* **Customer to Contact Center - Score:** The **Operata Audio Quality** score is the quality of the audio received by Amazon Connect from the Virtual Customer.
* **Contact Center to Customer - Audio Loss:** The percentage drop in the quality of the audio received by the Virtual Customer from Amazon Connect.
* **Contact Center to Customer - Score:** The **Operata Audio Quality** score is the quality of the audio received by the Virtual Customer from Amazon Connect.
* **Customer - Contact Center RTT:** The time in ms (1,000 ms = 1 seconds) it took audio to get from the Virtual Customer to Amazon Connect and back
* **Audio RTT \[Latency]:** The time in ms for audio to get from the Virtual Customer to the Agent and back to the Virtual Customer.
## 4. Contact Center - Agent (Agent Username)
words
\[LHS] Results
* **Contact Centre to Agent - Audio Loss:** The percentage drop in the quality of audio received by the test Agent from the Contact Center.
* **Contact Centre to Agent - Score:** The **Operata Audio Quality** score is the quality of the audio received by the test Agent from the Contact Center.
* **Agent to Contact Centre - Audio Loss:** The percentage drop in the quality of audio received by the Contact Center from the test Agent.
* **Agent to Contact Centre - Score:** The **Operata Audio Quality** score is the quality of the audio received by the Contact Center from the test Agent.
* **Contact Center - Agent RTT:** The time taken in ms for the test audio file sent from Connect to reach the test agent and get back to Connect.
* **Audio RTT \[Latency]:** The time in ms for audio to get from the Virtual Customer to the Agent and back to the Virtual Customer.
\[Centre] Hardware
* **CPU Utilisation:** The Average, Min and Max Percentage CPU utilisation of the test agents machine, during the test.
* **Agent Username:** The Amazon Connect Username used to login to the softphone
* **CPU Type:** Processor type on the test agent.
\[RHS] Software
* **Browser Type Version:** Browser type and version of the test agent.
## 5. Network (XX/10)
The quality of the data network which is given an overall Operata Experience score out of 10.
[How the Operata Experience score is calculated](/docs/help/heartbeat-cx-and-ax-score)
\[LHS] Results
* **Packet Loss:** The Average, Min and Max percentage inbound packet loss
* **Jitter:** The Average, Min and Max inbound jitter in ms
* **RTT:** The Average, Min and Max Round Trip Time in ms
* **MOS:** The Average, Min and Max MOS (Mean Opinion Score)
\[Centre] Network details
* **Agent LAN IP:** The Agents LAN IP address (either local or assigned, by a VPN for example)
* **Agent WAN IP:** The Agents Internet WAN IP address (may not be the same as the voice media path)
* **Network Type:** The test agents network type.
RHS \[Signalling/Media]
* **TURN server FQDN + Port:** The Amazon TURN and Port used for the test call.
# Amazon Connect - How can I report Agent interaction and hold Time?
Source: https://docs.operata.com/docs/help/amazon-connect-how-can-i-report-agent-interaction-and-hold-time
Operata bills Amazon Connect usage on agent interaction and hold time, measured in minutes. Here's how to find those figures in your Amazon Connect account.
Although Operata collects detail on every second of every call, Operata charges are based only on the time Agents have the call, this is known as Agent interaction and hold time - here's how to get this minute detail.
From your Amazon Connect Management console select **Historical Metrics**
Then select **Agents**
Now select the **Cog** icon on the RHS and then **Interval & Time range**, select the **Time range** you need and then move to the **Groupings** tab.
From **Groupings**, de-select **Agent** (this will show the total number of seconds only) and then move to the **Metrics** tab.
From **Metrics**, un-check all the Metrics and add only **Agent interaction and hold time** and finally select **Apply** and wait for the results.
***Note:*** *You may need to select smaller time periods if the record count exceeds AWS limits*
**Export** the results to **csv** and use your spreadsheet of choice to calculate the total minutes
***Note:*** Operata rounds up to the nearest minute for each call, so the number may not be exactly the same - but will be close (normally within 10-15%)
# Amazon Connect: what the AWS integration adds
Source: https://docs.operata.com/docs/help/aws-integration-benefits
What CTR and conversational analytics data add to Operata on Amazon Connect: complete contact records, coverage comparison, Hierarchy group filtering, Data Teams, and customer experience metrics.
There is the option of supplementing Operata browser extension collected data with data from within the Amazon cloud - ***AWS integration***.
Operata AWS integration uses AWS EventBridge pipes to securely push data to Operata with Privacy Controls to give customers control of the data elements sent.
[AWS Integration technical and deployment details](/docs/integrations-amazon-connect-overview)
There are significant benefits in enabling this Operata feature..
For the platform-neutral version of this page, see [What cloud collection adds](/docs/cloud-collection-benefits).
***
## Contact Trace Records (CTR)
### Data completeness
The data Operata collects from the softphone is accurate, but misses parts of data for how the call originated, how it was delivered and when the call is transferred.
Adding AWS integration brings in CTR data that fills these gaps.
***
#### Coverage
Optimal Technical and Operational performance is only realised when browser collected data is captured from all agents, understanding gaps in this coverage is key to filling them.
AWS integration enables **Cloud** data comparison vs **Browser** extension data with the details shown in the Collection Coverage dashboard.
***
#### Amazon Connect Hierarchy groups (Agent Groups)
Amazon Connect agent configurations can include [Hierarchy groups](https://docs.aws.amazon.com/connect/latest/adminguide/agent-hierarchy.html) (called Agent Groups in Operata) to add business level details such as teams or locations.
AWS integration automatically enables Operata dashboard views to be filterable using any or all of these values.
***
#### Data Teams
Users accessing Operata often need to be restricted to see only the dashboards and metrics relevant to their role.
Data Teams enables role-specific visibility with Operata, with Hierarchy Group (Agent Group) and CTR attributes used to determine the data seen.
Only with AWS integration will Data Teams be available.
***
***
## Conversational analytics
#### Customer Experience metrics
Understanding how customer calls originate, their treatment before being presented to agents and where calls are transferred to, is an important part of overall Customer Experience management.
AWS integration provides a more complete view of these details within the Customer Experience and Agent Interactions dashboards, specifically:
* **Call Queues** - Queue, IVR and Connection durations.
* **Call Transfers** - Internal and external transfer details, with a transfer map.
* **Call Initiation and disconnection** - detail on how calls originated and were disconnected.
* **Repeat calls** - Optional customer phone number capture needed to see the pattern of interactions over time, based on the calling number.
***
***
# Checking Operata service status and reporting platform issues
Source: https://docs.operata.com/docs/help/checking-operata-service-status-and-reporting-platform-issues
How to check whether Operata is experiencing a platform issue, quick self-service checks to try first, and how to report an issue to the Operata support team with the right information.
## Overview
If Operata appears to be down, loading slowly, or behaving unexpectedly, this article explains how to check the current service status and how to report an issue to the Operata team.
***
## Checking service status
Before contacting support, check whether there is a known platform issue:
* Check [https://trust.operata.com/](https://trust.operata.com/) to see real-time platform availability.
* Look for a **banner or notification** at the top of the Operata app — the team posts status updates here during incidents.
* Contact your Operata admin or CSM — they may already be aware of a platform event and in contact with the Operata team.
* Use the **chat widget** on this Help Centre page to ask Operata support if there is a current incident.
***
## Before reporting — quick checks
Some issues are local rather than platform-wide. Try these before contacting support:
* **Hard refresh** — press Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
* **Clear browser cache** — go to browser settings and clear cached images and files
* **Try a different browser** — if the issue is browser-specific, this will confirm it
* **Check your network** — try loading another site to confirm your internet connection is working
* **Connect from a different network** — try pairing to a mobile network to access Operata.
* **Ask a colleague** — if others in your team can access Operata normally, the issue may be local to your machine
***
## Reporting a platform issue to Operata
Report issues using either of the following options:
1. URL: Link to a form to capture data ([https://operata.com/support](https://operata.com/support))
2. Web chat (within the application) using the Have an issue 'Let Operata know' button.
# Custom Dashboard Creation
Source: https://docs.operata.com/docs/help/custom-dashboard-creation
There is a new process to create/edit Custom Dashboards - here's how.
Selecting the three dots to edit the charts and dashboards is no longer possible, a new process adds a layer of Operata review to ensure your dashboards are as performant as possible.
***
## Step 1 - Contact your Operata Customer Success Team
Use the Operata widget, email or Slack to let Operata know which Operata Group you need to create Custom Dashboards in - this gives you permanent access to edit the dashboards you have created.
The Operata team will contact you when you can create your own and the Dashboard administration url you need to use.
***
## Step 2 - Login to the Operata Group
Login the to the specific Group you want to create custom dashboards in at **Admin** level.
**From a new tab** access the Dashboard administration area:
* AU hosted customers - [https://bi-admin.operata.io/](https://bi-admin.operata.io/)
* US hosted customers - [https://bi-admin-us-east-2.operata.io/](https://bi-admin-us-east-2.operata.io/)
***
## Step 3 - Create/edit your Custom Dashboard in the bi-admin area
Select the Dashboards tab to see the latest Operata curated dashboards - copying and editing these, or the charts within them is often the best place to start.
Open the dashboard you want to start from, select the three dots on the Right Hand corner.
Save as (using your preferred dashboard name)
Edit the dashboard.
Even, drag other charts into the dashboard.
When you are ready **SAVE** the dashboard and it will appear in the bi-admin area dashboard list as **Draft**.
Open the dashboard and select **Draft** to toggle it to **Published**.
***
## Step 4 - Contact your Operata Customer Success Team
Use the Operata widget, email or Slack to let Operata know the Group and Dashboard name you want published.
The Dashboard will appear in the drop-down list of dashboards.
***
***
## Data table mapping from Canvas to Dashboards
Migrating custom dashboards from Superset 1 (Canvas icon) to Superset 4 (Dashboard icon) is a manual process.
As there is no direct mapping between the data tables, the best option is to use the Operata curated charts as a starting point and the schema for details of the table contents.
The fact tables are the most commonly used data sets
* fact\_\_call\_summaries\_with\_dimensions
* fact\_\_call\_events\_with\_dimensions
* fact\_\_agent\_status\_with\_dimensions
* fact\_\_contact\_lens\_with\_dimensions
* fact\_\_agent\_reported\_issue\_with\_dimensions
* fact\_\_softphone\_logs\_with\_dimensions
The other tables are less frequently used targeted data sets
* prior\_call
* next\_call
* surrounding\_calls
* surrounding\_agent\_status
* surrounding\_logs
* call\_insights
* agent\_status\_with\_logs
* calls\_with\_headsets
* contact\_lens\_with\_attributes
* dim\_agen
***
If there are any issues please contact your Operata Customer Success Team.
# Dashboard Changes
Source: https://docs.operata.com/docs/help/dashboard-changes
Changes as part of Dashboard re-platforming
We're re-platforming your dashboards to deliver faster performance, the dashboards content will be unchanged and no data will be lost, but there are some minor changes.
**Note:** For some customers this change has already happened
### ***What's not changing..***
* The data shown in your dashboards is identical.
* Nothing is being removed and no data will be lost.
* All historical data remains intact and accessible.
### ***What is changing..***
* A new **Dashboard** icon will appear in the toolbar to access the new dashboards.
* In some cases, the new **Dashboard** icon will replace the existing **Canvas** icon.
* There are some minor changes to how dashboards are used and filtered (see below)
* There is a change to the way Custom Dashboards are created (see below)
***
### Dashboard Filters
Applying a filter to using the dashboard, adds it to the filter bar.
To remove a filter you need to either remove from the filter bar, or re-select the section of the Donut chart used to filter.
***
### Custom Dashboards
You can no longer copy your own versions of the standard dashboards to create and edit.
Contact Operata to discuss the details of any new Custom Dashboards or to edit existing Custom Dashboards.
# Data Retention
Source: https://docs.operata.com/docs/help/data-retention
How long will data be retained in Operata?
Operata retains second-by-second detail for shorter periods than rolled-up summary data, with the data accessible in three ways:
## Tenor
* **65** days of data can be queried using Tenor
***
## Canvas dashboards
* **14-days** - Agent Softphone Logs at level 'WARN' or 'INFO'
* **30-days** - Agent Softphone Logs at level 'ERROR'
* **30-days** - Softphone Error States
* **65-days -** Detailed data
***
## Calls and Logs
* **14-days** - Softphone Logs
* **3-Years -** Call Stats Log - All the post call data collected for each call is summarised (including CTR and conversational analytics data within AWS CCaaS environments).
[Details on Operata data collection](/docs/get-started-overview)
***Note:*** Log download has a 10,000 record download limit
***
## Operata API
* **14-days** - Softphone Logs
* **3-Years -** Call Stats Log - All the post call data collected for each call is summarised (including CTR and conversational analytics data within AWS CCaaS environments).
* The detail and frequency of data collection is detailed in the Operata Developer Hub
[Developer Hub](/docs/get-started-overview)
Details of using the Operata API cal also be found in the Operata Developer Hub
[Using the Operata API](/docs/api-authentication)
# Data Teams
Source: https://docs.operata.com/docs/help/data-teams
Give the right people access to only the data they need..
## What is Data Teams?
You can now limit the data seen by Teammates when they login to Operata, giving access to a sub-set of Canvas dashboards that only show data for specific agents/calls based on:
* ***Agent Groups*** (from Hierarchy Groups within Amazon Connect customers)
* ***Call Attributes*** (from Contact Trace Records (CTR) within Amazon Connect customers)
## Using Data Teams
There is a new type of Operata Teammate called a **Group Viewer** that can be configured within one or more **Teams** that **Filters** the data they see dashboards based on defined Agent Groups or CTR attributes.
**Note:** **User** and **Admin** user types can also be configured as **Members** within Data Teams, this will limit the Dashboards they can see, but **NOT** any of the **Filter** conditions.
***
### Creating Viewer Teammates
When creating a Teammate select the Role 'Group Viewer'
When logged in as a **Group Viewer** only the **Dashboards** option is visible with a drop-down of Operata Groups the Teammate has access to and a list of the specific dashboards enabled for them.
***
### Creating Teams
**Teams** define both the data filters and access to specific dashboards.
Admin level Teammates can create, edit and delete **Teams** and then add Teammates to them, here's how\..
Select **Dashboards** and then **Manage Access**
The drop-down on the Left Hand Side shows the **Roles** you are configured for in this Group, this is ideal for testing the Date Roles you have configured.
Select **New Role +** to create a new role
Name it an then select **Create.**
Once created it will appear in the Teams list, select Edit to configure the filters by selecting +Adding Condition
Enter the Agent Group (Amazon Connect Hierarchy Groups) and CTR attributes that you will filter the data using.
Use the check-boxes to select the Dashboards you need this Team to access.
The select **Save..**
**Note:** Selected CTR attributes must be defined in the Privacy Controls allow list
**Note:** On first run all the Dashboard options will be shown, but only the allowed dashboards can be selected.. This issue is resolved when next accessing Operata
Finally add Add Teammates to the Team..
Select **View Members.**
Use the dropdown to select the Teammate and then **Add Team Member**.
***
# Amazon Connect: capture WebRTC diagnostics
Source: https://docs.operata.com/docs/help/dump-function-amazon-connect
Run the Operata dump function in the agent's browser console to capture the live WebRTC session when Operata isn't collecting the data it should.
This function captures all the data we need to trouble shoot data collection issues for Amazon Connect based softphone services.
To use it, launch your Amazon Connect based softphone and while its selected, right click and select **inspect**.
Select Console and paste this entire code block into the console, enter return and the response **\<- undefined** should be seen.
```
// connect versionasync function diagDump() { return Promise.all([window.operataDataAdaptor.getRTCSession()._pc].map(async (peerConnection) => await ( { id: peerConnection.__rtcStatsId, isTrackedByOperata: window.operataDataAdaptor.getRTCSession()._pc.__rtcStatsId === peerConnection.__rtcStatsId, peerConnectionDetails: { signallingState: peerConnection.signallingState, connectionState: peerConnection.connectionState, iceConnectionState: peerConnection.iceConnectionState, localStreams: peerConnection.getLocalStreams(), remoteStreams: peerConnection.getRemoteStreams(), receivers: peerConnection.getReceivers(), senders: peerConnection.getSenders(), }, // stats: await window.operataDataAdaptor.getRTCSession()?.getStats(), configuration: peerConnection.getConfiguration(), modernStats: Array.from((await peerConnection.getStats()).values()), legacyStats: await (new Promise(function (resolve) { peerConnection.getStats(function (rawStats) { resolve(rawStats); }); }).then(a => a.result().map( result => ({ type: result.type, id: result.id, ...result.names().reduce((obj, n) => ({...obj, [n]: result.stat(n)}), {}) }) ))) } )));}
```
Now make or take a call and once the call is established, paste the command below into the console, enter return and the console should return a **\[\{…}]** prompt.
```
await diagDump();
```
Finally, hover over the **\[\{…}]** prompt, right click and **copy object**
Paste the content into an email and send to Operata **[help@operata.com](mailto:help@operata.com)**
# Genesys Cloud CX - How can I report Agent talk and hold time?
Source: https://docs.operata.com/docs/help/genesys-cloud-cx-how-can-i-report-agent-talk-and-hold-time
Operata charges for Genesys Cloud CX are based on the minutes of Agent talk and hold time, here's how to find this detail.
Although Operata collects detail on every second of every call, Operata charges are based only on the time Agents have the call, this is known as Agent talk and hold time - here's how to get this minute detail.
***
## Permissions required
The user pulling the figures requires one of the following permission sets in Genesys Cloud:
• Analytics > Agent Aggregate > View
• UI > Supervisor > View
• A custom role with access to the Performance workspace views
***
## Step-by-step
Log in to **Genesys Cloud** at **[https://apps.\.pure.cloud](https://apps.\\\.pure.cloud)** - substituting the appropriate regional domain (mypurecloud.com.au, mypurecloud.com, mypurecloud.de, etc.).
From the top navigation, click **Performance** → **Workspace** → **Contact Center** → **Agents Performance**.
In the **date picker** (top right), select **Custom** and choose the first day of the calendar month through to the last day of the same month. For example, 1 April 2026 to 30 April 2026.
In the **Filter** pane on the left, set **Media Type** to **Voice** only. Clear any other media types to avoid including chat or email handle time.
Click the **column picker** (the gear icon above the table) and ensure the following columns are visible:
* **Avg Talk Time**
* **Total Talk Time**
* **Avg Hold Time**
* **Total Hold Time**
* **Total Handle Time** (cross-check only - this includes after-call work and is not used in the calculation)
* **Answered**.
Leave the agent filter blank to include every agent, or select specific agents to scope to a subset of the contact centre.
Click **Export** (top right), choose **CSV** as the output format and **Selected columns**. Genesys Cloud will email the file to the requester within a few minutes.
***Note:*** *For a more reliable baseline, repeat the export for the two preceding calendar months, particularly if your contact centre has seasonal demand patterns.*
***
## Converting the export to billable minutes
| Column | Formula | Example |
| - | - | - |
| Talk seconds | Convert Total Talk Time to seconds | 5h 12m 30s → 18,750 |
| Hold seconds | Convert Total Hold Time to seconds | 0h 38m 15s → 2,295 |
| Combined seconds | Talk seconds + Hold seconds | 21,045 |
| Billable minutes (per agent) | =CEILING(Combined seconds / 60) | 351 minutes |
***Note:*** *Operata rounds each call up to the nearest minute, not at the per-agent-monthly level, so the number may not be exactly the same - but will be close (normally within approximately 10%).*
# Getting help and reporting issues
Source: https://docs.operata.com/docs/help/getting-help-and-reporting-issues
How to get any questions answered and report issues with Operata
Select the speech bubble at the bottom right hand side to ask questions and report issues
***
### Asking questions
Select 'Send us a message' if you have any questions on how to use the Operata platform, one of the team will respond as quickly as possible.
***
### Finding help
Use the 'Search for help' feature to search the Operata user guides for the answer to any question.
***
### Operata training centre and user guides
Select 'Help' to select curated training material and user guides.
***
## Reporting issues
Raise any issues with the Operata platform using:
* Using the 'Have an issue' feature within the Operata help bubble.
If the platform is unavailable use this [Web form](https://operata.typeform.com/to/jDGyCVW3#name=xxxxx\&email=xxxxx\&company=xxxxx\&country=xxxxx).
***
### Operata Response and Restoration SLA
Upon receipt of a Support Services request Operata will determine the Severity Level applicable to the underlying issue, Operata uses the following severity classification.
| Severity Level | Underlying issue | Initial Response Timeframe | Restoration Target |
| - | - | - | - |
| **Critical** | Inability to collect any Customer data | 2 Business Hours | 6 Business Hours |
| **Serious** | No access to the Operata platform or collected data | 4 Business Hours | 12 Business Hours |
| **Moderate** | Non-critical data or functionality issue | 8 Business Hours | 24 Business Hours |
| **Minor** | Any impairment of the Software not falling into the above categories; and any cosmetic issue affecting the Software | 16 Business Hours | 160 Business Hours |
The initial response will set out the anticipated timeframe for resolution of the issue raised in the Support Service Requests.
Business Day means any weekday other than a public holiday in the Country of Service.
Business Hours means the hours of 08:00 to 18:00 on a Business Day in the Country of Service.
To the extent commercially practical, Operata will use reasonable endeavours to provide a final Resolution to the underlying issue promptly in proportion to the applicable severity level.
***
### Operata Service availability targets
The Operata monthly availability target 99.9%
Availability measurement is the percentage of time a Critical level service issue has impacted monthly availability, and excludes planned maintenance activities.
[Current Operata Availability](https://trust.operata.com/)
# How to activate your Operata account (and what to do if it fails)
Source: https://docs.operata.com/docs/help/how-to-activate-your-operata-account-and-what-to-do-if-it-fails
Step-by-step guide to activating your Operata account, with fixes for the most common activation errors including expired links and undelivered emails.
## Activating your account
When your admin adds you to Operata, you'll receive an activation email with the subject line **Hi \[your name] — you're invited to join your team on Operata!**
1. Open the email and click **Activate my account**.
2. You'll be taken to a page asking you to verify your email address. Click the confirmation link.
3. Set your password and log in at [app.operata.io](https://app.operata.io).
The activation link is valid for **7 days**. If you don't activate within that window, the link expires and you'll need a new one.
## Common problems and fixes
### I didn't receive the activation email
* Check your **spam or junk folder** — Operata invitation emails are sometimes filtered by enterprise mail gateways.
* Search for emails from [`no-reply@operata.com`](mailto:no-reply@operata.com) or with the subject *you're invited to join your team on Operata*.
* If your organisation uses Microsoft 365 or Google Workspace, ask your IT team to whitelist `operata.com` as a sending domain.
* Wait up to 10 minutes — some corporate mail systems delay external emails.
### I get an error when clicking the activation link
The most common error is *"Your email address could not be verified."* This usually means:
* **The link has expired** — activation links are valid for 7 days. If it's been longer, contact your Operata admin or message us in the chat widget to request a new invite.
* **The link was modified** — some email security tools rewrite URLs. Try copying and pasting the link directly into your browser instead of clicking it.
* **You're logged in to a different account** — open the link in an incognito/private window.
### I need a new activation link
* Ask your Operata admin to resend your invite from the **Teammates** section.
* Alternatively, use the chat widget on this page and we'll resend it for you.
### I activated but can't log in
* Go to [app.operata.io](https://app.operata.io) and click **Forgot password** to reset your credentials.
* If your organisation uses SSO, use your company login button rather than email and password.
* You may get an error, just select OK, but you will have access.
### I'm getting a blank screen after logging in
This usually means your account was created but you haven't been assigned to an Operata group yet. Contact your admin to confirm your group assignment, or reach out to Operata support.
# How to find my Operata Group ID
Source: https://docs.operata.com/docs/help/how-to-find-my-operata-group-id
Several integration processes need you to enter the Operata. Group ID - here's how to find it.
* Login to Operata and select the Group
* The Operata Group ID is the 32-character, alpha-numeric string after the [https://app.operata.io/](https://app.operata.io/) and before /dashboard?filter=.
In this example is is **a28453f9-c9d3-2c48-a7ed-84d9e67ab297**
# Jabra quick start
Source: https://docs.operata.com/docs/help/jabra-quick-start
The Engage range of Headsets can provide additional data to Operata for some unique insights, but there are some prerequisites.
Jabra is one of three audio vendors Operata reads — see [Agent headsets and AI audio tooling](/docs/integrations-headsets-and-audio-tooling) for the others.
To collect Jabra Engage headset statistics and call control here's what you need to do.
## Have compatible Jabra Headsets
* Models that currently support **headset statistics** capability are:
* *Jabra Engage 40*
* *Jabra Engage 50*
* *Jabra Engage 50 II*
* *Jabra Engage 55 (limited data)*
* *Jabra Engage 65 (limited data)*
* *Jabra Engage 75 (limited data)*
* For **Headset Call Control** capability enabled by the Operata agent collector Chrome/Edge extension (muting the Jabra Headset, mutes the softphone etc) lower levels of Jabra headsets are also supported.
* Jabra Evolve range
* *Jabra Engage 40*
* *Jabra Engage 50*
* *Jabra Engage 50 II*
* *Jabra Engage 55*
* *Jabra Engage 65*
* *Jabra Engage 75*
***
## Preparation
#### Stats Collection
* Both the **Jabra Chrome Host** and **Jabra Browser integration chrome extension** need to be installed on supported OS and Browsers (Chrome and Edge).
* Select the button below to see the latest details and software links from Jabra.
[Jabra stats software details](https://developer.jabra.com/sdks-and-tools/legacy#end-user-components-for-legacy-sdks)
* The firmware on your Jabra Headset may need to be updated to the latest version using the [Jabra Direct](https://www.jabra.com.au/software-and-services/jabra-direct) application.
* Jabra headset data collection needs to be enabled in Operata, just [contact Operata](mailto:help@operata.com) and we will do this.
#### Headset Controls
Jabra device call control for Amazon Connect based solutions **is already part** of the Operata Chrome and Edge extension - see details below.
[Amazon Connect headset control software details](https://developer.jabra.com/sdks-and-tools/amazonconnect)
***
## Testing
For testing you will need:
* Compatible Jabra Headset.
* Access to Operata.
A machine with access to the Agent Softphone that has:
* The Jabra Chrome Host and Jabra Browser integration chrome extension installed.
* The Operata Chrome extension installed (Chrome or Edge browsers)
* Chrome/Edge Headset mic settings to use the Jabra Headset.
* Machine Headset settings to use the Jabra Headset.
Once you have all this enabled, make and end a call, data should now appear in the Playbook - Jabra.
Here's the details...
[Jabra Dashboard](/docs/help/jabra)
# Krisp integration
Source: https://docs.operata.com/docs/help/krisp-integration
Operata reads the headset connected through Krisp, plus whether Krisp noise cancellation and accent conversion were active on the call.
Krisp sits between the agent's headset and softphone, filtering background noise and converting accents in real time.
Operata works with Krisp locally to see the physical headset behind Krisp's virtual device, plus whether noise cancellation or accent conversion were active on each call. In-call state is also captured, with changes updated in real time. When an agent reports an audio issue, you know whether Krisp's processing was involved.
## Before you start
* Operata Agent Collector browser extension v1.9.6 or later.
* Krisp Desktop v2.71.9 or later (Windows and macOS).
* The Krisp integration must be enabled at your account level by Krisp before Operata can collect any data. Contact your Krisp account manager or raise a Krisp support ticket requesting that they enable collection of Krisp output and processing information by Operata.
There is no browser version requirement. The integration connects directly to Krisp Desktop, not the browser.
## Verify
Open the **Headset Inventory** page in Operata. Each agent row shows the physical headset, whether Krisp is running, and which features were active.
**NC** means noise cancellation was on. **AC** means accent conversion was on.
## Updates
Krisp updates are delivered through the standard Krisp auto-update or manual update flow. No action required on your end.
## Troubleshooting
If Headset Inventory shows no Krisp data for an agent:
* Confirm the Agent Collector extension is v1.9.6 or later.
* Confirm Krisp Desktop is v2.71.9 or later.
* Confirm Krisp was running before the agent took the call, not started mid-call.
* Confirm the Krisp account-level integration has been enabled. If unsure, check with your Krisp account manager.
* If none of the above have resolved the issue, we are happy to help. Reach out to us at [support@operata.com](mailto:support@operata.com).
## Related
* [Agent headsets and AI audio tooling](/docs/integrations-headsets-and-audio-tooling)
* [Sanas integration](/docs/help/sanas-integration)
* [Headset logs](/docs/headset-logs)
# Why missed-call data varies with collector coverage
Source: https://docs.operata.com/docs/help/missedcallagent
What Operata records for a missed call changes depending on which agents run the Agent Collector and whether cloud collection is enabled. Here are all four combinations.
The data captured in Operata for MissedCallAgent events varies where not all agents have the Agent Collector installed, the details below show the data captured in each of the four possible scenarios - with and without cloud collection that adds contact record details from your platform.
***
### 1. Call to Agent 1 (MissedCallAgent) answered by Agent 2
#### Both agents have the Agent Collector
* *Browser data*: Agent 2 has the answered call details as expected.
* *Browser and cloud data:* Summary call record details both the agent who missed the call (Agent 1) and answered the call (Agent 2).
* Missed Call ID not found against MissedCallAgent for Agent 1 in Agent Interactions dashboard.
***
### 2. Call to Agent 1 (MissedCallAgent) answered by Agent 2
#### Only Agent 1 has the Agent Collector
* *Browser data*: Agent 1 has a zero length answered call - **this is misleading**.
* The Call Summary record has the correct details.
* *Browser and cloud data:* Summary call record is corrected with details of both the agent who missed the call (Agent 1) and answered the call (Agent 2).
***
### 3. Call to Agent 1 (MissedCallAgent) answered by Agent 2
#### Only Agent 2 has the Agent Collector
* *Browser data*: Agent 2 has the answered call details as expected.
* *Browser and cloud data:* Summary call record has no details on the agent who missed and answered the call - **this is misleading.**
***
### 4. Call to Agent 1 (MissedCallAgent) answered by Agent 2
#### Neither Agent has the Agent Collector
* *Browser data*: None collected
* *Browser and cloud data:* Summary call record has no details on the agent who missed and answered the call.
***
## Platform specifics
What `MissedCallAgent` and its neighboring states mean is platform-specific.
* [Amazon Connect: CCP (Contact Control Panel) error and agent state reference](/docs/help/amazon-connect-what-do-softphone-errors-mean) — what `MissedCallAgent` and the neighboring states mean on Amazon Connect.
## Related
* [Softphone issues](/docs/diagnose-softphone-issues) — where Operata surfaces softphone errors.
* [What cloud collection adds](/docs/cloud-collection-benefits) — why the cloud record fills these gaps.
* [CCP agent states](/docs/ccp-agent-states) — the stored field schema.
# Tenor for human agents — notifications
Source: https://docs.operata.com/docs/help/new-agent-notifications
There are some new notifications to help guide your day.
Tenor for human agents gives you some new notifications to help guide your day.
***
## Headset notification
**Why does this matter?**
Using a **headset** provides a better experience for both you and your customer
If you use internal microphone rather than a Headset, at the end of the call you will be prompted to plug-in your headset or switch to a headset in system settings.
The prompt may include a **Switch Devices** button giving you a dropdown to change your Microphone and Speaker device settings.
***
## Call ended on Hold
**Why does this matter?**
Callers may give up if placed on extended hold, or you may end the call.
You may need to call them back?
If you or the caller or you end the call while it has been on extended hold (more than 30 seconds) then you will be prompted.
***
## Call ended after a network issue
**Why does this matter?**
A network issue may have caused the call to end, you may need to call them back?
If you or the caller ends the call shortly after a network issue is detected then you will be prompted, with the option of logging the issue.
***
# Sanas integration
Source: https://docs.operata.com/docs/help/sanas-integration
Operata reads the headset connected behind the Sanas application, so device attribution survives the audio processing layer.
Sanas processes the agent's audio between the headset and the softphone. The integration lets Operata capture the headset connected behind it, so you keep device attribution on calls that run through Sanas.
## Before you start
* Operata Agent Collector browser extension v1.9.6 or later.
* Sanas software version 3.1.6.0.
* The Sanas application (Node.js) installed on the agent's operating system, Windows or macOS.
* Local socket connectivity enabled on the agent's machine.
Sanas needs local socket connectivity on the agent's machine. Raise this with your security team before you roll it out.
The minimum Chrome and Edge versions for this integration are being confirmed. Contact [support@operata.com](mailto:support@operata.com) for current requirements.
## Verify
Open the **Headset Inventory** page. With the integration working, each agent row shows the headset connected behind Sanas.
## Troubleshooting
If Headset Inventory shows no headset for a Sanas agent:
* Confirm the Agent Collector extension is v1.9.6 or later.
* Confirm the Sanas application is running and on version 3.1.6.0.
* Confirm endpoint security software isn't blocking local socket connectivity.
## Related
* [Agent headsets and AI audio tooling](/docs/integrations-headsets-and-audio-tooling) — the capability and the other vendors.
* [Krisp integration](/docs/help/krisp-integration) — noise cancellation and accent conversion state.
* [Headset logs](/docs/headset-logs) — the fields Operata stores.
# Enablement
Source: https://docs.operata.com/docs/help/service-enablement
The technical and operational stages of Operata enablement, progressed either during your trial or when you move to a paid Operata service.
The stages below detail these features with the information needed to progress approvals, delivery, and user training.
Some of these may have already been enabled as part of your Operata trial.
Steps that depend on your contact center platform live on their own pages — see [Platform-specific enablement](#platform-specific-enablement).
***
## Foundation
Ensuring the basic Operata features are in place.
### 1. Chrome and Edge browser extension deployment
The foundation of Operata observability, best deployed using a Group Policy.
* Chrome Web Store — [Operata Collector](https://chromewebstore.google.com/detail/operata-collector/efhlocglafmcfhkpojjbckpbonbfbgdb)
* MS Edge Add-ons — [Operata Collector](https://microsoftedge.microsoft.com/addons/detail/operata-collector/ghgkknhlginpepabafckbejbpfmdppjk)
Send agents a user guide on how to move to and use Tenor for human agents — [our version here](/docs/help/agent-copilot).
*For VDI customers, the Operata Collector may need to be deployed in more than one location.*
***
### 2. URL allowlisting
To access the Operata platform and ensure data is received, specific URLs need to be internet accessible.
* [URLs and protocols for Operata](/docs/help/which-urls-and-protocols-will-i-need-to-allow-so-i-can-use-operata)
***
### 3. CCaaS integration
Enablement takes minutes. Approvals sometimes take longer — we'll help here — but there are tangible benefits in bringing more contact center as a service (CCaaS) data into Operata.
Follow the enablement page for your platform:
* [Amazon Connect enablement](/docs/enablement-amazon-connect)
* [Genesys Cloud enablement](/docs/enablement-genesys)
* [NICE CXOne enablement](/docs/enablement-nice-cxone)
***
### 4. Operata user guides and support
* Questions
* Ensure your Operata service issue reporting process is understood — in-app, or at [https://operata.com/support](https://operata.com/support)
***
A good stage for Operata-hosted sessions with IT teams, to build depth of knowledge in using Operata.
***
## Stage 2
### 5. Non-production environment creation (DEV/SIT/UAT)
Creating non-production Operata environments lets you test more integrated features.
***
### 6. VPN bypass URL
Capture details of the underlying networks agents use to connect to the VPN, by making a simple change to the VPN client — add a bypass URL.
* [Agent VPN bypass URL](/docs/vpn-bypass)
***
### 7. Agent readiness test (additional cost)
Configure an **Agent Test** After Contact Work (ACW) state to let agents test their environment before your customers do. We have commercial bundles for its use.
* [Agent readiness test](/docs/help/agent-readiness-test)
***
### 8. SSO
Simplify access to the Operata platform as the number of users (Teammates) grows.
* [SSO enablement](/docs/guides-request-sso)
***
A good stage to have Operata-hosted sessions with Service Owner and Business Operations teams, to broaden the use of Operata.
***
### 9. Workflows
Automate actions using workflows, including Operata agent-reported issues creating tickets in your ITSM platform such as ServiceNow.
* [Workflows](/docs/help/workflow)
* [ServiceNow integration](/docs/help/servicenow-integration-to-operata-email-and-webhook)
***
### 10. API
Use Operata data in other systems by pulling data with our API.
* [Operata API](/docs/api-authentication)
***
## Stage 3
The grand finale — useful features for specific use cases.
### 11. Simulate (additional cost)
Generate calls at scale to assure the performance of your environment before your customers do.
* [Operata Simulate](/docs/help/videos/simulate)
***
### 12. Jabra headset integration
Integration between Jabra headsets and the Operata browser extension.
* [Jabra quick start](/docs/help/jabra-quick-start)
***
### 13. Operata availability
Configure the Operata service availability feed (RSS or email) from [https://trust.operata.com/](https://trust.operata.com/).
***
## Platform-specific enablement
Each platform has its own integration steps, approvals, and optional features. Work through the page for the platform you run:
CTR collection, conversational analytics, EventBridge, and Heartbeat.
OAuth client, EventBridge source, and redaction policy.
Tenant connection and Agent Collector tagging.
# Teammates
Source: https://docs.operata.com/docs/help/teammates
How to add, edit and delete users (Teammates) and what the Role types give access to.
Select **Team Manager** to add, edit, and delete users (Teammates) within the Group you are logged into, or to create and configure Teams (where enabled for your account).
### Adding Teammates
Select the **Teammates** tab and **Add Teammates** to add someone.
* Fill in the details, selecting the **Role:**
* **Group Admin** can create other Teammates and has full access.
* **Group User** can view but not create anything.
* **Group Viewer** can view only the dashboards and agents configured in Data Teams.
Then select **SAVE** to create the Teammate.
***
### **Teammates (users) Roles**
The features accessible at each level are in the table below.
| Feature | Group Admin | Group User | Group Viewer |
| - | - | - | - |
| View Legacy Dashboards | 🆗 | 🆗 | 🚫 |
| View Canvas Dashboards | 🆗 | 🆗 | 🚫 |
| View Specific Canvas Dashboards\* | 🆗 | 🆗 | 🆗 |
| Create Canvas Dashboards | 🆗 | 🆗 | 🚫 |
| Switch between Groups | 🆗 | 🆗 | 🆗 |
| View History | 🆗 | 🆗 | 🚫 |
| Create, edit and delete workflows | 🆗 | 🚫 | 🚫 |
| Create, edit, run and delete Simulate campaigns | 🆗 | 🚫 | 🚫 |
| Create, edit, run and delete Heartbeat tests | 🆗 | 🚫 | 🚫 |
| Configs - Change Softphone Configuration (including log levels) | 🆗 | 🚫 | 🚫 |
| Configs - Add/delete Simulate ‘whitelist’ numbers | 🆗 | 🚫 | 🚫 |
| Configs - Create/delete API Token | 🆗 | 🚫 | 🚫 |
| Add/Remove new Teammates (Group Admin or Group User) | 🆗 | 🚫 | 🚫 |
\* Needs the **[Data Teams](/docs/help/data-teams)** feature to be enabled, which limits views to specific dashboards with specific data.
***
## **Activate Account emails**
Once the account has been created, they receive an account activation email, then once confirmed, a second set-up password email from Operata ([help@operata.com](mailto:help@operata.com))***see***
### Account Activation
You will get the following confirmation
***
### Set your password email
The following email you receive will prompt you to set your password.
***Note:*** You need to **Set your password**, even when using Single Sign On (SSO)
Selecting **Set your password**, and launches the screen below.
Passwords need to be a minimum of **8-characters** in length, with at least three of the following four character types:
* Lower case letter
* Upper case letter
* Number
* Special Character
***
## 3. Now sign in using your email address and password.
If you are using SSO, you will not be prompted for a password.
# Operata Product Overview in < 3 minutes
Source: https://docs.operata.com/docs/help/videos/operata-product-overview-in-3-minutes
Here's a great way to get an overview of Operata and how we help businesses.
# The Operata 'Why' in < 90 seconds
Source: https://docs.operata.com/docs/help/videos/the-operata-why-in-90-seconds
Watch this video for a quick summary of Operata
# Which URLs and protocols will I need to allow so I can use Operata?
Source: https://docs.operata.com/docs/help/which-urls-and-protocols-will-i-need-to-allow-so-i-can-use-operata
What you need to allow Operata on your network
For Operata to work seamlessly on your network, we require the following URLs and ports to be allowed:
***
**Operata Platform**\
`https://app.operata.io`
`https://app-ap-southeast-2.operata.io https://app-us-east-2.operata.io`
`https://bi.operata.io`
`https://bi-ap-southeast-2.operata.io`
`https://bi-us-east-2.operata.io`
***
**Agent Notifications**
`https://push.operata.io`
`https://push-ap-southeast-2.operata.io`
**`IP addresses for https://push-ap-southeast-2.operata.io`**
\- `166.117.42.211`
\- `166.117.132.181`
`https://push-us-east-2.operata.io`
**`IP addresses for https://push-us-east-2.operata.io`**
\- `166.117.33.208`
\- `166.117.198.184`
***
**Operata Collector**
`https://api.operata.io`
`https://api-ap-southeast-2.operata.io`
**`IP addresses for https://api-ap-southeast-2.operata.io:`**
\- `166.117.66.217`
\- `99.83.254.130`
`https://api-us-east-2.operata.io`
**`IP addresses for https://api-us-east-2.operata.io:`**
\- `13.248.149.219`
\- `166.117.247.184`
`https://static.operata.io`
***
**Operata Collector - VPN bypass**
`https://agent-service.operata.io`
**`IP addresses for https://agent-service.operata.io:`**
\- `15.197.68.217`
\- `166.117.173.134`
***
Operata Chrome/Edge extension needs both HTTPS (TLS 1.2 and greater) and Secure WebSocket (WSS) protocols to the Operata Collector urls.
***
**Operata Authentication**\
`https://login.operata.io`
**Operata analytics**\
`https://analytics-cdn.operata.io`\
`https://analytics.operata.io`
***
**Feature toggling**
`https://clientsdk.launchdarkly.com`
`https://clientstream.launchdarkly.com`
`https://app.launchdarkly.com`
`https://events.launchdarkly.com`
***
BI admin (creating custom dashboards)
`bi-admin.operata.io`
`bi-admin-us-east-2.operata.io`
If you have any questions please contact [help@operata.com](mailto:help@operata.com) or get in touch with your friendly Operata representative.
# Workflow
Source: https://docs.operata.com/docs/help/workflow
Automate actions when MOS or network thresholds are breached, a Heartbeat test fails, a call ends, or an agent reports an issue — by email, webhook, EventBridge, or Slack.
Operata Workflows automate actions when MOS levels or network conditions have met a defined threshold, when a Heartbeat test finds an issue, when a call ends or even when Agents report an issue.
Send an email, push a WebHook, data to EventBridge data (including CCP logs) or even send a Slack message natively, whenever the threshold you have configured is reached or event happens.
## Workflow status
The first page lists the Workflows that have been created and gives options to change their **STATUS** to on/off, **Delete** or **Edit** them
## Creating Workflows
Selecting the **+CREATE WORKFLOW** starts the Workflow creation wizard.
## 1. Workflow Application
The first option is to choose what application will trigger the Workflow.
* The **CCaaS Platform** option takes events from the data network performance elements, the overall network performance MOS score, Agent Reported Issue or Heartbeat assurance test result.
* If you have **EventBridge** enabled then select **Contact Ended** to send data at the end of a call (where enabled)
* The **Jabra** option takes Jabra headsets performance statistics (where enabled)
Selecting **CCaaS Platform** and **NEXT** gives options on what event to trigger on.
## 2. Workflow Triggers
Choose what you want to trigger an event:
* MOS score
* Packet Loss
* Jitter
* RTT (Latency)
* If you have **Agent Issue** notification enabled, you can trigger events when agents report issues (see below for details)
* If you have **Heartbeat** enabled then you can trigger events if the tests find issues (see below for details)
* If you have **EventBridge** enabled then select **Contact Ended** to send data at the end of a call (see below for details)
* If you have **EventBridge** enabled then select **Agent Readiness Test** to send test data at the end of the call.
* If you have **EventBridge** enabled then select **CCP Logs** to send all collected CCP log data as it is collected by Operata.
then next to choose the **Action**
## 3. Workflow actions
This screen defines the action to take in the context of the **Trigger** selected.
* **Send Email**: does just that (see below for more details on the content of the email you can send.
* **Invoke WebHook:** used to event into a third party application, Operata uses uses basic authentication in Headers to secure WebHook messages.
* **Agent Notification:** Sends an alert to Tenor for human agents (not currently used)
* **Operata Test:** Launches the Agent Test sequence (not currently used)
* **Slack:** notifies to a nominated Slack channel
* **Agent Alert:** Sends an alert to Tenor for human agents
* **App Specific:** (not currently used)
* **Amazon EventBridge:** Send data to the EventBridge that has been created.
## 4. Configure
Now configure the Workflow thresholds and events that will trigger the Workflow
### Send Email
When you select **Send Email** as a notification a standard templated email is sent.
Simply set the threshold to generate the email and the email address.
The email sent contains summary details of the call that triggered the email event, with the Call ContactID to use within Operata to discover more.
### Invoke WebHook
This screen lets you set the level at which the event will trigger, the WebHook URL, Method, Headers and Body.
***Note:*** enter **#`{{.Records}}`** into the Body to see all the details for the call that triggered the event.
Add the details to match where the WebHook event will be sent.
### Slack Notification
When you select the Slack option, you will be prompted the enter the URL of your Slack workspace and channel.
## Agent Reported Issue
Three elements can be configured to trigger an Agent Reported issue workflow:
1. ***Category (this is optional, leave blank and any Cause will trigger the workflow)***
* Softphone would not work
* Poor sound quality
* Delay in the conversation
* Call disconnected
* Customer could not hear me
* Could not hear the customer
* Missed call, the Softphone did not ring
* Something else
**2. Severity (this is mandatory)**
* Terrible
* Difficult
* Minor
***3. Agent Comments*** *(this is optional, leave blank and any Scenario will trigger the workflow)*
Use this if you have instructed agents to 'Include an additional comment' specifically designed to create a ticket.
**Email Address** or **WebHook** details also need to be entered.
***Note:*** for WebHook notifications enter **#`{{.Records}}`** into the Body to see all the details for the call that triggered the event.
## Heartbeat Telephony
Three elements are needed to configure an Agent Reported issue workflow:
Status
* **Agent Error** - The target agent for the Heartbeat could not be found.
* **Call Failed** - The Virtual Customer call failed to be answered.
* **Call Not Accepted by Agent** - The Heartbeat test call could not be answered by the agent.
* **Poor Call Quality** - the Heartbeat test call was successful, but was of poor quality
**Email Address** or **WebHook** details also need to be entered.
***Note:*** enter **#`{{.Records}}`** into the Body to see all the details for the call that triggered the event.
### EventBridge
Details of how to configure and use EventBridge are here.
[EventBridge](/docs/concepts-eventbridge)
Events from Operata Workflows can push events to the configured EventBridge service:
* When a Contact ends.
* When a Heartbeat test is completed.
* When CCP logs are captured.
Typical Heartbeat test payload to EventBridge
```
{ "createdOn": "2022-01-24T22:17:31.417287Z", "heartbeatId": "2e4f8a78-1234-4a52-5678-c0fff3ced44d", "jobId": "1643062651416852388", "agentId": "andy", "agentType": "HUMAN_AGENT", "status": "Complete", "cxScore": 9, "axScore": 8, "networkScore": 10, "toNumber": "+61870712345", "description": "Toll Free test 1" }
```
## 5. Saving the workflow
Finally update the **Workflow Name** and **Tag** - then **NEXT** to move forward.
Your new Workflow appears in the **Workflow List**.
The example Workflow will send a WebHook whenever a call has an average MOS of less than 3.5.
## Event History
Selecting History then WORKFLOW ACTIONS brings up the list of workflow events that have been triggered.
# IAM policies
Source: https://docs.operata.com/docs/iam-policies
The AWS Identity and Access Management (IAM) roles and policies Operata's Amazon Connect integration requires — trust policies, attached policies, and the administrator policy for manual deployments outside AWS CloudFormation.
Operata's Amazon Connect integration uses two AWS Identity and Access Management (IAM) roles: the Amazon EventBridge Pipe execution role and the Lambda service role. The default AWS CloudFormation template creates and wires both. This page lists every trust policy, attached policy, and the administrator policy you need when deploying manually.
The default CloudFormation template creates and attaches every role
and policy on this page. Read it only if you need to audit, modify, or
deploy the integration manually outside CloudFormation.
## Roles
| Role | Trust principal | Attached policies | Purpose |
| - | - | - | - |
| EventBridge Pipe execution role | `pipes.amazonaws.com` | Kinesis source, Lambda invocation, API destination | Reads Contact Trace Records (CTRs) from Kinesis, invokes the redactor Lambda, sends events to the Operata API destination. |
| Lambda service role | `lambda.amazonaws.com` | `AWSLambdaBasicExecutionRole` (managed), Secrets Manager, EC2 ENI (VPC only), S3 (upsert only) | Runs the redactor Lambda, reads the Operata API token from Secrets Manager, and (optionally) reads agent data from S3. |
## EventBridge Pipe execution role
### Trust policy
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pipes.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "{AWS Account ID}",
"aws:SourceArn": "arn:aws:pipes:{AWS Region}:{AWS Account ID}:pipe/operataEventsPipe-{Instance Name}-amazonConnect"
}
}
}
]
}
```
### Kinesis source policy
Reads Contact Trace Records (CTRs) from the Amazon Connect Kinesis stream.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kinesis:DescribeStream",
"kinesis:DescribeStreamSummary",
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:ListShards",
"kinesis:ListStreams"
],
"Resource": "{CTR Kinesis Stream ARN}"
}
]
}
```
### Lambda invocation policy
Invokes the redactor Lambda for enrichment and redaction.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:InvokeFunctionUrl"
],
"Resource": "arn:aws:lambda:{AWS Region}:{AWS Account ID}:function:CloudCollectorV3Stack-cloudcollectorv3redactor*"
}
]
}
```
### API destination policy
Sends processed events to the Operata API destination. CloudFormation names the destination ARN `operataEndpointGroup-{Operata-Group-ID}`.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "events:InvokeApiDestination",
"Resource": "{API Destination ARN}"
}
]
}
```
## Lambda service role
### Trust policy
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
```
### Managed policy
Attach the AWS managed policy `AWSLambdaBasicExecutionRole`. It grants the Lambda permission to write to CloudWatch Logs.
### Secrets Manager access policy
Reads the Operata API token from Secrets Manager. The secret name
follows the pattern `cloud-collector-v3/ctr/{Operata Group ID}/apiToken`.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:{AWS Region}:{AWS Account ID}:secret:cloud-collector-v3/ctr/{Operata Group ID}/apiToken-*"
}
]
}
```
### EC2 network interface policy
Required only when the Lambda runs in a VPC. Lets it create and manage
the network interfaces in the deployment subnets.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AttachNetworkInterface",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces"
],
"Resource": "*"
}
]
}
```
### S3 access policy
Required only when CTR upsert is enabled. Lets the Lambda read agent
data files from your S3 bucket.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::{Agent Data Bucket Name}/*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::{Agent Data Bucket Name}"
}
]
}
```
## Administrator deployment policy
For manual installs outside CloudFormation, attach the following policy to your deploying principal. It covers the minimum permissions to create every resource the integration uses.
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IAMRoleAndPolicyManagement",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:CreatePolicy",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:GetRole",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"iam:PassRole",
"iam:TagRole",
"iam:UpdateAssumeRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/CloudCollectorV3Stack-*",
"arn:aws:iam::*:role/operataEventBridgePipeRole*",
"arn:aws:iam::*:policy/*-Operata-GroupId-*",
"arn:aws:iam::*:policy/cloudcollectorv3*",
"arn:aws:iam::*:policy/AgentDataS3Access"
]
},
{
"Sid": "SecretsManagerManagement",
"Effect": "Allow",
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:PutSecretValue",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:TagResource"
],
"Resource": "arn:aws:secretsmanager:*:*:secret:cloud-collector-v3/ctr/*/apiToken-*"
},
{
"Sid": "EventBridgeManagement",
"Effect": "Allow",
"Action": [
"events:CreateConnection",
"events:CreateApiDestination",
"events:UpdateConnection",
"events:UpdateApiDestination",
"events:DescribeConnection",
"events:DescribeApiDestination",
"events:ListConnections",
"events:ListApiDestinations",
"events:TagResource"
],
"Resource": [
"arn:aws:events:*:*:connection/operataAPIgroup-*",
"arn:aws:events:*:*:destination/operataEndpointGroup-*"
]
},
{
"Sid": "EventBridgePipeManagement",
"Effect": "Allow",
"Action": [
"pipes:CreatePipe",
"pipes:UpdatePipe",
"pipes:StartPipe",
"pipes:StopPipe",
"pipes:DescribePipe",
"pipes:ListPipes",
"pipes:TagResource"
],
"Resource": "arn:aws:pipes:*:*:pipe/operataEventsPipe-*"
},
{
"Sid": "LambdaFunctionManagement",
"Effect": "Allow",
"Action": [
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:UpdateFunctionConfiguration",
"lambda:GetFunction",
"lambda:GetFunctionConfiguration",
"lambda:AddPermission",
"lambda:RemovePermission",
"lambda:TagResource",
"lambda:ListVersionsByFunction"
],
"Resource": "arn:aws:lambda:*:*:function:CloudCollectorV3Stack-cloudcollectorv3redactor*"
},
{
"Sid": "LambdaS3CodeAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::*-operata-shared-assets-prod/redactor-*.zip"
},
{
"Sid": "KinesisReadAccess",
"Effect": "Allow",
"Action": [
"kinesis:DescribeStream",
"kinesis:ListStreams"
],
"Resource": "*"
},
{
"Sid": "CloudFormationAccess",
"Effect": "Allow",
"Action": [
"cloudformation:DescribeStacks",
"cloudformation:ListStacks"
],
"Resource": "*"
}
]
}
```
## Manual deployment order
For manual installs, create resources in this order. Each step assumes you have attached the administrator policy above to your deploying principal.
1. Create the Secrets Manager secret
`cloud-collector-v3/ctr/{Operata Group ID}/apiToken` with your
Operata API token as the value.
2. Create the Lambda service role with the `lambda.amazonaws.com`
trust policy. Attach `AWSLambdaBasicExecutionRole`, the Secrets
Manager policy, the EC2 ENI policy (VPC only), and the S3 policy
(upsert only).
3. Create the EventBridge Pipe execution role with the
`pipes.amazonaws.com` trust policy. Attach the Kinesis source,
Lambda invocation, and API destination policies.
4. Deploy the redactor Lambda. Name pattern
`CloudCollectorV3Stack-cloudcollectorv3redactor-{unique-id}`,
runtime `provided.al2`, handler `bootstrap`, timeout 60 seconds.
5. Create the EventBridge connection
`operataAPIgroup-{Operata Group ID}` with `API_KEY` authentication
and header `Operata-API-Key`.
6. Create the EventBridge API destination
`operataEndpointGroup-{Operata Group ID}`. Endpoint
`https://api.operata.io/v2/aws/events/contact-record`, method `POST`.
7. Create the EventBridge Pipe
`operataEventsPipe-{Instance Name}-amazonConnect`. Source: the
Kinesis CTR stream. Enrichment: the redactor Lambda. Target: the
API destination. Filter: `{ "data": { "Channel": ["VOICE"] } }`.
Verify the pipe status is `RUNNING` and watch CloudWatch Logs for the
Lambda function. Place a test contact through Amazon Connect and
follow [Verify the integration](/docs/ctr-installation#verify) on the
installation guide.
## Common deployment errors
| Error | When | Recover |
| - | - | - |
| `AccessDenied` on `iam:PassRole` | Deploying principal can't pass the EventBridge Pipe or Lambda roles. | Attach `iam:PassRole` for both role ARNs to the deploying principal. |
| `InvalidParameterException` on `pipes:CreatePipe` | The Kinesis stream ARN is malformed or in another region. | Verify the ARN matches the region you're deploying to. |
| `ResourceNotFoundException` | A dependency was created out of order. | Re-run in the order in [Manual deployment order](#manual-deployment-order). |
| Lambda connection timeout | Lambda is in a VPC without route to Secrets Manager or the Operata API. | Add a VPC endpoint for Secrets Manager, or move the Lambda to a subnet with NAT egress. |
## Related
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the data path these roles serve.
* [Install CTR collection](/docs/ctr-installation) — the default CloudFormation deploy.
* [KMS encryption](/docs/kms-encryption) — adds CMK access to the EventBridge Pipe role.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — covers Secrets Manager rotation and connection failures.
# Insights
Source: https://docs.operata.com/docs/insights
The insights fields Operata attaches to each Amazon Connect Contact record — including detection type, severity, measured value, and timestamp for every insight raised on the contact.
The `insights` object lists every insight Operata raised for one Amazon Connect Contact. Each entry maps to a named detection in the [insights catalog](/docs/insights-catalog); see [Insights](/docs/concepts-insights) for the underlying concept.
## Schema
```json theme={null}
"insights": {
"count": 2,
"tags": [
{
"id": "ins_01HXYZ8K3M7Q4R2P6T9V0W",
"type": "high_agent_connection_time",
"description": "Very High Agent connection time",
"severity": "Severe",
"value": 14.2,
"unit": "seconds",
"contactId": "b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340",
"detectedAt": "2026-05-18T10:14:43Z"
},
{
"id": "ins_01HXYZ8K3M7Q4R2P6T9V0X",
"type": "high_rtt",
"description": "High RTT",
"severity": "Minor",
"value": 280,
"unit": "milliseconds",
"contactId": "b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340",
"detectedAt": "2026-05-18T10:15:02Z"
}
]
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `count` | integer | yes | Number of insights raised on this Contact. | `2` |
| `tags` | object\[] | yes | Insights raised on this Contact. Empty array when no insights were raised. | — |
| `tags[].id` | string | yes | Unique insight ID. Stable across queries; safe to use as a primary key. | `ins_01HXYZ8K3M7Q4R2P6T9V0W` |
| `tags[].type` | string | yes | Insight type, matching an entry in the [insights catalog](/docs/insights-catalog). | `high_agent_connection_time` |
| `tags[].description` | string | yes | Human-readable description of the insight. | `Very High Agent connection time` |
| `tags[].severity` | string | yes | Severity level. One of `Minor`, `Severe`, `Terminal`. | `Severe` |
| `tags[].value` | number | no | Measured value that triggered the insight. Absent for insights that don't carry a numeric measurement. | `14.2` |
| `tags[].unit` | string | no | Unit of measurement for `value`. Common values: `seconds`, `milliseconds`, `percent`, `count`. | `seconds` |
| `tags[].contactId` | string (UUID) | yes | Amazon Connect Contact ID this insight applies to. | `b0c9d4d1-aaaa-bbbb-cccc-ee75d4240340` |
| `tags[].detectedAt` | string (ISO 8601) | yes | When Operata raised the insight. UTC. | `2026-05-18T10:14:43Z` |
# Insights catalog
Source: https://docs.operata.com/docs/insights-catalog
Every detection Operata runs over contact observations — names, categories, severities, pattern types, and thresholds.
The insights catalog lists every detection Operata runs over the observations on a contact. Each entry names the insight, what it measures, the severity levels it can raise, and the thresholds the detection rule uses.
## Severity levels
Operata raises insights at one of three severity levels, based on the impact and duration of the detected condition:
* **Minor (Warn)** — issues that cause slight degradation, typically brief or low-impact.
* **Severe (Critical)** — issues that significantly impact call quality or customer experience.
* **Terminal** — issues that result in call termination or complete communication failure.
## Pattern types
Many detections classify how the condition presents during a Contact:
* **Spike** — a sudden, short burst of the condition (under 2 seconds).
* **Sustained** — continuous presence of the condition over 3 or more seconds.
* **Degraded** — fluctuating levels that rise and fall over the Contact.
## Quick reference
### Network
| Insight | Impact | Severity Levels |
| - | - | - |
| High Inbound Packet Loss | Customer audio drops out or becomes unclear | Minor, Severe |
| High Outbound Packet Loss | Agent audio becomes choppy for customer | Minor, Severe |
| Zero Inbound Packets | Agent cannot hear customer | Minor, Severe, Terminal |
| Zero Outbound Packets | Customer cannot hear agent | Minor, Severe, Terminal |
| High Inbound Jitter | Customer audio becomes distorted for agent | Minor, Severe |
| High Outbound Jitter | Agent audio becomes choppy for customer | Minor, Severe |
| High Round Trip Time | Noticeable delay in conversation | Minor, Severe |
| Low Inbound MOS | Poor audio quality from customer | Minor, Severe |
| Low Outbound MOS | Poor audio quality to customer | Minor, Severe |
### Device
| Insight | Impact | Severity Levels |
| - | - | - |
| High CPU Utilization | Application and audio performance issues | Minor, Severe |
| Media Delivered to VDI | Potential audio quality degradation | Severe |
### Browser
| Insight | Impact | Severity Levels |
| - | - | - |
| Legacy Browser Use | Reduced performance and security risks | Minor, Severe |
### Audio device
| Insight | Impact | Severity Levels |
| - | - | - |
| Internal Microphone | Suboptimal audio capture quality | Minor |
| Mixed Audio Devices | Potential audio routing issues | Minor |
| Microphone Changed | Disruption to audio continuity | Minor, Severe |
| Virtual Audio Device | Altered audio processing | Minor |
### Agent interaction
| Insight | Impact | Severity Levels |
| - | - | - |
| Large amount of Hold | Excessive customer wait time | Minor, Severe |
| Large amount of Mute | Reduced interaction quality | Minor, Severe |
| Call Ended on Hold | Poor customer experience | Minor, Severe |
| Call Ended on Mute | Communication breakdown | Minor, Severe |
### Audio
| Insight | Impact | Severity Levels |
| - | - | - |
| Low Customer Audio | Difficulty hearing customer | Minor, Severe |
| Low Agent Audio | Difficulty hearing agent | Minor, Severe |
| High Customer Background Noise | Customer audio clarity reduced | Minor, Severe |
| High Agent Background Noise | Agent audio clarity reduced | Minor, Severe |
| Large amount of Silence | Potential engagement issues | Minor, Severe |
***
## Network insights
Network insights detect connectivity and data transmission problems that degrade real-time voice quality.
### High Inbound Packet Loss
**Definition**: Loss of data packets sent from the customer to the agent, causing degraded audio or missing speech during a call.
**Impact**: Customer audio drops out or becomes unclear, disrupting conversation flow and potentially causing frustration. The agent needs to ask customers to repeat themselves.
**Pattern types**:
* **Spike**: A sudden, short burst of high inbound packet loss
* **Sustained**: Continuous high inbound packet loss over a period of time
* **Degraded**: Fluctuating inbound packet loss that rises and falls over a period of time
**Detection thresholds**:
* Minor severity: Greater than 5% packet loss for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 5% for 3+ seconds
* Severe severity: Greater than 10% packet loss for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 10% for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### High Outbound Packet Loss
**Definition**: Loss of data packets sent from the agent to the customer, causing degraded audio or missing speech during a call.
**Impact**: Agent audio becomes choppy or drops out for the customer, reducing communication effectiveness and potentially damaging the customer experience.
**Pattern types**:
* **Spike**: A sudden, short burst of high outbound packet loss
* **Sustained**: Continuous high outbound packet loss over a period of time
* **Degraded**: Fluctuating outbound packet loss that rises and falls over a period of time
**Detection thresholds**:
* Minor severity: Greater than 5% packet loss for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 5% for 3+ seconds
* Severe severity: Greater than 10% packet loss for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 10% for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### Zero Inbound Packets
**Definition**: No data packets are received from the customer to the agent, indicating a complete loss of inbound audio.
**Impact**: Agent cannot hear the customer at all, leading to miscommunication, repeated phrases, or forced call termination.
**Pattern types**:
* **Spike**: A short period with zero inbound packets
* **Sustained**: A continuous period with zero inbound packets
* **Terminal**: The call ends while zero inbound packets are being received, regardless of duration
**Detection thresholds**:
* Minor severity (Spike): Any single second with zero packets
* Severe severity (Sustained): 5 or more consecutive seconds with zero packets
* Terminal severity: Call ended while experiencing zero inbound packets
***
### Zero Outbound Packets
**Definition**: No data packets are sent from the agent to the customer, indicating a complete loss of outbound audio.
**Impact**: Customer cannot hear the agent, breaking communication and damaging call continuity.
**Pattern types**:
* **Spike**: A short period with zero outbound packets
* **Sustained**: A continuous period with zero outbound packets
* **Terminal**: The call ends while zero outbound packets are being sent, regardless of duration
**Detection thresholds**:
* Minor severity (Spike): Any single second with zero packets
* Severe severity (Sustained): 5 or more consecutive seconds with zero packets
* Terminal severity: Call ended while experiencing zero outbound packets
***
### High Inbound Jitter
**Definition**: Variation in the timing of packets received from the customer to the agent, causing uneven or distorted audio.
**Impact**: Customer audio becomes unclear or drops out, disrupting conversation flow and potentially frustrating the agent. Agent needs to be alerted in real time.
**Pattern types**:
* **Spike**: A short, sudden increase in inbound jitter
* **Sustained**: A continuous period of elevated inbound jitter
* **Degraded**: Fluctuating inbound jitter levels over time
**Detection thresholds**:
* Minor severity: Greater than 15ms jitter for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 15ms for 3+ seconds
* Severe severity: Greater than 30ms jitter for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 30ms for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### High Outbound Jitter
**Definition**: Variation in the timing of packets sent from the agent to the customer, causing uneven or distorted audio.
**Impact**: Customer hears choppy or distorted agent audio, reducing clarity and comprehension.
**Pattern types**:
* **Spike**: A short, sudden increase in outbound jitter
* **Sustained**: A continuous period of elevated outbound jitter
* **Degraded**: Fluctuating outbound jitter levels over time
**Detection thresholds**:
* Minor severity: Greater than 15ms jitter for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 15ms for 3+ seconds
* Severe severity: Greater than 30ms jitter for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 30ms for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### High Round Trip Time
**Definition**: Delay in data transmission between agent and customer, affecting real-time communication flow.
**Impact**: Customer and agent experience noticeable audio delay, causing conversation overlap or awkward pauses.
**Pattern types**:
* **Spike**: A short, sudden increase in round trip time
* **Sustained**: A continuous period of elevated round trip time
* **Degraded**: Fluctuating round trip time levels over time
**Detection thresholds**:
* Minor severity: Greater than 350ms RTT for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 350ms for 3+ seconds
* Severe severity: Greater than 500ms RTT for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 500ms for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### Low Inbound Mean Opinion Score (MOS)
**Definition**: The Mean Opinion Score (MOS) reflects voice quality based on network performance from customer to agent. Low MOS indicates degraded audio quality.
**Impact**: Agent hears poor or distorted audio from the customer, making communication difficult and potentially requiring repeated questions.
**Pattern types**:
* **Spike**: A short, sudden drop in MOS value
* **Sustained**: A continuous period of low MOS value
* **Degraded**: Fluctuating low MOS values over time
**Detection thresholds**:
* Minor severity: MOS value of 3.6 or lower detected in the worst 2%, 10%, or 33% of the call
* Severe severity: MOS value of 3.0 or lower detected in the worst 2%, 10%, or 33% of the call
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends. MOS is measured on a scale of 1-5, with 5 being excellent quality.
***
### Low Outbound Mean Opinion Score (MOS)
**Definition**: The Mean Opinion Score (MOS) reflects voice quality based on network performance from agent to customer. Low MOS indicates degraded audio quality.
**Impact**: Customer hears poor or distorted audio from the agent, reducing overall call quality and potentially impacting customer satisfaction.
**Pattern types**:
* **Spike**: A short, sudden drop in MOS value
* **Sustained**: A continuous period of low MOS value
* **Degraded**: Fluctuating low MOS values over time
**Detection thresholds**:
* Minor severity: MOS value of 3.6 or lower detected in the worst 2%, 10%, or 33% of the call
* Severe severity: MOS value of 3.0 or lower detected in the worst 2%, 10%, or 33% of the call
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends. MOS is measured on a scale of 1-5, with 5 being excellent quality.
***
## Device insights
Device insights detect hardware performance problems on the agent's machine that affect application responsiveness and audio output.
### High CPU Utilization
**Definition**: Excessive processing load on the agent's device during a call.
**Impact**: Affects application and audio performance. Customer may hear audio glitches or delays caused by the agent's device performance issues. Agent may experience application lag or freezing.
**Pattern types**:
* **Spike**: A short, sudden increase in CPU utilization
* **Sustained**: A continuous period of high CPU utilization
* **Degraded**: Fluctuating CPU utilization levels over time
**Detection thresholds**:
* Minor severity: Greater than 90% CPU utilization for less than 2 seconds, OR 2+ spikes over 10 seconds, OR sustained above 90% for 3+ seconds
* Severe severity: Greater than 98% CPU utilization for less than 2 seconds, OR 4+ spikes over 10 seconds, OR sustained above 98% for 3+ seconds
**Notes**: Detection excludes the first 5 seconds of the call, periods of hold, and the first 5 seconds after hold ends.
***
### Media Delivered to VDI
**Definition**: Call media (voice) has been delivered to a Virtual Desktop Infrastructure (VDI) environment before being routed to the agent.
**Impact**: VDI environments can introduce additional latency and audio processing overhead, potentially degrading call quality.
**Detection thresholds**:
* Severe severity: Detected when media is delivered to a VDI environment
***
## Browser insights
Browser insights flag web browser versions that are outdated enough to affect performance or security.
### Legacy Browser Use
**Definition**: Use of a web browser version that is significantly outdated compared to the latest available version.
**Impact**: Legacy browsers may have reduced performance, security vulnerabilities, and compatibility issues with modern web applications.
**Detection thresholds**:
* Minor severity: Browser is more than 2 versions behind the latest release
* Severe severity: Browser is more than 10 versions behind the latest release
***
## Audio device insights
Audio device insights detect microphone and speaker configuration problems that reduce call audio quality.
### Internal Microphone
**Definition**: Use of a computer's built-in internal microphone rather than an external or headset microphone.
**Impact**: Internal microphones typically provide lower audio quality, pick up more background noise, and may be positioned suboptimally for voice capture.
**Detection thresholds**:
* Minor severity: Internal microphone detected
***
### Mixed Audio Devices
**Definition**: Use of different devices for microphone input and speaker output during the interaction (e.g., headset microphone with laptop speakers).
**Impact**: Mixed audio device configurations can lead to audio feedback, echo issues, and inconsistent audio quality.
**Detection thresholds**:
* Minor severity: Different microphone and speaker devices detected
***
### Microphone Changed
**Definition**: The agent's microphone device changed during the interaction.
**Impact**: Changing microphones mid-call can cause audio disruption, quality changes, and potential communication gaps.
**Detection thresholds**:
* Minor severity: Microphone changed to the same underlying device (e.g., different software interface to same hardware)
* Severe severity: Microphone changed to a completely different physical device
***
### Virtual Audio Device
**Definition**: Use of a virtual audio device that processes or modifies audio (e.g., Krisp, Sanas, or other noise cancellation/voice enhancement software).
**Impact**: Virtual audio devices can introduce processing latency and may alter audio characteristics in unexpected ways.
**Detection thresholds**:
* Minor severity: Virtual audio device detected
***
## Agent interaction insights
Agent interaction insights detect patterns in how agents use call controls — hold and mute — that affect contact duration and customer satisfaction.
### Large amount of Hold
**Definition**: Excessive use of the hold function during the call, keeping the customer waiting for extended periods.
**Impact**: Long hold times frustrate customers and extend call duration, negatively impacting customer satisfaction and operational efficiency.
**Detection thresholds**:
* Minor severity: Greater than 25% of call duration in hold state AND total hold time exceeds 30 seconds
* Severe severity: Greater than 50% of call duration in hold state AND total hold time exceeds 60 seconds
***
### Large amount of Mute
**Definition**: Excessive use of the mute function during the call, preventing the customer from hearing the agent.
**Impact**: Extended mute periods can create customer confusion and reduce interaction quality, as customers are unsure if the agent is still present or working on their issue.
**Detection thresholds**:
* Minor severity: Greater than 25% of call duration in mute state AND total mute time exceeds 30 seconds
* Severe severity: Greater than 50% of call duration in mute state AND total mute time exceeds 60 seconds
***
### Call Ended on Hold
**Definition**: The call ended while the customer was on hold for an extended period.
**Impact**: Ending a call while the customer is on hold creates a poor customer experience and may indicate an agent or system issue.
**Detection thresholds**:
* Minor severity: Call ended after 30+ seconds of hold
* Severe severity: Call ended after 120+ seconds (2 minutes) of hold
***
### Call Ended on Mute
**Definition**: The call ended while the agent's microphone was muted for an extended period.
**Impact**: Ending a call while muted may indicate communication breakdown or technical issues, creating a confusing experience for the customer.
**Detection thresholds**:
* Minor severity: Call ended after 30+ seconds of mute
* Severe severity: Call ended after 120+ seconds (2 minutes) of mute
***
## Audio insights
Audio insights detect problems with speech volume, background noise, and silence that affect how clearly each party hears the other.
### Low Customer Audio
**Definition**: Customer audio levels are unusually low, making it difficult for the agent to hear the customer.
**Impact**: Agent may struggle to understand the customer, requiring frequent requests for repetition and extending call duration.
**Detection thresholds**:
* Minor severity: Average audio energy of 3,000 or lower during customer speech periods (10+ seconds minimum)
* Severe severity: Average audio energy of 2,000 or lower during customer speech periods (10+ seconds minimum)
**Notes**: This insight is based on audio energy delivered to the softphone, independent of the agent's device volume settings. Detection requires at least 10 seconds of customer audio.
***
### Low Agent Audio
**Definition**: Agent audio levels are unusually low, making it difficult for the customer to hear the agent.
**Impact**: Customer may struggle to understand the agent, leading to miscommunication and frustration.
**Detection thresholds**:
* Minor severity: Average audio energy of 3,000 or lower during agent speech periods (10+ seconds minimum)
* Severe severity: Average audio energy of 2,000 or lower during agent speech periods (10+ seconds minimum)
**Notes**: This insight is based on audio energy sent from the softphone, independent of the customer's device volume settings. Detection requires at least 10 seconds of agent audio.
***
### High Customer Background Noise
**Definition**: High levels of background noise detected in the customer's audio when the customer is not speaking.
**Impact**: Background noise can make it difficult to hear the customer when they do speak and may indicate a poor calling environment.
**Detection thresholds**:
* Minor severity: Average background audio energy of 200 or higher when customer is not speaking (10+ seconds minimum)
* Severe severity: Average background audio energy of 400 or higher when customer is not speaking (10+ seconds minimum)
**Notes**: This insight is based on audio energy during periods when the customer is not talking. Detection requires at least 10 seconds of customer background noise.
***
### High Agent Background Noise
**Definition**: High levels of background noise detected in the agent's audio when the agent is not speaking.
**Impact**: Background noise from the agent's environment can distract the customer and appear unprofessional, potentially affecting customer satisfaction.
**Detection thresholds**:
* Minor severity: Average background audio energy of 200 or higher when agent is not speaking (10+ seconds minimum)
* Severe severity: Average background audio energy of 400 or higher when agent is not speaking (10+ seconds minimum)
**Notes**: This insight is based on audio energy during periods when the agent is not talking. Detection requires at least 10 seconds of agent background noise.
***
### Large amount of Silence
**Definition**: Excessive periods of silence during the call where neither the agent nor customer is speaking.
**Impact**: Long silence periods may indicate poor engagement, technical issues, or inefficient call handling, potentially frustrating customers.
**Detection thresholds**:
* Minor severity: Greater than 35% of call duration in silence state AND total silence time exceeds 45 seconds
* Severe severity: Greater than 60% of call duration in silence state AND total silence time exceeds 90 seconds
**Notes**: Silence is defined as periods where both parties have audio energy below 1,500.
***
## Related
* [Insights overview](/docs/insights-overview) — how insights relate to signals, observations, and contacts.
* [Data summary and frequency](/docs/resources-data-collection-frequency) — what Operata collects and how often.
* [WebRTC session](/docs/webrtc-session) — the per-second metrics most network insights run against.
* [Operata API — Getting started](/docs/api-getting-started) — query insights via the API.
# Insights overview
Source: https://docs.operata.com/docs/insights-overview
An insight is a named detection Operata derives from the observations on a contact — a known pattern, surfaced once per contact it matches.
An insight is a named detection Operata derives from the observations on a contact — a known pattern, surfaced once per contact it applies to.
## How it works
An insight has four parts: a **name** (for example, `audio_one_way`), a **category** (audio, network, agent, contact), a **severity** (minor, severe, terminal), and a **detection rule** that runs over the contact's observations. When the rule matches, Operata writes one insight record against the contact.
Insights are derived, not collected. The [Agent Collector](/docs/collector-overview) and [cloud collection](/docs/concepts-cloud-collection) emit signals; Operata persists them as observations on a contact; the insight engine then reads those observations and writes insights. Late-arriving signals can change which insights apply — a contact that looks clean on first read may gain an insight once its Contact Trace Record (CTR) or conversational analytics record lands.
Insights are bounded to one contact. Cross-contact analysis happens at the journey level, where [Customer Journey Trace](/docs/concepts-customer-journey-trace) aggregates insights across the contacts that share a journey. The full list of detections Operata runs lives in the [Insights catalog](/docs/insights-catalog) — names, categories, severities, and the conditions each rule matches.
## Why insights are separate from observations
Raw observations answer "what happened?" Insights answer "what should I care about?" The split keeps the data layer general — every observation stays queryable — while letting Operata ship pattern detection without forcing every API consumer to reimplement it. New detections appear in the catalog over time; the observation shapes do not change when they do.
Bounding each insight to one contact keeps them composable. Joins, journey rollups, and webhook events all assume one insight maps to one contact, which keeps the dashboard and Amazon EventBridge contracts predictable.
## Related
* [Insights — concept](/docs/concepts-insights) — the deeper model behind the detection engine.
* [Signals and observations](/docs/concepts-signals-and-observations) — the underlying data the insight engine reads.
* [Contacts and interactions](/docs/concepts-contacts-and-interactions) — the record an insight attaches to.
* [Insights catalog](/docs/insights-catalog) — every detection Operata ships today.
* [List contact summaries](/docs/api-contact-summary) — each summary row carries the count and severity of insights raised for the contact.
* [Get complete contact record](/docs/api-contact-record) — exposes the full insight list for one contact, with contributing observations.
* [Webhooks events](/docs/api-webhooks-events) — fires per-insight events as insights land, including late ones that follow a CTR.
* [Insights — Data reference](/docs/insights) — the field shape of the `insights` object returned on contact records.
# Connect Amazon Connect to Operata
Source: https://docs.operata.com/docs/integrations-amazon-connect-overview
Stream Contact Trace Records and related Amazon Connect data into Operata using the Cloud Collector.
Connect Amazon Connect to Operata and every contact's Contact Trace Record (CTR), conversation transcript, IVR flow path, and Lex intent lands in one place — ready for the insight engine and your team.
## How it works
Operata reads Amazon Connect data through the Cloud Collector: a set of CloudFormation stacks you deploy in your own AWS account. The stacks attach to the data sources you choose, read records via Kinesis, and forward them to Operata over an Amazon EventBridge Pipe and API destination. Your data never leaves your AWS account boundary until it reaches the Operata ingestion endpoint.
The CTR collection stack is the foundation. The others extend it.
| Stack | Data source | Use when |
| - | - | - |
| CTR collection | Contact Trace Records | You want core contact metadata. Required for the journey trace. |
| [Conversational analytics](/docs/conversational-analytics) | Conversational analytics | You want sentiment and conversation analytics. |
| [Contact Flow Logs](/docs/contact-flow-logs) | Contact Flow Logs | You want IVR path and block-level visibility. |
| [Amazon Lex](/docs/lex-integration) | Amazon Lex V2 | You want bot intent and fulfilment data. |
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role.
* An AWS account with permission to deploy CloudFormation in the region hosting your Amazon Connect instance. See [IAM policies](/docs/iam-policies).
* Your Amazon Connect instance Kinesis CTR stream ARN. Firehose-only setups need a Kinesis stream in front of the Firehose; see [Why Kinesis Streams, not Firehose](/docs/concepts-why-kinesis-streams).
* Familiarity with the [Cloud Collector](/docs/concepts-cloud-collector) data path (Kinesis → EventBridge Pipe → Lambda → API destination).
## Steps
1. **Send Operata the three install details.** Operata builds you a custom CloudFormation template once you provide: the CTR Kinesis stream ARN, the Amazon Connect instance alias (32 characters or fewer), and whether to enable redaction (if yes, the VPC ID and private subnet IDs). Operata responds with a quick-create CloudFormation link and your Operata Group ID.
2. **[Install the CTR collection stack](/docs/ctr-installation)** — deploy the core stack that creates the Kinesis source binding, the EventBridge Pipe, the redactor Lambda (if enabled), and the API destination that delivers events to Operata.
3. **Verify the integration** — place a test call through your Amazon Connect CCP, end the contact cleanly, then check the Operata console. The CTR appears under **Get the Details** within five minutes.
## Verify
Place a test call through your Amazon Connect CCP and end the contact cleanly. In the Operata console, open **Get the Details** and filter to the last 10 minutes. Your test contact appears with a matching `contactId`, and the `traceRecord` field contains the full CTR payload.
## Optional add-ons
Once CTRs flow, extend the integration with any of these stacks — each runs independently and does not affect the core pipe:
* [Install conversational analytics collection](/docs/conversational-analytics-installation) — sentiment scores, agent and customer turn data, category matches.
* [Install Contact Flow Logs collection](/docs/contact-flow-logs) — block-level visibility into your contact flows.
* [Install the Amazon Lex integration](/docs/lex-integration) — bot intent and fulfilment data alongside the CTR.
* [Grant KMS access](/docs/kms-encryption) — if your Kinesis stream is KMS-encrypted, grant the EventBridge Pipe role access to the key.
* [Tag the AWS resources](/docs/aws-tagging) — apply your organization's resource tags to the Cloud Collector stacks.
* [Install the Cloud Orchestrator](/docs/orchestrator-installation) — enables Heartbeat and Virtual Agent.
* [Set up Heartbeat](/docs/heartbeat-setup) — synthetic checks that call into your contact center on a schedule and measure availability and audio quality.
* [Deploy the Virtual Agent](/docs/virtual-agent) — automated bot calls that exercise your IVR paths and Lex bots end-to-end.
## Troubleshooting
See [Troubleshoot the AWS integration](/docs/aws-troubleshooting) for missing records, deployment failures, and secret management issues.
## Related
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the data path the stacks deploy.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — strip PII before it leaves your AWS account.
* [IAM policies reference](/docs/iam-policies) — the roles and policies the stack creates.
* [Architecture overview](/docs/get-started-architecture) — how collectors, signals, and observations fit together.
# Agent headsets and AI audio tooling
Source: https://docs.operata.com/docs/integrations-headsets-and-audio-tooling
The Agent Collector reads the agent's audio path — the headset itself, and any AI audio processing sitting between the headset and the softphone. Here's what Operata captures and how to set each vendor up.
Audio quality problems usually start at the agent's desk. The Agent Collector reads the audio path directly: which headset is connected, what it measured, and whether AI audio processing was running between the headset and the softphone.
## How it works
The [Agent Collector](/docs/collector-overview) browser extension talks to the vendor software already installed on the agent's machine. Each vendor exposes something different, so what Operata captures depends on which one you run.
## What you get
* **Device attribution** — the make and model in use on each contact, on the Headset Inventory page.
* **Headset audio measurements** — levels read at the device rather than inferred from the stream.
* **Processing state** — whether noise cancellation or accent conversion was active while the agent was talking.
Together these answer the question a voice quality dashboard can't: was it the network, the device, or the software processing the audio?
## Supported vendors
| Vendor | What Operata captures | Setup |
| - | - | - |
| Jabra | Headset statistics and call control on supported Engage and Evolve devices | [Jabra quick start](/docs/help/jabra-quick-start) |
| Krisp | The connected headset, plus whether noise cancellation and accent conversion are enabled | [Krisp integration](/docs/help/krisp-integration) |
| Sanas | The connected headset behind the Sanas application | [Sanas integration](/docs/help/sanas-integration) |
## Related
* [Headset compatibility](/docs/headset-compatibility) — supported devices, operating systems, and browsers.
* [Headset logs](/docs/headset-logs) — the data reference for what Operata stores.
* [Jabra dashboard](/docs/help/jabra) — where headset data lands in the app.
* [Audio levels](/docs/help/audio-levels) — how Operata measures loudness and background noise.
# Install the NICE CXOne integration
Source: https://docs.operata.com/docs/integrations-nice-cxone-install
Connect a NICE CXOne tenant to Operata and verify the first Interaction record arrives.
Connect your NICE CXOne tenant to Operata so Interaction records stream in automatically and the Agent Collector on each agent endpoint forwards machine, network, and softphone telemetry tagged with your Operata Group ID.
The full step-by-step NICE CXOne install runbook is not yet documented. Contact [Operata Support](mailto:support@operata.com) to coordinate the integration; the engineering team handles the tenant-side configuration alongside you while this page is being written.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role and your Operata Group ID.
* A NICE CXOne tenant with admin access to **MAX Agent** configuration, **WebRTC Softphone** settings, **User Management**, and **Studio** scripts where applicable.
* The [NICE CXOne integration overview](/docs/integrations-nice-cxone-overview) read end to end.
## Steps
1. **Provision the Operata Group ID in your NICE CXOne tenant.**
Contact Operata Support to receive the per-tenant configuration that binds NICE CXOne Interaction records to your Operata Group ID.
2. **Deploy the Agent Collector to each agent endpoint.**
Install the Operata browser extension on every agent's machine. See [Chrome extension](/docs/chrome-extension) or [Edge extension](/docs/edge-extension).
3. **Configure the MAX WebRTC Softphone.**
Operata Support provides the softphone configuration values; apply them in your NICE CXOne tenant under **Studio** and **WebRTC** settings.
4. **Place a test Interaction.**
Run a test interaction through MAX Agent. Operata records the Interaction within five minutes of Interaction end.
## Verify
In the Operata console, open **Contacts** and filter to the last 10 minutes. Your test Interaction appears with `contact.id.current` matching the NICE CXOne contact ID, `accountProperties.operataGroupId` matching your Group ID, and `serviceAgent` populated with the endpoint's machine, browser, and network details.
## Related
* [NICE CXOne integration overview](/docs/integrations-nice-cxone-overview) — Data flows, supported softphones, and the per-Interaction record shape.
* [Agent Collector](/docs/collector-overview) — Browser extension installation paths.
* [NICE CXOne data glossary](/docs/cxone-account) — Per-field reference for the Interaction records.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — How Operata applies redaction to incoming records.
# NICE CXOne integration
Source: https://docs.operata.com/docs/integrations-nice-cxone-overview
Connect NICE CXOne to Operata and get real-time CX observability over every Interaction — quality signals, analytics, and insights in one place.
Connect NICE CXOne (formerly NICE inContact) to Operata and get real-time visibility over every Interaction — whether a human agent or an AI agent handled it — so you can see why call quality, routing outcomes, and customer results are what they are. Operata is CX observability for cloud contact centers.
The integration collects data through two channels: the Agent Collector captures machine, browser, network, and softphone telemetry directly from the agent endpoint, and NICE CXOne streams structured Interaction records to Operata. Operata stitches those signals into observations, derives insights, and surfaces them in the Operata console and over the API.
Operata does not access call recordings or live audio media. The integration uses the same Customer Journey Trace identifier scheme as the Amazon Connect and Genesys Cloud integrations, so cross-platform journeys link automatically.
The full step-by-step NICE CXOne install runbook is not yet documented. A complete runbook lands in a later release. Contact [Operata Support](mailto:support@operata.com) to coordinate the integration; the engineering team handles the tenant-side configuration alongside you while this page is being written.
## How it works
Operata reads NICE CXOne through two channels.
* **Agent Collector** — a browser extension installed alongside the MAX Agent or MAX WebRTC Softphone. The Collector captures machine, browser, network, and softphone telemetry per Interaction and forwards it to Operata.
* **Interaction records** — each NICE CXOne Interaction reaches Operata as a structured record stamped with your Operata Group ID. The records carry the Interaction lifecycle, agent state, network and device data, and the WebRTC session metrics.
```mermaid theme={null}
flowchart LR
A[Agent Collector] -->|browser telemetry| O[Operata API]
N[NICE CXOne tenant] -->|Interaction records| O
O --> J[Customer Journey Trace]
```
## What data Operata collects
Per-Interaction record shapes are documented in the **Data reference** tab under NICE CXOne. The headline shapes are:
* [Account properties](/docs/cxone-account) — the Operata group binding the Interaction belongs to.
* [Interaction](/docs/cxone-interaction) — identifiers, event timestamps, direction, type, recording URL, and disconnect reason.
* [Agent](/docs/cxone-agent) — agent endpoint state captured by the Agent Collector — machine resources, browser, softphone version, audio devices, network details.
* [Headset](/docs/cxone-headset) — headset model, firmware, and audio device events.
* [WebRTC session](/docs/cxone-webrtc-session) — per-session WebRTC statistics including packet loss, jitter, and MOS.
* [Agent feedback](/docs/cxone-agent-feedback) — agent-reported issues raised from the Collector toolbar.
* [Insights](/docs/cxone-insights) — Operata insights computed across the Interaction.
## Supported softphones and browsers
Operata supports the following NICE CXOne softphone:
* **MAX WebRTC Softphone** (browser-based).
Browser support for the Agent Collector on NICE CXOne:
| Browser | Version |
| - | - |
| Google Chrome | Last three stable versions |
For the cross-platform compatibility matrix, see [Compatibility platforms](/docs/compatibility-platforms).
## Verify
In the Operata console, open **Group Settings > Integrations**. The **NICE CXOne** integration appears once the first Interaction record arrives. Per-Interaction analytics appear in the **Contacts** view within five minutes of Interaction end.
## Related
* [Install the NICE CXOne integration](/docs/integrations-nice-cxone-install) — Connect a NICE CXOne tenant to Operata.
* [Agent Collector](/docs/collector-overview) — Install the browser extension on each agent endpoint.
* [Concept: Customer Journey Trace](/docs/concepts-customer-journey-trace) — How Operata links NICE CXOne Interactions across the journey.
* [NICE CXOne data glossary](/docs/cxone-account) — Per-field reference for the Interaction record shape.
# Observability backends
Source: https://docs.operata.com/docs/integrations-observability-overview
Operata forwards contact and signal events to your observability stack — Splunk, Datadog, and more — through Amazon EventBridge.
Operata forwards contact and signal events to your observability stack through Amazon EventBridge. Every Operata event lands on an EventBridge bus in your AWS account; you route from there to Splunk, Datadog, S3, or any AWS-native destination using standard EventBridge rules.
No separate webhook endpoint is required. Operata owns the publishing; you own the routing.
## Related
* [EventBridge](/docs/concepts-eventbridge) — how Operata publishes events to your AWS account.
* [Webhooks overview](/docs/api-webhooks-overview) — the canonical event catalog, envelope format, and delivery guarantees.
* [Configure webhooks](/docs/api-webhooks-configure) — bind an EventBridge partner event source to a bus in your tenant.
# Choose your integration
Source: https://docs.operata.com/docs/integrations-overview
Every Operata deployment pairs a platform integration with the Agent Collector. Pick your contact center platform and install both.
Connect your contact center platform and Operata starts receiving data. Collectors in your environment send signals — per-contact measurements from Contact Trace Records (CTRs), platform events, and agent-side telemetry — and Operata stores them as observations that the insight engine and your team can act on.
## How every integration works
Every integration has the same two parts, whatever platform you run.
1. **A platform integration.** Streams the contact record and platform events from your contact center into Operata. What it deploys depends on the platform — a stack in your AWS account, an OAuth client, or an event subscription.
2. **The [Agent Collector](/docs/collector-overview).** A browser extension that captures machine, network, headset, and softphone telemetry from the agent's endpoint. No central service can produce this, so it is the same install on every platform.
Install both. A platform integration alone gives you the contact record without the agent-side truth; the Agent Collector alone gives you endpoint telemetry with no contact to attach it to.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role.
* The contact center platform you operate, administered by you or a team you can reach.
## Contact center platforms
Pick the platform that hosts your contacts.
| Platform | What Operata collects | Install |
| - | - | - |
| **Amazon Connect** | Contact Trace Records, conversational analytics, Contact Flow Logs, and Lex data, through the Cloud Collector in your AWS account | [Overview](/docs/integrations-amazon-connect-overview) · [Install](/docs/ctr-installation) |
| **Genesys Cloud** | Conversation analytics and platform events through Amazon EventBridge, plus a read-only OAuth client; the Operata Fetcher Service handles enrichment | [Overview](/docs/genesys-overview) · [Install](/docs/genesys-installation) |
| **NICE CXOne** | Interaction records and softphone telemetry | [Overview](/docs/integrations-nice-cxone-overview) · [Install](/docs/integrations-nice-cxone-install) |
NICE CXOne overview and install scope are landing now; the full runbook arrives in a later release.
## Agent Collector
The browser extension that captures agent-side telemetry per contact. Required alongside every platform integration.
| Page | What it covers |
| - | - |
| [Agent Collector](/docs/collector-overview) | What it captures and how it reaches Operata |
| [Chrome extension](/docs/chrome-extension) | Install on Google Chrome |
| [Edge extension](/docs/edge-extension) | Install on Microsoft Edge |
| [VPN bypass URL](/docs/vpn-bypass) | Configure when agents work behind a corporate VPN, so Operata sees the true ISP and network location |
## Observability backends
Forward Operata events to the stack your team already watches.
* [Observability backends](/docs/integrations-observability-overview) — Datadog, Splunk, New Relic, and other destinations Operata can ship Amazon EventBridge events to.
## Verify
In the Operata console, open **Group Settings > Integrations**. The integrations you have installed appear with status `Active`. Each installed integration also lists its current Group ID binding and the AWS region it streams from.
## Related
* [How Operata works](/docs/get-started-architecture) — the three layers, before you commit to a deployment shape.
* [Cloud Collector](/docs/concepts-cloud-collector) — the AWS-side ingestion service Amazon Connect integrations deploy.
* [Customer Journey Trace](/docs/concepts-customer-journey-trace) — how Operata links contacts across integrations into one trace.
* [Compatibility](/docs/compatibility-platforms) — supported platform versions and feature coverage.
# Grant KMS access to the EventBridge Pipe
Source: https://docs.operata.com/docs/kms-encryption
Add Kinesis and Amazon EventBridge Pipe statements to a customer-managed KMS key so the Cloud Collector can decrypt Contact Trace Records.
If your Kinesis stream is encrypted with a customer-managed KMS key (CMK), grant
the Cloud Collector's Amazon EventBridge Pipe execution role the KMS actions it
needs to decrypt Contact Trace Records (CTRs) from Kinesis.
## Before you start
* A Kinesis stream encrypted with a customer-managed KMS key. AWS
managed keys (`aws/kinesis`) need no extra policy work.
* The deployed [Cloud Collector](/docs/concepts-cloud-collector) — the
CloudFormation stack you installed in
[Install CTR collection](/docs/ctr-installation).
* Two values from the stack:
* The ARN of the Kinesis stream the pipe reads from.
* The ARN of the EventBridge Pipe execution role (CloudFormation
output `EventBridgePipeRoleArn`).
* IAM permission to edit the KMS key policy.
The Cloud Collector needs five KMS actions on the CMK:
```text theme={null}
kms:Encrypt
kms:Decrypt
kms:ReEncrypt*
kms:GenerateDataKey*
kms:DescribeKey
```
## Steps
### 1. Open the KMS key
In the AWS console, open **KMS → Customer managed keys** and select
the key the Kinesis stream uses.
### 2. Edit the key policy
Under **Key policy**, click **Switch to policy view** (if you're in
the default view) and then **Edit**.
### 3. Add the Kinesis and Pipe statements
Append the following two statements to the `Statement` array.
Substitute your real Kinesis stream ARN and EventBridge Pipe role ARN
for the placeholders.
```json theme={null}
{
"Sid": "AllowKinesisStreamEncryption",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "{Kinesis Stream ARN}"
},
{
"Sid": "AllowEventBridgePipeDecrypt",
"Effect": "Allow",
"Principal": {
"AWS": "{Execution Role of EventBridge Pipe}"
},
"Action": "kms:Decrypt",
"Resource": "*"
}
```
A worked example:
```json theme={null}
"Resource": "arn:aws:kinesis:us-east-1:8012345678:stream/Operata-Kinesis"
"Principal": {
"AWS": "arn:aws:iam::8012345678:role/OperataAWSIntegration-CTR-operataEventBridgePipeRol-R2GazQu5D7mk"
}
```
### 4. Save the policy
Click **Finish** to save. KMS key policy changes take effect
immediately.
## Verify
Place a test contact through Amazon Connect and confirm the CTR
appears in the Operata console within five minutes. If it doesn't,
check the EventBridge Pipe in the AWS console for a `KMSAccessDenied`
error and re-check the Principal ARN you pasted into the second
statement.
## Related
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — covers KMS-related delivery failures.
* [IAM policies reference](/docs/iam-policies) — the rest of the roles the EventBridge Pipe needs.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — what the pipe does once it can read the stream.
# Install the Amazon Lex integration
Source: https://docs.operata.com/docs/lex-integration
Deploy the CloudFormation stack that streams Amazon Lex V2 conversation events into Operata for correlation with Amazon Connect contacts.
Deploy the CloudFormation stack so your Amazon Lex V2 conversation events stream
from CloudWatch into Operata — a test contact that routes through your Lex bot
shows the bot's intents, slots, and fulfillment data in the Operata console
within five minutes of contact end.
## Before you start
* An [Amazon Connect integration](/docs/integrations-amazon-connect-overview)
already streaming Contact Trace Records (CTRs).
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* AWS [IAM permissions](/docs/iam-policies) to deploy CloudFormation in
the region hosting your Amazon Lex V2 bots.
* [Amazon Lex V2](https://docs.aws.amazon.com/lexv2/latest/dg/what-is.html)
bots wired into your Amazon Connect contact flows.
* [Lex conversation logging](https://docs.aws.amazon.com/lexv2/latest/dg/conversation-logs.html)
enabled on each bot alias you want to monitor. Operata consumes text
logs; audio logs are not required.
Configure conversation logging per bot alias in the Amazon Lex V2
console. Operata consumes the text-based log stream.
## Steps
### 1. Send Operata the install details
Contact [Operata Support](mailto:support@operata.com) with:
* **AWS region** hosting your Lex bots.
* **CloudWatch log group name** for the Lex conversation logs —
usually `/aws/lex/`. To find it for a specific bot,
open the Amazon Lex console, select the bot, open **Deployment →
Aliases**, and copy the **CloudWatch Log Group Name** value from the
right-hand panel.
* **Operata Group ID** — Operata can confirm yours if you do not have
it on hand.
Operata returns a quick-create CloudFormation link pre-filled with
your configuration.
### 2. Open the quick-create link
Click the link to open the [CloudFormation
console](https://console.aws.amazon.com/cloudformation). Every
parameter is pre-populated except the API key.
### 3. Enter your Operata API token
Paste an Operata API token into the **API key** parameter. Create one
in the Operata console under **Settings → Config → API**. See [Authentication](/docs/api-authentication)
for the full lifecycle.
### 4. Deploy the stack
Acknowledge the IAM resource creation and click **Create stack**. The stack
reaches `CREATE_COMPLETE` in around five minutes. CloudFormation provisions:
| Resource | Quantity | Purpose |
| - | - | - |
| [EventBridge Pipe](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) | 1 | Streams Lex conversation events to the Operata API destination. |
| [API Destination](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-api-destinations.html) | 1 | The Operata API endpoint. |
| [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) | 1 | Service-execution role for the Pipe. |
| [IAM Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) | 2 | CloudWatch source access and API destination invocation. |
| [Secrets Manager Secret](https://docs.aws.amazon.com/secretsmanager/) | 1 | The Operata API key. |
### 5. (Optional) Tag the new resources
Apply your cost-allocation and ownership tags. See [Tag your AWS
resources](/docs/aws-tagging).
### 6. Place a test contact through the bot
Trigger a call that routes to your Lex bot through an Amazon Connect
contact flow. Interact by voice or DTMF as your flow expects. End the
contact cleanly.
## Verify
In the [Operata console](https://app.operata.io), open **Calls and
Logs → Summary** and locate the test contact. The Lex conversation
events appear within five minutes of contact end and join the Contact
Trace Record (CTR) by `ContactId`.
If nothing appears after five minutes, see [Troubleshooting](/docs/aws-troubleshooting).
## Data collected
Each event carries a Lex conversation log entry, including:
* Session ID and bot identifiers.
* Intent names and recognition confidence scores.
* Slot values (subject to redaction).
* Utterance text (subject to redaction).
* Session attributes.
* Fulfillment status and Lambda response data.
* Conversation timestamps.
For the full Lex log schema, see the
[AWS Lex logging reference](https://docs.aws.amazon.com/lexv2/latest/dg/security-logging-and-monitoring.html).
## Privacy
Raw Lex logs contain customer utterances and slot values. The
integration ships a redaction Lambda that runs in your AWS account
before any log leaves AWS. See:
* [Lex redaction schema](/docs/lex-privacy) — the field-tier schema and the mandatory keep-list.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — the model the redaction Lambda enforces.
Contact [Operata Support](mailto:support@operata.com) for help selecting
a redaction configuration.
## Charges
All AWS service charges from this stack appear on your AWS bill. The Lex
integration is included in every Operata plan at no Operata cost.
Primary cost factors:
* EventBridge event processing.
* CloudWatch Logs data transfer out of CloudWatch.
* Secrets Manager (rolled into the API destination charge).
You may incur additional [AWS data-transfer charges](https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer)
for data leaving AWS to Operata.
## Deploying alongside other stacks
The Lex stack runs independently of the CTR, conversational analytics, and
contact-flow logs stacks. Add or remove any stack without affecting
the others.
## Related
* [Lex redaction schema](/docs/lex-privacy) — strip PII fields before logs leave AWS.
* [Install Contact Flow Logs collection](/docs/contact-flow-logs) — pair Lex bot data with the broader IVR path.
* [Concept: Cloud Collector](/docs/concepts-cloud-collector) — the Operata-side runtime that joins Lex events to contacts.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — missing events, IAM debugging, Amazon EventBridge Pipe failures.
# Lex redaction schema
Source: https://docs.operata.com/docs/lex-privacy
Field tiers, mandatory keep-list, and processing order for the Amazon Lex redaction Lambda that runs in your AWS account.
The Amazon Lex redaction Lambda enforces this schema. The Lambda runs inside
your AWS account, applies these rules to every Lex conversation event read
from CloudWatch, and ships only the surviving payload to Operata.
For the model behind the schema and the rollout procedure, see
[Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction)
and [Configure Lex redaction](/docs/guides-configure-lex-redaction).
This schema applies to the Amazon Lex integration only. Contact
Flow Logs and CTR integrations have their own schemas.
## Field tiers
Every field in a Lex conversation event belongs to exactly one of six
tiers.
| Tier | Behavior | Controlled by |
| - | - | - |
| Mandatory | Key and value transmitted unchanged. Cannot be denied, hashed, encrypted, or redacted. | Operata |
| Allow | Key and value transmitted unchanged. Customer-declared. | Customer |
| Deny | Key and value removed entirely. Operata never sees the field. | Customer |
| Encrypt | Key retained, value replaced with a hash or ciphertext. | Customer |
| Transform | Key retained, value replaced with derived or calculated data. | Customer |
| Default | Key retained, value nullified. | Customer |
The four customer-configurable tiers (Allow, Deny, Encrypt, Transform)
are mutually exclusive: any one field appears in at most one tier.
Today only the Mandatory tier is enforced end to end. Allow, Deny,
Encrypt, and Transform are accepted in the config but applied as
pass-through. Follow the [Operata changelog](/docs/changelog) for
rollout.
## Processing order
The Lambda processes every event in four passes, in order.
1. **Mandatory override.** Check each field path against the mandatory
list. If a mandatory field sits under a denied parent, retain the
parent and prune all non-mandatory siblings. Mandatory always wins.
2. **Deny.** Evaluate every remaining field path against the deny
list. Mark matched fields for removal.
3. **Allow, Encrypt, Transform.** Apply the customer-declared tiers
to remaining fields.
4. **Default nullify.** Every field not covered by the previous three
passes keeps its key, value becomes `null`.
## Path notation
Both lists use dot notation.
* `sessionState` matches the entire object at that key.
* `sessionState.intent.name` matches only that subfield.
* A trailing `.*` matches every direct child of the path. For
example, `interpretations.intent.slots.*.shape` matches the `shape`
field on every slot under `interpretations.intent.slots`.
Rules apply at every depth consistently.
## Parent-key behavior
When a deny entry targets a parent and no mandatory entry references
any child, the Lambda removes the entire key — not an empty object.
When a deny entry targets a parent and the mandatory, allow, encrypt,
or transform list references one or more children of that parent, the
Lambda retains the parent containing only those referenced children.
## Data flow
```text theme={null}
CloudWatch (raw Lex conversation log)
↓
Redaction Lambda (in your AWS account)
├─ Pass 1: Mandatory override
├─ Pass 2: Deny
├─ Pass 3: Allow / Encrypt / Transform
└─ Pass 4: Default nullify
↓
Operata API (filtered payload only)
```
## Mandatory keep-list
The redaction Lambda always preserves these fields, regardless of
deny, encrypt, or transform configuration.
```text theme={null}
errorLogSchema
errorLogSchemaType
timestamp
requestId
messageVersion
transcriptions.resolvedContext.intent
transcriptions.transcriptionConfidence
transcriptions.resolvedSlots.*.shape
fulfilledByAssistedNlu
requestAttributes.x-amz-lex:*
sessionId
inputMode
bargeIn
operationName
isTestWorkbenchTraffic
interpretations.intent.name
interpretations.intent.state
interpretations.intent.slots.*.shape
interpretations.intent.confirmationState
interpretations.interpretationSource
interpretations.nluConfidence
developerOverride
bot
sessionState.sessionAttributes.x-amz-lex:*
sessionState.sessionAttributes.bedrock_request_id
sessionState.sessionAttributes.confirm_bedrock_request_id
sessionState.sessionAttributes.confirm_llm
sessionState.sessionAttributes.confirm_llm_input_tokens
sessionState.sessionAttributes.confirm_llm_latency
sessionState.sessionAttributes.confirm_llm_model_id
sessionState.sessionAttributes.confirm_llm_output_tokens
sessionState.sessionAttributes.llm
sessionState.sessionAttributes.llm_input_tokens
sessionState.sessionAttributes.llm_latency
sessionState.sessionAttributes.llm_model_id
sessionState.sessionAttributes.llm_output_tokens
sessionState.dialogAction
sessionState.dialogAction.slotToElicit
sessionState.dialogAction.type
sessionState.intent.name
sessionState.intent.state
sessionState.intent.slots.*.shape
sessionState.intent.confirmationState
sessionState.originatingRequestId
missedUtterance
responseReason
utteranceContext
```
## Related
* [Configure Lex redaction](/docs/guides-configure-lex-redaction) — step-by-step rollout.
* [Concept: Privacy and redaction](/docs/concepts-privacy-and-redaction) — the cross-integration model.
* [Contact Flow Log redaction schema](/docs/contact-flow-log-privacy) — the sibling schema for contact-flow logs.
* [Install the Amazon Lex integration](/docs/lex-integration) — the integration this schema applies to.
# Machine, browser, and network data
Source: https://docs.operata.com/docs/machine-browser-network
Browser name and version, CPU model, and IP addresses for the agent endpoint, captured by the Agent Collector on every Amazon Connect Contact.
The `browser`, `system`, and `network` objects identify the agent endpoint's browser, hardware, and network configuration for one Amazon Connect Contact. The Agent Collector emits these objects on every Contact.
## Schema
```json theme={null}
"browser": {
"name": "Chrome",
"version": "115.0.5790.170"
},
"system": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz"
}
},
"network": {
"agentExternalIPAddress": "103.120.49.101",
"agentIPAddress": "192.168.1.18"
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `browser.name` | string | yes | Browser engine name reported by the Agent Collector. | `Chrome` |
| `browser.version` | string | yes | Browser version string. | `115.0.5790.170` |
| `system.cpu.modelName` | string | yes | CPU model string reported by the operating system. | `Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz` |
| `network.agentExternalIPAddress` | string (IPv4) | yes | Agent WAN IP address (the public IP detected by Operata). | `103.120.49.101` |
| `network.agentIPAddress` | string (IPv4) | yes | Agent LAN IP address (the local interface that handled media). | `192.168.1.18` |
For the full agent endpoint object that wraps these fields, see [Agent](/docs/agent).
## Notes
* `network.agentExternalIPAddress` is the public IP Operata detects, used for geolocation and ISP lookup. `network.agentIPAddress` is the local interface address that handled media.
* All five fields are marked required: the Agent Collector always captures them.
# Install the Cloud Orchestrator
Source: https://docs.operata.com/docs/orchestrator-installation
Deploy the Cloud Orchestrator CloudFormation stack into your AWS account so the ECS Fargate service starts and Heartbeat checks can run.
Deploy the Cloud Orchestrator (Operata's Amazon ECS Fargate service for synthetic
testing and recording analysis) into your AWS account — when the stack reaches
`CREATE_COMPLETE` and the ECS service shows **Running tasks: 1/1**, you're ready
to drive Heartbeat checks.
## Before you start
* An Amazon Connect instance in the AWS region you intend to deploy
into. Cloud Orchestrator must live in the same region as Amazon
Connect.
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* The Cloud Orchestrator CloudFormation template URL. Operata supplies
one of two templates: a **new-VPC** template that creates a dedicated
VPC, or an **existing-VPC** template that deploys into a VPC you
already operate. Contact [Operata Support](mailto:support@operata.com)
for the link.
* AWS [IAM permissions](/docs/iam-policies) to create CloudFormation
stacks, IAM roles, ECS clusters, VPC networking, and Secrets Manager
secrets.
* The [Cloud Orchestrator concept](/docs/concepts-cloud-orchestrator)
read end to end — this page is the deployment runbook for the
service that page describes.
* If your call recordings use a customer-managed KMS key, plan to
follow [KMS encryption](/docs/kms-encryption) after the stack
deploys.
## Steps
### 1. Collect the eight required parameters
Have these values ready before you open CloudFormation. The
existing-VPC template needs two more, covered in step 2.
| Parameter | Where to find it |
| - | - |
| `ConnectInstanceARN` | Amazon Connect console → **Overview**. Use the full ARN, for example `arn:aws:connect:ap-southeast-2:083560123456:instance/8f3b9a12-2b6b-4a07-8d33-c6f7b21a4ab0`. |
| `ConnectRecordingsBucketName` | Amazon Connect console → **Data Storage**. Bucket name only — for `call.recordings/connect/acme-prod`, enter `call.recordings`. |
| `LogLevel` | Leave at the default `0`. |
| `OperataAPIToken` | Operata console → **Settings → Config → API**. Create a token labeled `Orchestrator` and copy the value. See [Authentication](/docs/api-authentication) for the full token lifecycle. |
| `OperataAPIUrl` | Leave at the default `https://api.operata.io`. |
| `OperataGroupID` | Provided by Operata. |
| `OperataHeartbeatRoutingProfile` | Set to `Operata_Heartbeat_RP`. You create this profile in [Set up Heartbeat](/docs/heartbeat-setup). |
| `OrchestratorVersion` | Leave at the default. |
### 2. (Existing VPC only) Collect the VPC parameters
Skip this step if you use the new-VPC template.
| Parameter | Where to find it |
| - | - |
| `VPCID` | The VPC ID to deploy the ECS cluster into. |
| `SubnetIDs` | The list of VPC subnets allowed for ECS task deployment. |
The VPC must allow bi-directional media access for the Virtual Agent
to operate:
* Outbound port `3478` open on the Virtual Agent security group.
* VPC ACL inbound: UDP ports `49152`–`65535`.
* VPC ACL outbound: UDP ports `49152`–`65535` and `3478`–`65535`.
See the [AWS guide to CCP networking](https://docs.aws.amazon.com/connect/latest/adminguide/ccp-networking.html#stateless-firewalls)
for the upstream reference.
### 3. Create the CloudFormation stack
In the AWS console, open **CloudFormation** in the same region as your
Amazon Connect instance, then choose **Create stack → With new
resources (standard)**.
Select **Upload a template file** and upload the `.yml` Operata
supplied. Click **Next**.
### 4. Enter the stack parameters
Give the stack a name that includes `OperataOrchestrator` — for
example, `OperataOrchestrator-prod`. Paste the parameters you collected
in step 1 (and step 2, if you use the existing-VPC template).
**Cloud Orchestrator parameters cannot be edited after stack creation.**
If a parameter is wrong, delete the stack and create a new one. Do not
use the change-sets feature. If you replace an existing Orchestrator,
update the Lambda name in Amazon Connect to point at the new stack's
Lambda — the old name no longer exists.
### 5. Review and create the stack
Click through **Next** on the stack-options screen. On the **Review
and create** screen, check the IAM resource-creation acknowledgement
and click **Create stack**.
The stack reaches `CREATE_COMPLETE` in around 10 minutes.
### 6. (Optional) Tag the new resources
Apply your cost-allocation and ownership tags. See [Tag your AWS
resources](/docs/aws-tagging) for the tag set Operata expects on the
deployed stack.
## Verify
Open the Cloud Orchestrator stack in the CloudFormation console, then
open the **Resources** tab and search for `log`. Click the log group
link to open CloudWatch Logs. The most recent log stream confirms the
Orchestrator service started and is polling the Operata API.
In Amazon ECS, the stack creates a Fargate cluster running one service.
The service shows **Running tasks: 1/1**.
If the stack fails to reach `CREATE_COMPLETE` or the logs show errors,
see [Troubleshoot the AWS integration](/docs/aws-troubleshooting).
## Related
* [Set up Heartbeat](/docs/heartbeat-setup) — create the routing
profile, contact flow, and phone number that drive synthetic test
calls.
* [Heartbeat Virtual Agent](/docs/virtual-agent) — deploy the
containerized agent that answers Heartbeat calls.
* [Concept: Cloud Orchestrator](/docs/concepts-cloud-orchestrator) —
the AWS-side runtime you just deployed and why it is built this way.
* [EventBridge](/docs/concepts-eventbridge) — how Heartbeat run
results reach your downstream systems.
# PII in Operata
Source: https://docs.operata.com/docs/pii
What counts as personally identifiable information in the data Operata collects, and how redaction at the edge controls what leaves your environment.
Personally identifiable information (PII) in Operata is any field on a contact record that can identify a real person — phone numbers, agent names, custom attributes carrying customer data — and you decide which of those fields leave your environment by configuring redaction at the edge of your AWS account.
## How it works
The data Operata ingests carries PII in three places:
* **Contact metadata** — customer phone numbers, queue names, custom attributes set by your flows, and any other field on the Amazon Connect Contact Trace Record (CTR) or the Genesys Cloud / NICE CXOne equivalents.
* **Agent context** — agent usernames, machine identifiers, and any account-level attributes you map to agents.
* **Conversational content** — conversation transcripts and sentiment fields, Amazon Lex slot values, and contact-flow log entries.
Operata does not see any of these fields until they leave your environment. Redaction runs at the edge of your AWS account through the [Cloud Collector](/docs/concepts-cloud-collector), so the fields you redact never reach Operata in the first place. There is no Operata-side "delete PII" step — if a field is in the payload Operata received, the field is stored.
The redaction model is allow-list or deny-list per field path. You configure it through the [redaction API](/docs/api-data-redaction) and apply it to one or more sources: CTRs, conversational analytics, contact-flow logs, and Lex events.
## Why redaction runs at the edge
Redacting at the edge means your AWS account remains the boundary of PII control. Operata cannot accidentally store fields it never received, audits are simpler (the redaction config is the single source of truth for what crosses the boundary), and the contract is reversible — change the config, and the next CTR honors the new rules.
The allow-list and deny-list shape is deliberate: a deny-list is easy to start with ("don't send me phone numbers"), an allow-list is the safer default for high-regulation tenants ("send only the fields I name"). Both compile to the same execution.
## Related
* [Privacy and redaction](/docs/concepts-privacy-and-redaction) — the model behind redaction across all sources.
* [Cloud Collector](/docs/concepts-cloud-collector) — where redaction runs.
* [Get redaction config](/docs/api-get-redaction-config) — read the current allow/deny rules for a source.
* [Update redaction config](/docs/api-update-redaction-config) — change the rules. Idempotent.
* [Delete redaction config](/docs/api-delete-redaction-config) — remove rules for a source.
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — the redaction guide for Amazon Connect.
* [Configure Genesys redaction](/docs/guides-configure-genesys-redaction) — the redaction guide for Genesys Cloud.
# Privacy and redaction overview
Source: https://docs.operata.com/docs/privacy-and-redaction-overview
How Operata handles privacy and redaction — what runs at the edge, what you control, and where to configure it.
Operata redacts at the edge of your environment before contact data leaves for Operata. This section maps the privacy model, defines personally identifiable information (PII) in the context of what Operata collects, and lists the configuration entry points for each data source.
## What's in this section
* **[Privacy and redaction concept](/docs/concepts-privacy-and-redaction)** — the model behind redaction: what runs where, what you control, and what stays raw.
* **[PII](/docs/pii)** — what counts as PII in the data Operata collects.
* **[Redaction config (API)](/docs/ctr-redaction-config)** — the API entry point for managing allow-list and deny-list rules.
For the API endpoint reference, see [Data redaction endpoints](/docs/api-data-redaction).
## Guides
For task-oriented walkthroughs, see the redaction guides:
* [Configure CTR redaction](/docs/guides-configure-ctr-redaction) — Amazon Connect CTR.
* [Configure Genesys redaction](/docs/guides-configure-genesys-redaction) — Genesys Cloud conversation data.
* [Configure contact-flow log redaction](/docs/guides-configure-contact-flow-log-redaction) — Amazon Connect contact-flow logs.
* [Configure Lex redaction](/docs/guides-configure-lex-redaction) — Amazon Lex slot values and events.
# Product lifecycle
Source: https://docs.operata.com/docs/product-lifecycle
Support phases, notice periods, and the current lifecycle status of every Operata product version.
Operata products move through three support phases — Committed, Deprecated, Retired — with a minimum 90-day notice before any change. This page lists the current phase of every product version Operata ships.
## Support phases
| Phase | Support | Updates | CCaaS integration support |
| - | - | - | - |
| Committed | Full | Active | Current and previous two versions of Chrome and Edge. |
| Deprecated | Limited | Critical fixes only. No new installations. | Limited or none. |
| Retired | None | None | None. Documentation may be archived. |
### Committed
A Committed product receives full technical support, regular software updates, complete documentation, and active feature development. The Collector supports the current and previous two versions of Chrome and Edge while in this phase.
### Deprecated
A Deprecated product is scheduled for removal or replacement. Development has stopped. Operata resolves critical functionality issues but does not commit to fixing minor bugs or cosmetic issues. CCaaS integration support is limited. Documentation remains available. Support focuses on migration.
### Retired
A Retired product receives no support. Documentation may be archived. Operata ships no further bug fixes or updates.
## Notice period
Operata gives a minimum **90-day advance notice** for:
* Version support changes.
* Feature deprecations.
* Product retirements.
Notices arrive through Operata platform notifications, email, service reviews, and documentation updates.
## Current product versions
### Browser extensions
| Product | Version | Status | Committed date | Deprecated date | Retired date |
| - | - | - | - | - | - |
| Operata Collector for Chrome and Edge | 1.7.x | Committed | Jan 1, 2024 | Jun 1, 2025 | Dec 1, 2025 |
| Operata Collector for Chrome and Edge | 1.8.x | Committed | Aug 1, 2025 | — | — |
| Operata Collector for Chrome and Edge | 1.6.x | Deprecated | — | Jan 1, 2024 | — |
### Cloud services
| Product | Version | Status | Committed date | Deprecated date | Retired date |
| - | - | - | - | - | - |
| Heartbeat (Orchestrator) | 1.0.13 | Committed | Mar 1, 2023 | — | — |
| Virtual Agent | 1.xx | Committed | Sep 1, 2022 | — | — |
| AWS Integration | 1.xx | Committed | Jun 1, 2023 | — | — |
## Retired products
| Product | Version | Deprecated date | Retired date |
| - | - | - | - |
| Agent Collector JS | 1.xx | Jul 1, 2022 | Jan 1, 2023 |
| Operata Collector for Chrome and Edge | \<1.4.x | Jul 1, 2022 | Jan 1, 2023 |
| Operata Collector for Chrome and Edge | 1.5.x | Nov 1, 2022 | Mar 1, 2023 |
| Cloud Collector (Conductor) | 1.x.x | Jul 1, 2022 | Jan 1, 2023 |
| Cloud Collector and Heartbeat (Orchestrator) | 1.0.12 | Oct 1, 2022 | Mar 1, 2023 |
| Cloud Collector and Heartbeat (Orchestrator) | 1.0.13 | Aug 1, 2023 | Feb 1, 2024 |
## Feature deprecation
When Operata deprecates a feature, it is either removed entirely or automatically migrated to a replacement.
| Feature | Replacement | Status | Deprecated date | Retired date |
| - | - | - | - | - |
| Cloud Collector (Conductor) | AWS Integration | Retired | Aug 1, 2023 | Feb 1, 2024 |
| Classic Dashboards | Canvas Dashboards | Retired | May 1, 2024 | May 1, 2024 |
| Jabra Stats Dashboard | Canvas Dashboards | Retired | May 1, 2024 | May 1, 2024 |
## Related
* [Platform compatibility](/docs/compatibility-platforms) — certified CCaaS versions.
* [Browser compatibility](/docs/browser-compatibility) — supported browser versions.
* [Feature matrix](/docs/compatibility-feature-matrix) — feature availability by edition.
Contact [Operata Support](mailto:support@operata.com) for migration guidance or lifecycle planning.
# Quickstart
Source: https://docs.operata.com/docs/quickstart
One curl call, your Group ID, and an API token — your first Operata API response in 90 seconds.
Send one curl request and see an Operata contact in the response. You need a Group ID, an API token, and curl.
## Before you start
* An [Operata account](https://app.operata.io). Your **Operata Group ID** is the UUID in the console URL.
* An **API token** generated under **Settings → Config → API**.
## Make the request
```bash theme={null}
curl -u "$OPERATA_GROUP_ID:$OPERATA_API_TOKEN" \
"https://api.operata.io/v1/data/calls?fromTime=2026-05-17T00:00:00Z&toTime=2026-05-18T00:00:00Z&size=1"
```
## What you should see
```json theme={null}
{
"data": [
{
"id": "ctr_0HXYZ123456789ABCDE",
"started_at": "2026-05-17T15:02:11Z",
"duration_ms": 184200,
"agent": { "id": "agent_42", "name": "Riley Chen" },
"queue": "billing-tier-1"
}
],
"next_cursor": null
}
```
## What the response means
* You authenticated with HTTP Basic — Group ID as username, token as password. See [Authentication](/docs/api-authentication).
* You requested one contact from a 24-hour window using the contact summary endpoint. See [Contact summary](/docs/api-contact-summary).
* The response uses Operata's standard paginated envelope: a `data` array and a `next_cursor` field that is `null` when there are no further pages. See [Pagination](/docs/api-pagination).
* A 429 response means you hit the per-token budget — back off using `Retry-After`. See [Rate limits](/docs/api-rate-limits).
* Every 4xx and 5xx response carries a stable `error.code` you match on. See [Errors](/docs/api-errors).
## Related
The mental model behind contacts, signals, and observations.
Every endpoint, every parameter.
Choose which fields to strip before they reach Operata.
# Data collection — Amazon Connect
Source: https://docs.operata.com/docs/resources-data-collection-amazon-connect
How Operata collects Amazon Connect data from two independent sources — the AWS-side Cloud Collector and the agent-side Agent Collector — and joins them on the contact ID.
For Amazon Connect, Operata collects data from two sources: the AWS-side Cloud Collector running in your account, and the Agent Collector running in the agent's browser. The two streams join on the Amazon Connect contact ID.
## What each collector captures
Operata's Amazon Connect data falls into two categories.
**Customer Experience** covers the calling-party leg of the Contact. This includes Contact Trace Records (CTRs), conversation transcripts and sentiment, contact-flow logs, and Lex events.
**Agent Experience** covers the agent's network, machine, and softphone environment. This includes softphone logs, WebRTC session metrics, network performance, system performance, headset telemetry, screen recording telemetry, and any end-user-reported issues.
The two sources collect independently and join on the contact ID Operata observes from each:
* **Cloud Collector** runs in your AWS account. It ingests CTRs, conversational analytics output, contact-flow logs, and Lex events through Amazon EventBridge Pipes or a Lambda function provided by Operata. Redaction runs at this edge — see [PII](/docs/pii).
* **Agent Collector** runs in the agent's browser as the Operata Chrome or Edge extension. It captures the agent-side WebRTC stats, system resources, and headset telemetry every 10 seconds during a call.
## Why the sources are separate
Contact Trace Records (CTRs) are emitted by Amazon Connect after a contact ends. Agent-side telemetry only exists in the browser during the call. The split lets Operata observe both ends of a contact without forcing either side to ship data the other already has — and lets you control which CTR fields leave your AWS account through redaction without affecting the agent stream.
## Related
* [Data collection — Genesys Cloud](/docs/resources-data-collection-genesys) — the equivalent picture for Genesys Cloud.
* [Data summary and frequency](/docs/resources-data-collection-frequency) — which fields are collected and how often.
* [Example payloads](/docs/resources-data-collection-examples) — real JSON for pre-contact, during-contact, and post-contact data.
* [Cloud Collector](/docs/concepts-cloud-collector) — the AWS-side ingestion service.
* [Agent Collector](/docs/collector-overview) — the browser-side collector.
* [Screen recording observability](/docs/screen-recording) — whether Amazon Connect screen recording ran for each contact.
# Example payloads
Source: https://docs.operata.com/docs/resources-data-collection-examples
Complete example JSON payloads showing the data Operata collects at each Amazon Connect collection phase — pre-contact, during contact, and post-contact.
These are complete example payloads for each Amazon Connect collection phase — pre-contact, during contact, and post-contact. For the full list of fields and send frequencies, see [Data summary and frequency](/docs/resources-data-collection-frequency).
## Pre-contact
The following JSON shows the data Operata collects at the **initialization** of a contact.
```json theme={null}
{
"operataClientId": "78c93dee-a955-46c2-ab10-696d417031ec",
"agent": "Kelly",
"browser": {
"name": "Chrome",
"version": "88.0.4324.96"
},
"system": {
"cpu": {
"modelName": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz",
"idlePercentage": 94.58,
"usedPercentage": 5.420000000000002
},
"memory": {
"available": 38.17,
"total": 64
}
},
"state": "Busy",
"timestamp": "2021-01-25T22:49:20.626Z",
"context": {
"callContactId": "b9376095-4bb9-4b59-be5a-1c20b437d562"
}
}
```
## During contact
The following JSON shows the data Operata collects **during** a contact.
```json theme={null}
{
"timestamp": "2021-01-25T22:49:29.909Z",
"contactId": "e7388f85-068d-4bfb-99a8-762547bfff2b",
"agent": "Alexa",
"packetsSent": 50,
"packetsReceived": 49,
"packetsLost": 0,
"packetsLostFraction": 0,
"jitter": 5,
"rtt": 67,
"mos": 4.428995599562176,
"clientInfo": {
"operataClientId": "58e79ec6-b376-4b90-8bb1-d4c7edb07abf",
"operataClientSecret": "EpNsbIJalARhaSQxALe",
"ccpUrl": "https://danzig.com/unnameableness/parrotize",
"group": "",
"operataAPI": "https://api.operata.io"
},
"agentStatus": "Talk",
"cpuAvailable": 95.3,
"memoryAvailable": 59.8,
"inbound": {
"packetsLost": 0,
"packetsCount": 49,
"audioLevel": 689,
"jitterBufferMillis": 0,
"roundTripTimeMillis": null
},
"outbound": {
"packetsLost": 0,
"packetsCount": 50,
"audioLevel": 4,
"jitterBufferMillis": 5,
"roundTripTimeMillis": 43
}
}
```
## After contact
The following JSON shows the data Operata collects at the **completion** of a contact.
```json theme={null}
{
"timestamp": "2021-01-25T22:50:18.094Z",
"operataClientId": "58e79ec6-b376-4b90-8bb1-d4c7edb07abf",
"operataClientSecret": "EpNsbIJalARhaSQxALe",
"group": "",
"callContactId": "e7388f85-068d-4bfb-99a8-762547bfff2b",
"agent": "Alexa",
"agentAutoAnswer": false,
"agentIPAddress": "192.168.1.1",
"duration": 1,
"durationSeconds": 55,
"callStartTime": "2021-01-25T22:49:20.626Z",
"callEndTime": "2021-01-25T22:50:15.280Z",
"jitter": {
"min": 0,
"max": 7,
"avg": 2
},
"rtt": {
"min": 44,
"max": 119,
"avg": 57
},
"mos": {
"min": 4.400265513005151,
"max": 4.431607946461576,
"avg": 4.413012176931047
},
"packetLoss": {
"min": 0,
"max": 0,
"avg": 0
},
"totals": {
"packetsLostFraction": 0,
"packetsReceived": 2950,
"bytesReceived": 392828,
"bytesSent": 201819
},
"ipAddress": "10.4.2.11",
"port": 57574,
"protocol": "udp",
"networkType": "lan",
"attributes": {
"Location": "Default"
},
"iceServer1": {
"ipAddress": "turnnlb-xFUcx6Bbf.elb.ap-southeast-2.amazonaws.com.",
"port": "3478",
"protocol": "udp"
},
"iceServer2": null,
"clientInfo": {
"operataClientId": "58e79ec6-b376-4b90-8bb1-d4c7edb07abf",
"operataClientSecret": "EpNsbIJalARhaSQxALe",
"ccpUrl": "https://danzig.com/unnameableness/parrotize",
"group": "",
"operataAPI": "https://api.operata.io"
},
"browser": {
"name": "Chrome",
"version": "88.0.4324.96"
},
"callEvents": {
"muted": "2021-01-25T22:49:20.626Z",
"unmuted": "2021-01-25T22:49:20.626Z",
"onHold": "2021-01-25T22:49:20.626Z",
"resumed": "2021-01-25T22:49:20.626Z",
"incoming": "2021-01-25T22:49:14.427Z",
"connecting": "2021-01-25T22:49:14.427Z",
"connected": "2021-01-25T22:49:20.626Z",
"ended": {
"party": "Agent",
"timestamp": "2021-01-25T22:50:15.280Z"
}
},
"report": null,
"cpu": {
"min": 89.95,
"max": 96.5,
"avg": 94.68,
"model": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz"
},
"memory": {
"min": 38.17,
"max": 38.36,
"avg": 38.26,
"total": 64
}
}
```
## Related
* [Data summary and frequency](/docs/resources-data-collection-frequency) — every data group, by phase and frequency.
* [Data collection — Amazon Connect](/docs/resources-data-collection-amazon-connect) — the two-source collection model.
* [PII](/docs/pii) — what counts as PII and how to control which fields leave your environment.
# Data summary and frequency
Source: https://docs.operata.com/docs/resources-data-collection-frequency
Every data group Operata collects, organized by collection phase — pre-contact, during contact, post-contact — with send frequency for each.
Operata collects data across three phases of the contact lifecycle — pre-contact, during contact, and post-contact. The table below maps each data group to its phase and send frequency; each row links to the [Data reference](/docs/contact) glossary entry for that group.
## Data groups by phase
| Data group | [Pre-contact](/docs/resources-data-collection-examples#pre-contact) | [During contact](/docs/resources-data-collection-examples#during-contact) | [Post-contact](/docs/resources-data-collection-examples#after-contact) |
| - | - | - | - |
| *Send frequency* | *Once* | *Every 10 seconds* | *Once* |
| [Agent state logging](/docs/ccp-agent-states) | Yes | Yes | Yes |
| [System CPU and memory usage](/docs/system-resources) | Yes | Yes | Yes |
| Agent name and contact ID | Yes | Yes | Yes |
| [Agent feedback](/docs/agent-feedback) | Yes | Yes | Yes (optional) |
| [Geolocation and ISP](/docs/geolocation-isp) | Yes | Yes | Yes |
| [Machine, browser, and network data](/docs/machine-browser-network) | Yes | | Yes |
| [WebRTC metrics](/docs/webrtc-session) | | Yes | Yes |
| [Headset logs](/docs/headset-logs) | | Yes | Yes |
| [Contact Trace Records](/docs/contact-trace-records) | | | Yes (optional) |
| [Call signaling and handling events](/docs/call-events) | | | Yes |
| [CCP error logs](/docs/ccp-error-logs) | | | Yes |
| [Screen recording telemetry](/docs/screen-recording) | | | Yes (optional) |
| [Conversational analytics](/docs/conversational-analytics-data) | | Yes | Yes (optional) |
## Related
* [Example payloads](/docs/resources-data-collection-examples) — real JSON for each phase.
* [Data collection — Amazon Connect](/docs/resources-data-collection-amazon-connect) — the two-source model for Amazon Connect.
* [Data collection — Genesys Cloud](/docs/resources-data-collection-genesys) — the browser-only model for Genesys Cloud.
# Data collection — Genesys Cloud
Source: https://docs.operata.com/docs/resources-data-collection-genesys
How Operata collects Genesys Cloud data entirely through the agent-side Agent Collector running in the agent's Chrome browser.
For Genesys Cloud, Operata collects data from the agent's Chrome browser through the [Operata Chrome extension](/docs/chrome-extension). There is no AWS-side ingestion for Genesys Cloud — the agent browser is the single source.
## What the collector captures
Operata's Genesys Cloud data falls into two categories.
**Conversation data** covers the calling-party (customer) journey through Genesys Cloud IVRs and interactions with bots and agents.
**Agent-side data** covers the agent's network and operating environment. This includes softphone, network, system, and headset logs, plus any end-user-reported issues.
The Agent Collector captures both streams in the agent's browser during the Conversation. There is no equivalent of the Amazon Connect CTR or conversational analytics path — every Genesys Cloud Conversation Operata observes comes through the browser collector.
## Related
* [Data collection — Amazon Connect](/docs/resources-data-collection-amazon-connect) — the two-source picture for Amazon Connect.
* [Data summary and frequency](/docs/resources-data-collection-frequency) — which fields are collected and how often.
* [Example payloads](/docs/resources-data-collection-examples) — real JSON for pre-contact, during-contact, and post-contact data.
* [Genesys Cloud integration](/docs/genesys-overview) — install and configure the Genesys Cloud collector.
* [Agent Collector](/docs/collector-overview) — the browser-side collector.
# Screen recording observability
Source: https://docs.operata.com/docs/screen-recording
Find which contacts recorded, which didn't, and which agents account for the difference, from the screen recording lifecycle the Agent Collector parses out of the CCP logs.
Screen recording observability is a set of telemetry entries reporting whether Amazon Connect screen recording ran for each contact. The Agent Collector watches the Contact Control Panel (CCP) log stream, picks out the screen recording lifecycle lines, and ships them as structured entries tagged `ScreenRecording`. This page is for anyone who has to evidence screen recording coverage. The job is to find which contacts recorded, which didn't, and which agents account for the difference.
## What Amazon Connect reports
Amazon Connect reports that a contact was *flagged* for screen recording. Operata reports what happened next: whether the agent's machine recorded it, and whether the recording reached S3.
The failure sits on the agent endpoint. Screen recording depends on the Amazon Connect client app — a Windows installer that endpoint management has to deploy to every agent workstation. When the app is missing, blocked, or broken, Amazon Connect still flags the contact, the CCP still creates a recording, and nothing uploads. The Contact Trace Record (CTR) carries the flag, not the outcome.
Screen recording often carries a contractual compliance obligation, and the evidence for it is the gap between those two facts.
## Before you start
Screen recording telemetry is **off by default**. Three things have to be true:
* **Operata enables it on your group.** The Agent Collector reads a `screenRecordingTelemetry` flag from the collector configuration Operata serves to each group. When the flag is absent, the Collector defaults it to `false` and skips screen recording parsing entirely. Ask Operata support to turn it on.
* **CCP log collection is on.** The parser runs inside the CCP log pipeline. No log collection, no screen recording telemetry.
* **Agent Collector v1.7.29 or later**, on Chrome or Microsoft Edge, with agents on Windows. The Amazon Connect client app ships as a Windows MSI, so macOS agents produce no screen recording.
Screen recording telemetry is Amazon Connect only. The Genesys Cloud and NICE CXOne adaptors don't emit it.
## How it works
The Agent Collector hooks the Amazon Connect Streams logger in the agent's browser. For every captured entry at `INFO` level whose text mentions `recording`, it runs the screen recording parser.
Two component names show up in the logs, so check which one you're filtering on:
* **`screenRecorder`** — Amazon's component on the raw CCP log lines the screen recorder writes. These are in the CCP logs whether or not screen recording telemetry is on. Filter on `component = screenRecorder` to read them, including the `WARN` and `ERROR` lines.
* **`ScreenRecording`** — Operata's component on the telemetry entries the parser creates. These only exist when screen recording telemetry is enabled on your group.
The parser matches five lifecycle patterns and turns each into a telemetry entry with `component: "ScreenRecording"`:
| Log line contains | Entry `text` | Captured in `data` |
| - | - | - |
| `New recording` | `New recording` | `contactId`, `screenRecordingEnabled`, `screenRecordingId` |
| `PUT S3Upload for recording` | `PUT S3Upload for recording` | `blockNumber`, `blockStatus`, `contactId` |
| `Detected ended contact` (with a JSON payload) | `Detected ended contact - recording end contact object` | The contact summary object |
| `Detected ended contact` (with a JSON payload) | `Detected ended contact - recording end task objects` | `recordingTaskObjs`, `contactId` |
| `Received CCP ContactRefreshed event for contact`, or `TAPS.RECORDING.SIGNAL` | The raw log line | `contactId` |
Each entry joins the CCP log stream the Collector already ships, carrying the contact ID, a timestamp, and the standard vendor fields. Operata builds the per-contact screen recording summary server-side from those entries.
```
Amazon Connect flags contact for screen recording
→ CCP creates a recording, client app uploads parts
→ Streams logs each transition at INFO
→ Agent Collector parses matching lines
→ ScreenRecording telemetry entries in the CCP log stream
→ Operata assembles the per-contact summary
```
The parser reads `INFO` entries only, so screen recording warnings and errors stay ordinary CCP log lines rather than becoming `ScreenRecording` telemetry. The lifecycle payloads come from Amazon's log text, so their shape follows the Streams library, not an Operata contract.
## What's collected
### Recording start
Emitted when the CCP creates a recording.
| Name | Type | Description | Example |
| - | - | - | - |
| `contactId` | string (UUID) | The contact the recording belongs to. | `04ea96b3-454f-4f65-9767-784e2e99b694` |
| `screenRecordingEnabled` | boolean | Always `true` on this entry — its presence is the signal that recording started. | `true` |
| `screenRecordingId` | string (UUID) | The recording the CCP created. | `69ee35e5-faf5-425c-a727-8a15cd151fe9` |
### Part upload
Emitted once per block the client app pushes to S3. Counting these entries tells you how much of the recording left the workstation.
| Name | Type | Description | Example |
| - | - | - | - |
| `blockNumber` | integer | The block this upload covers. | `1` |
| `blockStatus` | string | Upload outcome as reported in the log line. | `SUCCESS` |
| `contactId` | string (UUID) | The contact being recorded. | `04ea96b3-454f-4f65-9767-784e2e99b694` |
### End of contact
When the contact ends, the CCP logs a summary the parser splits into two entries: the contact object, and the array of recording task objects.
Contact object:
| Name | Type | Description |
| - | - | - |
| `agentId` | string (UUID) | The Amazon Connect agent handling the contact. |
| `contactId` | string (UUID) | The contact the recordings belong to. |
| `initialContactId` | string (UUID) | The first contact in the chain. Differs after a transfer. |
| `contactState` | string | Contact state at assembly, such as `ENDED`. |
| `contactType` | string | Channel of the contact, such as `VOICE`. |
| `contactStartTimeMillis` | integer (epoch ms) | When the contact started. |
| `contactEndTimeMillis` | integer (epoch ms) | When the contact ended. |
| `contactLastKnownTimeMillis` | integer (epoch ms) | Last contact state the CCP observed. |
| `recordingTasks` | array of string (UUID) | Recording task IDs for this contact. An empty array means the CCP created none. |
Each entry in `recordingTaskObjs`:
| Name | Type | Description |
| - | - | - |
| `recordingId` | string (UUID) | The recording task. Matches an ID in `recordingTasks`. |
| `recordingStatus` | string | Terminal state of the recording, such as `SUCCEEDED` or `FAILED`. |
| `recordingStartTimeMillis` | integer (epoch ms) | When capture started. |
| `recordingEndTimeMillis` | integer (epoch ms) | When capture stopped. |
| `recordingLastKnownTimeMillis` | integer (epoch ms) | Last recording state the CCP observed. Runs past `recordingEndTimeMillis` while final parts upload. |
| `totalRecordingBlocks` | integer | Blocks the client app captured. |
| `totalSizeInBytes` | integer | Total captured size. |
| `numOfPartsUploaded` | integer | Parts the client app uploaded. Compare against `totalRecordingBlocks`. |
| `latestPartNumReceived` | integer | Highest part number the service acknowledged. |
| `isLastPartReceived` | integer | `1` once the final part is acknowledged, `0` until then. |
The Collector passes these through from Amazon's payload without transforming them. Treat the Amazon Connect documentation as the authority on their exact semantics.
## Reading the result
Compliance reporting asks three questions of each contact.
| Question | Where to look | Healthy |
| - | - | - |
| Did recording start? | A `New recording` entry for the contact | Present, with a `screenRecordingId` |
| Did parts upload? | `PUT S3Upload for recording` entries | One per block, each with a successful `blockStatus` |
| Did it complete? | `recordingStatus` in `recordingTaskObjs`, plus `numOfPartsUploaded` against `totalRecordingBlocks` and `isLastPartReceived` | `SUCCEEDED`, counts match, `isLastPartReceived` is `1` |
The case to chase is a contact with a `New recording` entry and no upload entries behind it. Recording started and produced nothing.
## Failure signatures
**Recording started, nothing uploaded.** A `New recording` entry, then an end-of-contact entry, with no `PUT S3Upload for recording` entries between them. The Amazon Connect client app is missing, not running, or blocked on that workstation. This is the most common cause, and it usually points at an endpoint deployment problem across the estate rather than a per-agent fault.
**Recording never started.** The contact was flagged in Amazon Connect, but no `New recording` entry exists and `recordingTasks` comes back empty in the end-of-contact object.
**Partial upload.** Upload entries exist but stop short — `numOfPartsUploaded` trails `totalRecordingBlocks`, or `isLastPartReceived` stays `0`. The workstation lost the network or the app died mid-contact.
Amazon also logs screen recording problems at `WARN` and `ERROR` — stale recording state, recordings marked `FAILED`, contacts dropped for having no recording task. Those lines are not captured as `ScreenRecording` telemetry, because the parser only reads `INFO` entries. They do appear in the raw CCP logs under `component = screenRecorder` when your capture level includes them. Pull the full log for the agent and time range from [Calls and logs](/docs/help/calls-and-logs) and read it with the [CCP log parser](/docs/help/amazon-connect-log-parser).
## Privacy
Operata reads screen recording metadata out of CCP log text. It does not access the recordings themselves — no video, no frames, no screen content, and no access to the S3 bucket the recordings land in. Every field above is parsed from a log line. The Collector has no media path and no S3 credentials.
## Limits
Collection works today. The reporting layer on top of it is still being built.
* **Off by default.** Screen recording telemetry needs Operata to enable the flag on your group. It is not automatic on upgrade.
* **No packaged coverage dashboard.** Operata does not yet ship a screen recording coverage report or a "recording failed" insight. Reach the data through CCP logs and custom dashboards. The packaged report — flagged, recorded, and transmitted as contact attributes visible in Canvas — is on the roadmap.
* **Not in the MCP trace schema.** The [Operata MCP Server](/docs/guides-mcp-intro) exposes the underlying softphone logs through `agent_logs` and `traces_span_logs`, so an AI client can read the raw lifecycle entries. The normalized screen recording summary is not yet part of the CX trace schema, so you can't query it as a structured field.
* **Warnings and errors aren't tagged.** The parser reads `INFO` entries only, so Amazon's screen recording `WARN` and `ERROR` lines stay in the raw log stream rather than becoming screen recording telemetry.
* **Retention on the summary data differs from log retention.** Confirm the current window with Operata support before you build a reporting process on it.
* **Operata can't see whether the client app is installed.** It observes what the CCP logs. A missing client app is an inference from the failure pattern, not a direct reading.
* **Payload shape follows Amazon.** The end-of-contact fields come from the Streams log text and can change when AWS changes the library.
## Related
* [Agent Collector](/docs/collector-overview) — the browser-side collector that captures this data.
* [CCP error logs](/docs/ccp-error-logs) — the other log stream the Collector attaches to each contact.
* [Tools and logs](/docs/diagnose-tools-and-logs) — getting raw logs out of Operata.
* [Data collection — Amazon Connect](/docs/resources-data-collection-amazon-connect) — the full collection picture for Amazon Connect.
* [Amazon Connect screen recording](https://docs.aws.amazon.com/connect/latest/adminguide/faq-screenrecording.html) — AWS requirements and setup.
# Collect
Source: https://docs.operata.com/docs/signal-overview
Collection is where Operata data starts. Four collection types run in the agent's browser and in the cloud, emit timestamped measurements, and apply your redaction policy before anything crosses the boundary to Operata.
Collection is where Operata data starts. Collectors run where the data is made — in the agent's browser and in the cloud — and emit [signals](/docs/concepts-signals-and-observations): single timestamped measurements of what happened.
## How it works
Four collection types feed Operata. Each covers measurements the others can't produce. Two read the real traffic your contact center handles; two generate synthetic traffic so you find a fault before a customer does.
| Collection type | Runs in | Emits |
| - | - | - |
| [Cloud Collector](/docs/concepts-cloud-collection) | Your cloud account, or Operata's, depending on the platform | Contact records from your platform's own event stream |
| [Cloud Synthetics](/docs/concepts-cloud-orchestrator) | Your AWS account, on Amazon Connect | Results of [Heartbeat](/docs/heartbeat-setup) checks and [Virtual Agent](/docs/virtual-agent) calls placed through your contact flow |
| [Agent Collector](/docs/collector-overview) | The agent's browser | Headset audio levels, network quality, microphone state, page focus, softphone CTI events |
| [Agent Synthetics](/docs/help/agent-readiness-test) | The agent's browser | Results of a readiness test the agent runs on demand against their own device, network, and browser |
Synthetic contacts carry the same signals a real contact does, so they land as observations on a contact and raise the same insights.
Signals flow one way. A collector emits, Operata ingests, and nothing downstream reaches back to change what a collector reports.
## Why redaction runs here
The collectors run inside your boundary, so your [redaction policy](/docs/privacy-and-redaction-overview) applies before any data leaves it. A field you redact is never transmitted, which means Operata never stores it and the API never returns it. Redaction at the collector is the only place that guarantee holds.
## Platform specifics
What each collector reads depends on the platform you run.
* [Amazon Connect](/docs/integrations-amazon-connect-overview) — Contact Trace Records (CTRs) from Kinesis, conversational analytics output, and contact-flow logs.
* [Genesys Cloud](/docs/genesys-overview) — conversation records and analytics.
* [NICE CXOne](/docs/integrations-nice-cxone-overview) — interaction records.
## Related
* [What cloud collection adds](/docs/cloud-collection-benefits) — why browser data alone leaves gaps.
* [Choose your integration](/docs/integrations-overview) — the platforms Operata collects from.
* [Collection frequency](/docs/resources-data-collection-frequency) — how often each collector reports.
* [Data collection — Amazon Connect](/docs/resources-data-collection-amazon-connect) — the field-level coverage for Amazon Connect.
* [Privacy and redaction](/docs/privacy-and-redaction-overview) — what you can suppress, and where.
* [Monitor](/docs/core-overview) — what happens to a signal after collection.
# Assure
Source: https://docs.operata.com/docs/surface-overview
Surface is the application layer — the dashboards, synthetic assurance, and account controls that put observations and insights in front of a person.
Surface is the application layer. It reads the observations and insights [Monitor](/docs/core-overview) produces and puts them in front of a person — never a raw signal.
## How it works
Three things sit on Surface.
* **Dashboards.** The Operata app renders contacts, agents, cohorts, logs, and the [insights](/docs/insights-overview) raised against them. The [User Guides](/docs/help/getting-started) cover every dashboard page by page.
* **Synthetics and assurance.** [Heartbeat](/docs/heartbeat-setup) places synthetic test calls into your contact center on a schedule, and the [Virtual Agent](/docs/virtual-agent) answers them, so you measure the path end to end without waiting for a real customer to hit the fault.
* **Account and access.** [Single sign-on](/docs/guides-request-sso), groups, and teammate permissions control who sees what.
## Why synthetics sit alongside dashboards
A dashboard tells you what happened on the contacts you had. A synthetic tells you what would happen on the next one. Running both on the same observation model means a Heartbeat result and a real contact are compared like for like — same fields, same insights, same thresholds — so a synthetic failure points at the same root cause a live contact would.
## Related
* [Insights overview](/docs/insights-overview) — what the dashboards raise and why.
* [Set up Heartbeat](/docs/heartbeat-setup) — the routing profile, contact flow, and number that drive synthetic calls.
* [User Guides](/docs/help/getting-started) — dashboard-by-dashboard help for end users.
* [Build](/docs/api-getting-started) — the same data over the API, for when a dashboard is not the destination.
# System CPU and memory usage
Source: https://docs.operata.com/docs/system-resources
CPU idle/used percentages and memory available/total for the agent endpoint, sampled by the Agent Collector across each Amazon Connect Contact.
The `system` object reports CPU and memory usage on the agent endpoint for one Amazon Connect Contact. The Agent Collector samples these metrics throughout the Contact and writes the summary when the Contact disconnects.
## Schema
```json theme={null}
{
"system": {
"cpu": {
"idlePercentage": 94.58,
"usedPercentage": 5.42
},
"memory": {
"available": 38.17,
"total": 64
}
}
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `system.cpu.idlePercentage` | number | yes | CPU idle percentage averaged across the Contact. | `94.58` |
| `system.cpu.usedPercentage` | number | yes | CPU used percentage averaged across the Contact. | `5.42` |
| `system.memory.available` | number | yes | Memory available at the end of the Contact, in gigabytes. | `38.17` |
| `system.memory.total` | number | yes | Total machine memory, in gigabytes. | `64` |
## Notes
* CPU percentages are averages across all samples taken during the Contact.
* Memory values are in gigabytes. `system.memory.available` is the snapshot at Contact end; `system.memory.total` reflects physical RAM and doesn't change across contacts on the same machine.
# How Tenor works
Source: https://docs.operata.com/docs/tenor-overview
Tenor is the agentic layer over Operata CX observability data — a CX AI agent that works for people and for other AI agents.
Tenor is the action layer. It's a CX AI agent that works for people and for other AI agents, delivered where teams already are — Slack, Teams, and the Operata Platform.
## How it works
Tenor splits by audience.
| Audience | What Tenor does |
| - | - |
| IT teams | Autonomous root cause analysis and resolution, delivered as an agent in Slack and Teams. |
| Ops teams | Plain-language analysis and charting across platforms. |
| Human agents | Readiness testing, real-time issue prevention, problem resolution, and technical guidance at the agent desktop. |
Tenor reaches you two ways: in the Operata console, and through your own AI assistant or agents. The [Operata MCP Server](/docs/guides-mcp-intro) exposes Tenor and its source data — contacts, insights, analytics, and the knowledge base — to AI clients over the Model Context Protocol (MCP), so an agent queries your live CX data with the same model the dashboards and the API use.
## Related
* [How Operata works](/docs/get-started-architecture) — the five capability layers, Tenor included.
* [Operata MCP Server](/docs/guides-mcp-intro) — the shipped surface for AI tooling.
* [Tenor for human agents](/docs/help/agent-copilot) — the agent-desktop widget.
# Deploy the Operata AWS stacks with Terraform
Source: https://docs.operata.com/docs/terraform-deployment
Deploy the Operata Cloud Collector v3 stacks into your AWS account using Operata's pre-synthesized Terraform JSON files.
Deploy the full suite of Operata Cloud Collector v3 stacks with Terraform.
Operata publishes pre-synthesized Terraform JSON files (`.tf.json`) — you
download one file per stack, set a handful of variables, and run
`terraform apply`. You need Terraform and AWS credentials, nothing else. There's
no CDK, npm, or other build tooling involved.
Before you start, know that:
* Each stack takes around 5–15 minutes to deploy.
* Terraform state is stored locally by default. For team environments, configure
a remote backend (S3, for example) before you deploy.
* Keep your Operata API key out of version control — pass it inline or store it
in a secrets manager.
## Before you start
| Requirement | Notes |
| - | - |
| Terraform | v1.8 or later — [install guide](https://developer.hashicorp.com/terraform/install). The templates don't set `required_version`, so an older CLI isn't blocked, but Operata tests against 1.8 and up. |
| AWS provider | Pinned to exactly `5.100.0` in `required_providers`, not a range. If you run a provider mirror or an air-gapped registry, stock that version before you run `terraform init`. |
| AWS credentials | In the target account, with permission to create IAM, Lambda, Kinesis, EventBridge, Secrets Manager, and CloudWatch Logs resources — and, for `clrules`, CloudFormation and Amazon Connect rule resources |
| Operata Group ID | [How to find your Operata Group ID](/docs/help/how-to-find-my-operata-group-id) |
| Operata API key | [How to create an API key](/docs/api-authentication) |
| Terraform templates | Download one per stack from [Available stacks](#available-stacks) below. |
## Available stacks
Stacks are independent — deploy them in any combination.
| Stack | What it collects | Template | VPC variant |
| - | - | - | - |
| Contact Trace Records (CTR) | CTR data from your Amazon Connect Kinesis stream | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-trace-records.tf.json) | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-trace-records-vpc.tf.json) |
| Contact Lens Data (CLD) | Conversational analytics output from S3 | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-data.tf.json) | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-data-vpc.tf.json) |
| Contact Flow Logs (CFL) | Contact flow logs from CloudWatch | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-flow-logs.tf.json) | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-flow-logs-vpc.tf.json) |
| Lex V2 Logs | Lex V2 conversation logs from CloudWatch | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-lexv2-logs.tf.json) | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-lexv2-logs-vpc.tf.json) |
| Contact Lens Rules (CLR) | Real-time and post-call conversational analytics rules, deployed into your Amazon Connect instance via nested CloudFormation stacks | [Download](https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-rules.tf.json) | — |
Choose a VPC variant only if your AWS account requires Lambda functions to run
inside a VPC — typically enterprise or regulated environments. VPC variants
take two extra variables: a VPC ID and a list of private subnet IDs. If you're
not sure which you need, ask whoever manages your AWS account. The standard
(non-VPC) variant is usually the right choice.
## Deploy a stack
Deploy only the stacks you need, in any order. Each section below is a
complete, ready-to-run deploy block. Fill in your own values — Group ID, API
key, ARNs, and log group names — before you run it.
Resource names are fixed. Every template hard-codes `prod` into its secret
names, resource names, and — for `clrules` — its CloudFormation stack name.
There's no environment variable to set. Deploying the same stack twice into
one AWS account and region collides on those names.
### Contact Trace Records (CTR)
```bash theme={null}
mkdir -p ~/operata/ctr
cd ~/operata/ctr
curl -O https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-trace-records.tf.json
cat > terraform.tfvars < terraform.tfvars < terraform.tfvars < terraform.tfvars <`. Find yours in the CloudWatch
console, or see [Contact flow logs](/docs/contact-flow-logs).
```bash theme={null}
mkdir -p ~/operata/cfl
cd ~/operata/cfl
curl -O https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-flow-logs.tf.json
cat > terraform.tfvars < terraform.tfvars < terraform.tfvars < terraform.tfvars < terraform.tfvars < \
--publish-status PUBLISHED \
--query 'RuleSummaryList[?starts_with(Name, `operata_`)] | length(@)'
```
To remove the stack, run `terraform destroy`. `clrules` creates no AWS Secrets
Manager secrets, so no force-deletion step is required afterwards.
## Verify
### 1. Place a test contact
Make or receive a short test call in your Amazon Connect instance. On an inbound
call, **close the contact** before you check for data, or it won't appear. Data
can take up to five minutes to reach Operata after the call ends.
### 2. Check API activity
Open **Group Settings → Integrations → API Management** and look for a recent
**Last Used** timestamp on the API key.
* **Recent activity** — your stack is sending data. Continue to step 3.
* **No recent activity** — stop here. Check that `operata_api_key` and
`operata_group_id` in your `terraform.tfvars` match your Operata account, then
test again. If there's still no activity, contact Operata support.
### 3. Check the data view for your stack
* **CTR** — open **Calls and Logs → Details / Summary** and confirm the test
call appears.
* **Contact Lens (CLD)** — open **Dashboards → Conversational Analytics** and
confirm data appears. Filter by the test agent's name or sort by most recent
call.
If nothing appears after 10 minutes, work through
[Troubleshooting](#troubleshooting).
## Upgrade an existing stack
To apply a newer Operata release to a stack you've already deployed:
1. Download the new `.tf.json` file into the same working directory, replacing
the previous file. Filenames carry no version tag, so the latest release is
always at the same URL.
2. Run `terraform plan` and confirm only the expected resources change —
typically the Lambda zip key and a few metadata fields.
3. Run `terraform apply`.
If unexpected resources appear in the plan, contact Operata before you
continue.
State in the working directory tracks resource identity, so the upgrade happens
in place. Terraform doesn't replace the EventBridge pipe, the Kinesis stream, or
the IAM resources. For `clrules`, `terraform apply` triggers a CloudFormation
stack update on the nested `operata-contact-lens-rules-prod` stack, which diffs
and updates only the changed rules.
Each stack upgrades independently. Collection pauses for roughly 2–5 minutes per
stack while the apply runs, and calls handled in that window don't reach
Operata — so schedule upgrades outside peak contact center hours where you can.
## Redeploy after a destroy
AWS Secrets Manager schedules secrets for deletion with a 30-day recovery
window — `terraform destroy` doesn't remove them immediately. Run
`terraform apply` again before that window expires and the apply fails with:
```
InvalidRequestException: You can't create this secret because a secret with this name is already scheduled for deletion.
```
To unblock an immediate redeploy, force-delete the affected secrets after the
destroy:
```bash theme={null}
aws secretsmanager delete-secret \
--region ap-southeast-2 \
--secret-id /cloud-collector-v3/ctr/apiToken-prod \
--force-delete-without-recovery
```
`--force-delete-without-recovery` removes the secret permanently. Use it only
when you intend to recreate it immediately.
Secrets created per stack:
| Stack | Secrets |
| - | - |
| `clrules` | None |
| CTR | `/cloud-collector-v3/ctr/apiToken-prod` |
| CLD | `/cloud-collector-v3/cld/apiToken-prod` |
| CFL | `/cloud-collector-v3/cfl/apiToken-prod`, `/cloud-collector-v3/cfl/redactionPolicyCache-prod` |
| Lex V2 Logs | `/cloud-collector-v3/lex/apiToken-prod`, `/cloud-collector-v3/lex/redactionPolicyCache-prod` |
## Troubleshooting
Work through these before you contact Operata support.
**EventBridge Pipe fails to create on the first apply.** This is an IAM
eventual-consistency issue. The role and policies are created correctly, but
EventBridge runs an upfront access check before IAM has finished propagating.
Run `terraform apply` again — Terraform leaves the role in place and retries
only the pipe.
**Secret already scheduled for deletion.** Force-delete the affected secrets
from the CLI (see [Redeploy after a destroy](#redeploy-after-a-destroy)), then
apply again.
**CLD deploys cleanly but no data appears in Operata.** The EventBridge Pipe
shows `RUNNING` but no conversational analytics summaries arrive. Check that conversational analytics is
enabled on your Amazon Connect instance and that calls run with conversational analytics
analysis turned on.
**Terraform `inline_policy` deprecation warning.** Terraform may print a
deprecation warning on `aws_iam_role.inline_policy`. It's a provider-level
notice. The configuration applies cleanly and the warning has no functional
impact.
## Get help
If you hit an issue, or you're not sure which stacks or environment apply to
your setup, email [help@operata.com](mailto:help@operata.com) or send a message
from inside the Operata app.
## Related
* [Install CTR collection](/docs/ctr-installation) — the CloudFormation path for the same collector.
* [Install conversational analytics](/docs/conversational-analytics-installation) — conversational analytics prerequisites and configuration.
* [IAM policies](/docs/iam-policies) — the permissions each stack needs.
* [Troubleshoot the integration](/docs/aws-troubleshooting) — missing records, deployment failures, secret management.
# Deploy the Heartbeat Virtual Agent
Source: https://docs.operata.com/docs/virtual-agent
Deploy the Heartbeat Virtual Agent on Amazon ECS Fargate so it can log in to Amazon Connect and answer synthetic Heartbeat calls.
Deploy the Heartbeat Virtual Agent — a containerized Amazon ECS Fargate
service — into your AWS account so it logs in to Amazon Connect under a
dedicated user and answers synthetic Heartbeat calls.
## Before you start
* [Cloud Orchestrator installed](/docs/orchestrator-installation) in
the same AWS region as your Amazon Connect instance.
* [Heartbeat set up](/docs/heartbeat-setup) — routing profile, contact
flow, and dedicated phone number all in place.
* An [Operata account](/docs/get-started-overview) with Admin role and
your Operata Group ID.
* An Operata-supplied Virtual Agent CloudFormation template URL.
Contact [Operata Support](mailto:support@operata.com) for the link.
* Amazon Connect administrator access — you create a dedicated user
for the Virtual Agent in step 2.
* If your Amazon Connect instance uses Single Sign-On (SSO), confirm
the IDP provider with Operata (Azure is common) and have a Virtual
Agent login provisioned in that IDP. Including `operata-virtual-agent`
in the username helps identify the user later.
**The Virtual Agent does not support agent login with MFA.**
Create the agent without MFA. Any configuration that later enforces
MFA — for example, Azure Security Defaults — must exclude this user.
Heartbeat calls fail as soon as MFA is enforced on the Virtual Agent
login.
## Steps
### 1. Confirm SSO details with Operata (SSO only)
If your agents sign in via SSO, send Operata your IDP provider name
and the Virtual Agent username you provisioned. Skip this step for
non-SSO instances.
You can run more than one Virtual Agent — each one needs its own
unique login.
### 2. Create the Virtual Agent user in Amazon Connect
Sign in to the Amazon Connect console and open **User Management**,
then **Add new users → Create and set up a new user**.
Configure the user:
* **Non-SSO:** set the login name `operata-virtual-agent` and a
password — you paste this password into the CloudFormation parameters
in step 4.
* **SSO:** create an agent login that meets your IDP's requirements.
**Do not assign the `Operata_Heartbeat_RP` routing profile to this
user.**
The Virtual Agent receives calls outside the routing profile system.
Assigning `Operata_Heartbeat_RP` to the Virtual Agent prevents the
agent from logging in and breaks Heartbeat.
Save the user. Verify the user details on the confirmation screen,
then **Create users**.
### 3. Open the Virtual Agent CloudFormation template
In the AWS console, open **CloudFormation** in the same region as your
Amazon Connect instance, then choose **Create stack → With new
resources (standard)**.
Select **Amazon S3 URL**, paste the template URL Operata supplied, and
click **Next**.
### 4. Enter the stack parameters
Provide:
| Parameter | Value |
| - | - |
| `APIKey` | The Operata API token created when you deployed Cloud Orchestrator. |
| `AgentPassword` | The password you set in step 2 (non-SSO), or the IDP password for the Virtual Agent user (SSO). |
| `AgentUsername` | The username you created in step 2. |
| `CCPUrl` | The Amazon Connect CCP URL for your instance. Do not use a custom CCP URL. |
| `LoginUrl` | SSO only — the URL the agent client redirects to for SSO sign-in. |
| `OperataAPIUrl` | Leave at the default `https://api.operata.io`. |
| `OperataGroupID` | Provided by Operata. |
| `SubnetIDs` | VPC subnets allowed for ECS task deployment. |
| `VPCID` | The VPC ID to deploy the ECS cluster into. |
Click **Next**.
### 5. Review and create the stack
Click through **Next** on the stack-options screen. On the **Review
and create** screen, acknowledge IAM resource creation and click
**Create stack**. The stack reaches `CREATE_COMPLETE` in around 10
minutes.
### 6. (SSO only) Confirm the SSO provider on the Operata side
The SSO provider on your Operata account must match the IDP the
Virtual Agent signs in to. Operata configures this — contact
[Operata Support](mailto:support@operata.com) if you set up SSO for
the first time. You can confirm the current setting at **Settings →
Config → SSO** in the Operata console.
### 7. (Optional) Tag the new resources
Apply your cost-allocation and ownership tags. See [Tag your AWS
resources](/docs/aws-tagging) for the tag set Operata expects.
## Verify
In the Amazon Connect console, open **Real-time metrics → Agents**.
The Virtual Agent user appears as logged in within five minutes of the
ECS task starting.
Run a Heartbeat test from the Operata console — the test call dials
the Heartbeat phone number, the Virtual Agent answers, and the run
result appears on the [Operata console](https://app.operata.io) and
on your EventBridge bus.
If the Virtual Agent does not appear logged in, see
[Virtual Agent troubleshooting](/docs/virtual-agent-troubleshooting).
## Related
* [Virtual Agent troubleshooting](/docs/virtual-agent-troubleshooting) —
diagnose stuck tasks, failed logins, and ECS task crashes.
* [Concept: Cloud Orchestrator](/docs/concepts-cloud-orchestrator) —
the runtime the Virtual Agent answers calls inside of.
* [EventBridge](/docs/concepts-eventbridge) — receive each Heartbeat
run's result on your event bus.
* [Request SSO](/docs/guides-request-sso) — the broader SSO setup if
you configure SSO across Operata.
# Troubleshoot the Virtual Agent
Source: https://docs.operata.com/docs/virtual-agent-troubleshooting
Diagnose and fix a Heartbeat Virtual Agent that is not running, not logged in to Amazon Connect, or failing to answer synthetic calls.
The Heartbeat Virtual Agent fails in three common ways: the Amazon ECS task is not running, the agent is not logged in to Amazon Connect, or the agent credentials cannot be authenticated manually. Start at the section that matches your symptom.
## Before you start
* Admin access to the AWS account hosting the [Cloud Orchestrator](/docs/concepts-cloud-orchestrator) and the Virtual Agent stack.
* The Virtual Agent CloudFormation stack name and the Amazon Connect instance it is bound to.
* The `AgentUsername` and `AgentPassword` you set when you deployed the [Virtual Agent stack](/docs/virtual-agent).
## The Virtual Agent task is not running
### 1. Open the Virtual Agent CloudFormation stack
In the AWS console, open **CloudFormation** and select the Virtual Agent stack. Open the **Resources** tab and click the physical ID of the ECS service.
### 2. Check deployments and tasks
The ECS service detail page shows **Deployments and tasks**. A healthy service shows `1/1` — one task running out of one desired.
If the count is `0/1`, the task is stopped or failing to start. Continue to step 3.
### 3. Inspect the failing task
Open the **Tasks** tab on the service. Click into the most recent task. The **Stopped reason** and **Containers** sections explain why the task exited.
The most common causes:
* **Image pull failure** — the task can't reach the Operata container registry. Confirm the VPC the stack deploys into has outbound internet access (NAT gateway or VPC endpoints).
* **Insufficient task CPU or memory** — bump the task definition's resource allocation and update the service.
* **Container exit on startup** — the agent crashed before logging in. Continue to "The Virtual Agent is not logged in" below to read the logs.
You can stop and start the Virtual Agent from this view by updating the service's desired task count.
## The Virtual Agent is not logged in
The fastest check is the Amazon Connect console — the real-time agent metrics show the Virtual Agent as logged in once login succeeds. If the metrics show the agent offline, read the ECS logs.
### 1. Open the Virtual Agent ECS service
In the AWS console, open **CloudFormation** and select the Virtual Agent stack. Under **Resources**, expand the `VirtualAgent` resource and click through to the ECS cluster the stack created.
### 2. Open the logs
Click the service — named `VirtualAgent` — and select the **Logs** tab. The log lines describe the login flow:
| Log line | Meaning |
| - | - |
| `Logging in using native CCP` | Non-SSO login attempt. |
| `Logging in using SSO Provider: ` | SSO login attempt. |
| `logged in successfully` | Login succeeded. The agent is ready to answer Heartbeat calls. |
| `Failed to login` | Login failed. The Virtual Agent retries; multiple failures may appear before a success. |
A long-running service may also show repeated `logged in successfully` entries from session refreshes — that is normal.
### 3. Match the failure to a cause
| Failure line near a `Failed to login` | Likely cause | Recovery |
| - | - | - |
| `Authentication failed` (non-SSO) | The `AgentPassword` is wrong, or the user is disabled in Amazon Connect. | Reset the password in Amazon Connect, redeploy the stack with the new value. |
| `Authentication failed` (SSO) | The IDP rejected the credentials, or MFA is enforced. | Confirm the IDP login works in a browser. Exclude the user from MFA enforcement. |
| `Timed out waiting for CCP` | The VPC can't reach the CCP URL, or the URL is wrong. | Confirm `CCPUrl` matches the Amazon Connect instance and is reachable from the VPC. |
| `Routing profile not allowed` | The user has `Operata_Heartbeat_RP` assigned. | Remove the routing profile from the Virtual Agent user. |
## The Virtual Agent ID cannot be authenticated manually
The third step is to confirm the Virtual Agent's credentials work outside ECS — this isolates Amazon Connect or IDP issues from ECS networking issues.
### 1. Non-SSO instances
Open the Amazon Connect CCP URL in a browser. Sign in with the `AgentUsername` and `AgentPassword` you set in the Virtual Agent CloudFormation stack. The agent should reach the **Ready** state.
If sign-in fails, reset the password in Amazon Connect and redeploy the Virtual Agent stack with the new `AgentPassword`.
### 2. SSO instances
Open the `LoginUrl` you set in the Virtual Agent stack in a browser. Sign in with the `AgentUsername` and the IDP password for that user. The agent should redirect to Amazon Connect and reach **Ready**.
If sign-in fails:
* The IDP login is broken — fix it in the IDP first.
* MFA is enforced on the Virtual Agent user — exclude the user from MFA enforcement (for example, in Azure Security Defaults).
## Verify
Run a Heartbeat test from the Operata console. The test call dials the Heartbeat phone number, the Virtual Agent answers within seconds, and the run completes within the Heartbeat call duration (typically under 30 seconds). The run appears on the [Operata console](https://app.operata.io) and on your EventBridge bus.
If the Virtual Agent still does not answer after working through this page, contact [Operata Support](mailto:support@operata.com) with the ECS service ARN, the most recent task ID, and the relevant log extract.
## Related
* [Deploy the Heartbeat Virtual Agent](/docs/virtual-agent) — redeploy the stack if you changed parameters.
* [Set up Heartbeat](/docs/heartbeat-setup) — confirm the routing profile, contact flow, and phone number bindings.
* [Concept: Cloud Orchestrator](/docs/concepts-cloud-orchestrator) — the runtime the Virtual Agent answers calls inside of.
* [Troubleshoot the AWS integration](/docs/aws-troubleshooting) — for CTR and Amazon EventBridge-related failures on the same AWS account.
# Configure the VPN bypass URL
Source: https://docs.operata.com/docs/vpn-bypass
Route the Operata lookup endpoint outside your VPN tunnel so Operata records each agent's true ISP and network location, not the VPN provider's exit address.
Route the Operata lookup endpoint outside your VPN tunnel so Operata records each agent's true ISP and network location — not the VPN provider's exit address.
## Before you start
* An [Operata account](/docs/get-started-overview) with Admin role.
* [Agent Collector](/docs/collector-overview) installed on each agent endpoint.
* Admin access to your VPN client configuration — Zscaler, Cisco AnyConnect, Palo Alto GlobalProtect, or equivalent — and the authority to add a split-tunnelling rule.
## Why VPN routing hides agent location
When agents work behind a VPN, all traffic flows through the VPN provider's exit. To Operata, every agent looks like the VPN provider — the same IP, the same ISP, the same geolocation. ISP-specific connectivity issues become invisible.
Operata exposes a single lookup endpoint that returns the requesting device's true public IP. The Agent Collector calls this endpoint at the start of each session. If your VPN routes that endpoint through the tunnel, the response carries the VPN exit IP instead of the agent's true network identity.
## Steps
### 1. Add a split-tunnelling rule
In your VPN client's split-tunnelling configuration, route the host `agent-service.operata.io` — specifically `https://agent-service.operata.io/lookup` — through the local network instead of the VPN tunnel. The host serves only the lookup endpoint and returns no business data.
### 2. Roll out the rule to agent endpoints
Push the updated VPN policy to every agent endpoint through your existing device-management tooling. The change takes effect on the next VPN session.
### 3. Place a test contact
Have an agent reconnect the VPN, open the contact center softphone, and place a test contact end to end.
## Verify
Visit `https://agent-service.operata.io/lookup` directly in a browser on the agent endpoint while the VPN is connected. The response returns the agent's local public IP, not the VPN provider's exit address.
In the Operata console, open the test contact and check **Network Details**. The `AgentIP` field shows the local public IP and the `AgentISP` field shows the agent's actual ISP, not the VPN provider.
The lookup endpoint returns only the requesting device's IP. No business data, customer data, or call metadata passes through it.
## Related
* [Agent Collector](/docs/collector-overview) — The extension that calls the lookup endpoint per session.
* [Chrome extension](/docs/chrome-extension) — Install the Collector on Chrome.
* [Edge extension](/docs/edge-extension) — Install the Collector on Edge.
* [Geolocation and ISP](/docs/geolocation-isp) — The data shape the Collector reports per contact.
# WebRTC session
Source: https://docs.operata.com/docs/webrtc-session
Packet counts, MOS (mean opinion score), jitter, RTT (round-trip time), media and signalling endpoints, setup timers, and audio devices for each Amazon Connect Contact, captured by the Agent Collector.
The `webRTCSession` object captures WebRTC (Web Real-Time Communication) session details for one Amazon Connect Contact, written by the Agent Collector when the Contact disconnects. It covers inbound and outbound packet metrics, MOS (mean opinion score), jitter, RTT (round-trip time), signalling and media endpoints, setup event timers, failure flags, and the audio devices in use.
## Schema
```json theme={null}
"webRTCSession": {
"metrics": {
"inbound": {
"packetsReceived": 2643,
"packetsLost": 0,
"packetsLostPercentage": 0,
"bytesReceived": 298621,
"audioLevel": { "max": 8191, "avg": 520.32 },
"jitterBufferMils": { "min": 1, "max": 14, "avg": 3.25 }
},
"outbound": {
"packetsSent": 2931,
"packetsLost": 52,
"packetsLostPercentage": 1.77,
"bytesSent": 247605,
"audioLevel": { "max": 18712, "avg": 6094.7 },
"jitterBufferMils": { "min": 0.19, "max": 38.73, "avg": 7.79 }
},
"rtt": { "max": 566, "avg": 122 },
"jitter": { "max": 14, "avg": 3 },
"mos": { "min": 2.52, "max": 4.43, "avg": 4.3 }
},
"serviceEndpoint": {
"fqdn": "",
"transportLifeTimeSeconds": 0,
"expiry": "0001-01-01T00:00:00Z"
},
"mediaEndpoint": {
"fqdn": "turnnlb-93f2de0c97c4316b.elb.ap-southeast-2.amazonaws.com.",
"destinationPort": "3478",
"sourcePort": "63568",
"transport": "udp",
"privateIp": "10.4.3.213"
},
"signallingEndpoint": { "fqdn": "" },
"eventTimer": {
"gumTimeMillis": 418,
"initializationTimeMillis": 445,
"iceCollectionTimeMillis": 270,
"signallingConnectTimeMillis": 2,
"handshakingTimeMillis": 473,
"preTalkingTimeMillis": 927,
"cleanupTimeMillis": 163
},
"eventFailure": {
"iceCollectionFailure": false,
"signallingConnectionFailure": false,
"handshakingFailure": false,
"gumOtherFailure": false,
"gumTimeoutFailure": false,
"createOfferFailure": false,
"setLocalDescriptionFailure": false,
"userBusyFailure": false,
"invalidRemoteSDPFailure": false,
"noRemoteIceCandidateFailure": false,
"setRemoteDescriptionFailure": false
},
"usedDevices": [
{
"timestamp": "2026-05-18T10:14:10.654Z",
"deviceId": "default",
"groupId": "ac3e3f65d873aaaabbbbbcccce1d2ccd24fd34c5d341089a66ef02589dabf06b0",
"kind": "audioinput",
"label": "Default - Elgato Wave:3 (0fd9:0070)"
}
]
}
```
## Fields
| Name | Type | Required | Description | Example |
| - | - | - | - | - |
| `metrics.inbound.packetsReceived` | integer | yes | Total RTP packets received from Amazon Connect during the Contact. | `2643` |
| `metrics.inbound.packetsLost` | integer | yes | Total inbound RTP packets lost. | `0` |
| `metrics.inbound.packetsLostPercentage` | number | yes | Inbound packet loss as a percentage. | `0` |
| `metrics.inbound.bytesReceived` | integer | yes | Total inbound bytes received. | `298621` |
| `metrics.inbound.audioLevel` | object | yes | Inbound audio level range — `max` and `avg`. | — |
| `metrics.inbound.jitterBufferMils` | object | yes | Inbound jitter-buffer delay in milliseconds — `min`, `max`, `avg`. | — |
| `metrics.outbound.packetsSent` | integer | yes | Total RTP packets sent to Amazon Connect during the Contact. | `2931` |
| `metrics.outbound.packetsLost` | integer | yes | Total outbound RTP packets lost. | `52` |
| `metrics.outbound.packetsLostPercentage` | number | yes | Outbound packet loss as a percentage. | `1.77` |
| `metrics.outbound.bytesSent` | integer | yes | Total outbound bytes sent. | `247605` |
| `metrics.outbound.audioLevel` | object | yes | Outbound audio level range — `max` and `avg`. | — |
| `metrics.outbound.jitterBufferMils` | object | yes | Outbound jitter-buffer delay in milliseconds — `min`, `max`, `avg`. | — |
| `metrics.rtt` | object | yes | Round-trip time in milliseconds — `max` and `avg`. | `{ "max": 566, "avg": 122 }` |
| `metrics.jitter` | object | yes | Jitter in milliseconds — `max` and `avg`. | `{ "max": 14, "avg": 3 }` |
| `metrics.mos` | object | yes | Estimated Mean Opinion Score — `min`, `max`, `avg`. Range 1 (worst) to 5 (best). | `{ "min": 2.52, "max": 4.43, "avg": 4.3 }` |
| `serviceEndpoint.fqdn` | string | yes | Amazon Connect service WebSocket FQDN. | `service.connect.ap-southeast-2.amazonaws.com` |
| `serviceEndpoint.transportLifeTimeSeconds` | integer | yes | Transport lifetime advertised by the service endpoint, in seconds. | `0` |
| `serviceEndpoint.expiry` | string (ISO 8601) | yes | When the service-endpoint transport expires. | `0001-01-01T00:00:00Z` |
| `mediaEndpoint.fqdn` | string | yes | Amazon Connect TURN service FQDN. | `turnnlb-93f2de0c97c4316b.elb.ap-southeast-2.amazonaws.com.` |
| `mediaEndpoint.destinationPort` | string | yes | Destination port on the TURN service. | `3478` |
| `mediaEndpoint.sourcePort` | string | yes | Source port used on the agent endpoint. | `63568` |
| `mediaEndpoint.transport` | string | yes | Transport protocol. One of `udp`, `tcp`, `tls`. | `udp` |
| `mediaEndpoint.privateIp` | string (IPv4) | yes | Private IP the agent endpoint used for media. | `10.4.3.213` |
| `signallingEndpoint.fqdn` | string | yes | Amazon Connect signalling WebSocket FQDN. | `signalling.connect.ap-southeast-2.amazonaws.com` |
| `eventTimer.gumTimeMillis` | integer | yes | `getUserMedia` call duration in milliseconds. | `418` |
| `eventTimer.initializationTimeMillis` | integer | yes | WebRTC initialization duration in milliseconds. | `445` |
| `eventTimer.iceCollectionTimeMillis` | integer | yes | ICE candidate collection duration in milliseconds. | `270` |
| `eventTimer.signallingConnectTimeMillis` | integer | yes | Signalling connection duration in milliseconds. | `2` |
| `eventTimer.handshakingTimeMillis` | integer | yes | DTLS handshake duration in milliseconds. | `473` |
| `eventTimer.preTalkingTimeMillis` | integer | yes | Time from session start to first audio in milliseconds. | `927` |
| `eventTimer.cleanupTimeMillis` | integer | yes | Session teardown duration in milliseconds. | `163` |
| `eventFailure` | object | yes | Per-stage WebRTC failure flags. Each property is a boolean; `true` means the named failure occurred during session setup or teardown. | — |
| `usedDevices` | object\[] | yes | Audio input and output devices the Contact Control Panel used during the session. Each entry has `timestamp`, `deviceId`, `groupId`, `kind`, `label`. | — |
| `usedDevices[].kind` | string | yes | Device kind. One of `audioinput`, `audiooutput`. | `audioinput` |
## Notes
* Packet and byte counts are totals for the Contact, not rates. Loss percentages are derived values.
* RTT and jitter values are in milliseconds.
* `jitterBufferMils` is the jitter-buffer delay, distinct from the raw jitter reported in `metrics.jitter`. Both are in milliseconds.
* All `eventTimer` durations are in milliseconds and measure discrete phases of WebRTC session setup and teardown.
* `eventFailure` booleans are all present on every contact record, even when no failure occurred. A value of `false` means the named stage completed without error.