02 Get your data in /Integrations
Cognigy
Send AI agent conversations from Cognigy to Dimension Labs with the universal API.
- C CognigyTickets, chats, calls, reviews
- ⟳ Your jobPull new · map fields · every 15 min
- { } Universal APIPOST /track · /trackhistorical
- Dimension LabsRead in full · enriched daily
This brings in your Cognigy.AI conversations, message by message: what each end user wrote, what the AI agent answered and what a human agent wrote after a handover. Each Cognigy session becomes one conversation. You run it on your side: a small script pulls from the Cognigy OData Analytics endpoint and posts each message to the universal API.
What you need
Section titled “What you need”- A Cognigy user with the
odataglobal role, and an API key for that user. - Your OData domain:
https://odata-trial.cognigy.aion a trial,https://odata-<your-domain>.cognigy.aion shared SaaS,https://odata-<backend-url>on premises, orhttps://cognigy-odata-<region>.nicecxone.comthrough NICE CXone. On dedicated SaaS, ask Cognigy for the URL. - Optionally, your project id, to give the job its own rate limit budget.
- A Dimension Labs API key for a new Universal API source. See Your API key.
1. Get API access in Cognigy
Section titled “1. Get API access in Cognigy”- Make sure the user has the
odataglobal role (OData authentication). An API key has the same permissions as its user. - Open My Profile: click your user icon in the upper-right corner of the Main page.
- In the API Keys section, click +, enter a name and click Confirm.
- Click the key’s value to copy it, and store it in a secrets manager. Cognigy shows it only once (My Profile).
Send the key in the apikey header. Cognigy also accepts it as a query parameter, but the header keeps it out of URLs and logs.
2. Pull new messages
Section titled “2. Pull new messages”Use the Conversations collection of OData endpoint version 2.4 (Cognigy 4.65 and later). It logs every session message from the end user, the AI agent and the human agent, one record per message:
curl -H "apikey: $COGNIGY_API_KEY" \ "https://odata-trial.cognigy.ai/v2.4/Conversations?\$filter=timestamp%20ge%20'2026-10-01T00:00:00.000Z'&\$orderby=timestamp%20asc&\$top=1000"- Dates are ISO 8601 in UTC, in single quotes.
$filter,$orderby,$top,$skipand$selectare supported, and each may appear only once in a URL. - High
$skipvalues can time out. Page by time instead (keyset pagination): ask again from the lasttimestampyou received. - Add
projectId eq '<project-id>'to the filter to use that project’s own request budget. - OData data isn’t updated in real time, so the code re-reads the last hour on every run.
Cognigy’s default request limits per budget: a burst of 50 requests, then 10 requests a second, with at most 4 requests at a time. Going over returns 429 with a Retry-After header in seconds (request limits).
Cognigy deletes analytics data, Conversations included, after a time to live set for your organization (data expiration). History only goes back that far.
3. Map the fields
Section titled “3. Map the fields”| Dimension Labs | Cognigy | Notes |
|---|---|---|
text | inputText | Skip records where it is empty. Skip source suggestion: those are suggestions nobody sent. |
userId | contactId | The id of the connecting user. Use it on both sides of the conversation. Fall back to the sessionId. |
incoming | source | true when source is user. bot (the AI agent) and agent (a human agent) are false. |
sessionId | sessionId | Prefix it, for example cognigy-<sessionId>. |
conversationId | sessionId | Same value as sessionId. Keeps the conversation together across a handover to a human agent. |
dimensionlabs_timestamp | timestamp | Convert with toMillis. |
platformJson | channel, flowName, projectName, endpointName, localeReferenceId, inHandoverConversation, rating, id | rating is 1 or -1 when the user rated the session. |
If an endpoint has Mask Sensitive Analytics turned on, inputText arrives masked; if Collect Analytics is off, nothing is logged at all. Version 2.4 names the record id id; version 2.3 used _id.
Personal data. Check what your channels put in contactId: if it holds a phone number or email address, use the sessionId instead. End users sometimes type names, emails or order numbers: redact them before you send, or turn on Cognigy’s own Data Redaction for the project. See PII redaction.
4. Send it
Section titled “4. Send it”// cognigy.mjs. Environment: COGNIGY_ODATA_URL (for example https://odata-trial.cognigy.ai), COGNIGY_API_KEY, COGNIGY_PROJECT_ID (optional), DL_API_KEY.import { sendToDimensionLabs, toMillis } from './dimensionlabs.mjs';
const HOUR = 60 * 60 * 1000;const PAGE = 1000;const OVERLAP = HOUR; // OData isn't real time: re-read the last hour. Duplicates are removed.const sleep = (ms) => new Promise((r) => setTimeout(r, ms));const BASE = `${process.env.COGNIGY_ODATA_URL.replace(/\/$/, '')}/v2.4/Conversations`;const PROJECT = process.env.COGNIGY_PROJECT_ID;const iso = (ms) => new Date(ms).toISOString();const safe = (s) => String(s).replace(/:/g, '-');
// Retries Cognigy's rate limits (429) and server errors (5xx), honoring Retry-After.async function get(url) { for (let attempt = 0; ; attempt++) { const res = await fetch(url, { headers: { apikey: process.env.COGNIGY_API_KEY } }); if (res.ok) return res.json(); if ((res.status !== 429 && res.status < 500) || attempt === 5) throw new Error(`Cognigy returned ${res.status}: ${await res.text()}`); await sleep((Number(res.headers.get('retry-after')) || 2 ** attempt) * 1000); }}
// Sends every message logged at or after `since` (Unix ms). Returns the new `since`.export async function syncCognigy({ since, historical = false }) { let newest = since; let from = Math.max(0, since - OVERLAP); let skip = 0; // records already read that share the `from` timestamp for (;;) { const filter = [`timestamp ge '${iso(from)}'`, PROJECT && `projectId eq '${PROJECT}'`].filter(Boolean).join(' and '); const rows = (await get(`${BASE}?$filter=${encodeURIComponent(filter)}&$orderby=${encodeURIComponent('timestamp asc,id asc')}&$top=${PAGE}${skip ? `&$skip=${skip}` : ''}`)).value ?? []; for (const r of rows) { const ts = toMillis(r.timestamp); newest = Math.max(newest, ts); if (r.source === 'suggestion' || !r.inputText?.trim()) continue; const id = `cognigy-${safe(r.sessionId)}`; await sendToDimensionLabs({ text: r.inputText, userId: r.contactId ? safe(r.contactId) : id, incoming: r.source === 'user', sessionId: id, conversationId: id, dimensionlabs_timestamp: ts, platformJson: { channel: r.channel, flow: r.flowName, project: r.projectName, endpoint: r.endpointName, locale_id: r.localeReferenceId, source: r.source, in_handover: r.inHandoverConversation, rating: r.rating, cognigy_record_id: r.id, }, }, { historical: historical || ts < Date.now() - HOUR }); } if (rows.length < PAGE) break; // Keyset pagination: continue from the last timestamp, skipping the records already read at it. const lastTs = toMillis(rows[rows.length - 1].timestamp); const atLast = rows.filter((r) => toMillis(r.timestamp) === lastTs).length; skip = lastTs === from ? skip + atLast : atLast; from = lastTs; } return newest;}5. Run it
Section titled “5. Run it”Save the code as cognigy.mjs in a project set up as in Set up your project, and run it with the scheduled sync runner: import { syncCognigy as sync } from './cognigy.mjs';.
- History first:
node run.mjs 2026-01-01sends every message since that date to/trackhistorical, as far back as your data expiration allows. Then start a backfill from the Backfill tab. - Then every 15 minutes: the scheduled job sends new messages to
/track, and they are enriched automatically every day. A message that is more than an hour old when the job sees it goes to/trackhistorical, and needs a backfill. - Re-runs are safe: duplicates are removed automatically, so the one-hour overlap on each run costs nothing but a few extra calls.
The code sends one request at a time, well inside Cognigy’s limits, and waits whenever Cognigy asks it to. The same OData feed also opens in Excel or Power BI, so you can export it to a file instead, upload the file (check it with the file checker), then run a backfill.
Cognigy reference
Section titled “Cognigy reference”Checked against Cognigy’s documentation on 2026-10-26.