# 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. Diagram of a proxy sitting between the agent's browser and the contact center cloud, inspecting traffic in both directions 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. Genesys Cloud Organization Settings 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` Creating the OPERATA_Role 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 Selecting the required permissions 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 Adding the OAuth client Click **Next**. On the role-assignment screen, toggle the **Assigned** column for the `OPERATA_Role` you created above and click **Next**. Assigning the OPERATA_Role Leave the default token duration of `86400` seconds (24 hours) and click **Save**. Token duration screen 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. Client ID and secret displayed 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. Selecting Amazon EventBridge in the Integrations catalog On the **Details** tab, set: * **Integration Name:** `Operata AWS EventBridge` Click **Save**. EventBridge integration name 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. EventBridge configuration screen 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. Event source suffix uniqueness error ### 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**. Entering the Genesys Org ID in Operata 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 Operata platform: Tenor, Surface, Core, and Signal layers over integrated sources. ## 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. Headset Inventory page showing an agent row with NC and AC indicators for noise cancellation and accent conversion **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.