> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Talkdesk calling setup

> Connect Talkdesk calls to Open sessions, link agents and contacts, and import recordings and transcripts. Use when configuring call logging and media delivery.

Talkdesk handles your calls and audio. With call-event automations enabled, Open creates one phone session per call, links the customer and handling teammate, and records the result. Recording and transcript callbacks enrich that session when media becomes available. Call-finished workflows run once; media arriving later does not rerun them.

An Open integrations administrator and a Talkdesk account administrator are needed for setup. The call and media endpoints below must be deployed before production automations use them. Saving settings in Open does not activate the custom integration or create Talkdesk automations.

## What your team needs to configure

| Where | Required setup |
| - | - |
| Open | Save the Talkdesk account, region, and integration name; create the restricted organization API key. |
| Talkdesk | Activate the Open custom integration if needed, enable embedded calling, allow the Open origin, and synchronize agents and contacts. |
| Talkdesk call automations | Publish call-event actions for both directions and the required answered and unanswered outcomes. Include linked Open agent and contact IDs when available. |
| Recordings | Enable recording in Talkdesk, create its recording OAuth client, save those credentials in Open's **Recordings** tab, and publish the recording-ready callback. |
| Transcripts | Ensure the Talkdesk account has access to voice transcription, publish its AI Launchpad flow for the required language, agents or ring groups, and directions, then publish the transcript-ready callback. Open's **Transcripts** tab explains these steps. |

After configuration, verify answered inbound and outbound calls, an unanswered call, agent attribution, recording playback, and transcript delivery. Connecting the dialer or saving credentials alone does not complete these steps.

## Connect calling and contact synchronization

1. Open **Settings → Integrations → Talkdesk → Connection**. Enter your Talkdesk account name, region, and integration name (the internal name registered with Talkdesk, usually `open-cx`), then save.
2. If it is not already active, have Talkdesk enable the Open custom integration for your account. Configure your Open organization API key in that integration.
3. In Talkdesk, enable **Connect to CTI**, **Synchronize agents**, and **Synchronize contacts**, then run both synchronizations. Contact synchronization sends Open contacts to Talkdesk; it does not import contact edits made in Talkdesk.
4. Set each Talkdesk agent's **Client Integration** to Open, and allow `https://platform.open.cx` in **Admin → Embedding Settings**.
5. Open the Talkdesk dialer in Open, sign in, and test both an incoming and an outgoing call.

See [Talkdesk's embedding instructions](https://support.talkdesk.com/hc/en-us/articles/35497801968667-How-to-Embed-Talkdesk-within-your-System).

The custom integration uses `api_key` as its custom authentication field and these production `POST` endpoints:

| Purpose | Endpoint |
| - | - |
| Validate the Open key | `https://api.open.cx/backend/talkdesk/auth-validation` |
| Synchronize agents | `https://api.open.cx/backend/talkdesk/agent-sync` |
| Synchronize contacts | `https://api.open.cx/backend/talkdesk/contact-sync` |

For the full integration, create an Open organization API key with **Full Access disabled**, **`users:read`**, **`contacts:write`**, and **`chat-sessions:write`**. Contact write permission includes contact read access. A read-only synchronization key cannot import call sessions or media. A sync notification saying **enqueued** confirms scheduling, not completion; verify the synchronized records.

### Link agents

The **Agents** tab in Open's Talkdesk settings explains the setup and links to **Manage teammates**. Agent links are managed by Talkdesk's synchronization; Open does not provide a separate manual mapping table.

Use the same email address for a teammate in both systems. In Talkdesk, open **Integrations → Open → Settings** and select **Sync agents**, then select Open as that agent's **Client Integration** in their Talkdesk user settings. The synchronized Open teammate ID identifies the handling agent when importing call sessions and transcripts. For call attribution, the call-event action must also send **Open Agent External ID**, as described below.

## Enable call sessions

> [!WARNING]
>
> The connected dialer and contact synchronization alone do not create phone sessions. Your Talkdesk administrator must also configure call-event automations. Calls made before these automations are enabled are not imported automatically.

The Open API key used for call updates needs **`chat-sessions:write`** and **`contacts:write`**. Keep **`users:read`** for agent synchronization; `contacts:write` also grants the contact read access needed for synchronization. Keys configured only with the original read permissions cannot log calls.

Create and publish a self-service action in [Talkdesk Connections](https://docs.talkdesk.com/docs/building-a-custom-integration-with-connections), or ask Talkdesk to register an action in the existing custom integration using the settings below. Connections actions complement the existing integration; they do not replace its agent/contact synchronization or CTI activation.

For Connections, configure a `POST` action with `Content-Type: application/json`, explicitly construct the `auth`, `meta`, and `data` envelope below, and map event fields using the variable picker. Save and publish the action before adding automations. Configure the action to accept HTTP `201` as successful receipt.

| Setting | Value |
| - | - |
| Provider | Your registered integration name, usually `open-cx` |
| Name | `sync_call_session` |
| Display | `update a call session` |
| Description | `create or update the phone session for a Talkdesk call` |
| Endpoint | `https://api.open.cx/backend/talkdesk/call-events` |
| Method | `POST` |
| Authentication | Existing custom authentication field `api_key` |
| Success | `201`, with `external_id` identifying the Open session |

Follow Talkdesk's [action configuration](https://docs.talkdesk.com/docs/integration-configuration) and [action executor contract](https://docs.talkdesk.com/docs/implementing-an-action-executor). The action receives this envelope:

```json theme={"dark"}
{
  "auth": { "api_key": "YOUR_OPEN_ORGANIZATION_API_KEY" },
  "meta": {
    "contact_external_id": "OPEN_CONTACT_UUID",
    "agent_external_id": "OPEN_USER_ID"
  },
  "data": {
    "call_id": "TALKDESK_CALL_ID",
    "interaction_id": "TALKDESK_INTERACTION_ID",
    "direction": "inbound",
    "status": "completed",
    "from_number": "+12025550101",
    "to_number": "+12025550102",
    "started_at": "2026-11-04T10:00:00Z",
    "duration_seconds": 30,
    "ended_at": "2026-11-04T10:00:40Z",
    "event_at": "2026-11-04T10:00:40Z"
  }
}
```

Use Talkdesk's variable picker to map real call fields; the uppercase identifiers above are placeholders. Configure the action inputs as follows:

| Input | Type | Required | Meaning |
| - | - | - | - |
| `call_id` | Text | Yes | Stable ID for this call attempt, identical in every update |
| `direction` | Select | Yes | `inbound` or `outbound` |
| `status` | Select | Yes | One of the statuses below |
| `from_number`, `to_number` | Tel | Yes | Originating and dialed numbers in international format; JSON `null` for an unavailable number |
| `started_at` | Datetime or Unix seconds as text | Yes | Original start time, unchanged in subsequent updates |
| `event_at` | Datetime | Yes | Time of this update |
| `answered_at` | Datetime | For `in_progress`; optional for completed calls with duration | Actual time the customer and teammate connected, when available |
| `duration_seconds` | Number or numeric text | For completed calls without `answered_at` | Reported connected duration in seconds, excluding time spent waiting before connection |
| `ended_at` | Datetime | For ended calls | Actual end time |
| `interaction_id` | Text | When sending a transcript | Talkdesk Interaction ID, retained for matching the call with its media; cannot change once supplied |
| `recording_url` | URL | No | Direct, downloadable HTTPS audio URL |
| `transcript_text` | Textarea | No | Final complete transcript text |
| `transcript` | Array | No | Complete structured turns; send this or `transcript_text`, never both |

Dates must include their timezone (`Z` or an explicit offset). For `started_at`, Open also accepts Talkdesk's Unix-seconds text, such as `"1793814245"`, and converts it to the corresponding UTC time. Send seconds, not milliseconds. Omit optional fields when unavailable; do not send empty strings. For anonymous callers, or structured transcript payloads, use a Talkdesk Connections action capable of sending the JSON envelope above.

If the call-end event has no answer timestamp, send `duration_seconds` and omit `answered_at`. Duration must be non-negative and no longer than the call's start-to-end interval; decimal seconds round up to whole seconds. Numeric text such as `"30"` is accepted, including `"0"`. Only send duration on ended calls. Do not substitute total elapsed time or calculate a fictional answer timestamp. Open records the reported duration and leaves unknown answer and ringing times blank. A real answer timestamp received in another update is retained; the reported duration takes precedence over a duration calculated from timestamps.

Create automations for both directions, using the call events available in your Talkdesk account:

| Call event | Send status | Additional fields |
| - | - | - |
| Call starts or reaches the contact center | `initiating` | Original start time and numbers |
| Customer and teammate connect | `in_progress` | `answered_at` |
| Answered call ends | `completed` | `ended_at`, plus `answered_at` or `duration_seconds` |
| Incoming call is missed | `missed` | `ended_at`, no invented answer time |
| Outgoing call is unanswered | `no_answer` | `ended_at` |
| Busy, declined, failed, or canceled call | `busy`, `rejected`, `failed`, or `canceled` | `ended_at` |

Confirm the available events and fields with Talkdesk before enabling the automations. If only end events are configured, the session appears after the call ends. Open processes accepted updates in the background, so a `201` confirms receipt; verify the session separately.

Previously synchronized contacts and agents are identified through `meta.contact_external_id` and `meta.agent_external_id`, which contain **Open IDs**, not Talkdesk IDs. Without a contact ID, Open matches or creates a contact using the customer's phone number. Without a matched agent, the session remains unassigned. A supplied ID belonging to another organization is rejected. Agent IDs must be positive decimal Open user IDs no greater than `2147483647`; larger values return `400`.

When using Talkdesk Connections, map **Open Agent External ID** from the event fields to `meta.agent_external_id` on both inbound and outbound answered-call actions. This reuses the existing agent synchronization link and lets imported transcript messages show the teammate's name. The separate **Agent ID** event field contains a Talkdesk ID and cannot be used here. The synchronized teammate must belong to the Open organization receiving the callback, including when testing in a separate environment.

## Recordings, transcripts, and post-call behavior

Talkdesk's Interaction ID is different from its legacy Call ID. Keep `call_id` unchanged across updates. A call event containing `transcript` or `transcript_text` must also include `interaction_id`; otherwise Open returns `400`. This links transcript sources so redaction can erase the stored copies. For call events without a transcript, the Interaction ID remains optional. Supplying an Interaction ID alone does not download recordings or subscribe to transcription events.

For a further full call update, keep the same call identity and terminal status and set `event_at` to the later update time. Alternatively, use the media-ready callback below, which needs only the Interaction ID and media fields. The call event must also contain that same `interaction_id`; Open does not infer it from a legacy Call ID or a phone number.

### Transcription setup in Talkdesk

Open **Settings → Integrations → Talkdesk → Transcripts** for the setup instructions and a direct link to the transcript section of the full guide. This tab provides guidance; it does not activate transcription or report its live status in Talkdesk.

A Talkdesk administrator must configure [voice transcription in AI Launchpad](https://support.talkdesk.com/hc/en-us/articles/13368032305179-Configuring-AI-Launchpad) for an available product, choose the language and applicable agents or ring groups, select the required call directions, and publish the flow. Then configure the **interaction transcription is available** automation with the transcript-ready payload below.

No additional Talkdesk transcription credentials are entered in Open. The existing Open organization API key authenticates the delivered transcript. Recording credentials authorize recording downloads and do not activate transcription.

### Media-ready callbacks

Configure a separate action that sends `POST https://api.open.cx/backend/talkdesk/media-events`. Use the same organization API key and write permissions as call events. Successful receipt returns `202` with `{ "message": "Media update queued" }`; this confirms acceptance, not a completed download.

Use published Connections actions for the two media events below. Explicitly map their JSON bodies and configure HTTP `202` as a successful response. Both events must carry the same Interaction ID as the corresponding call event. Media callbacks alone do not create sessions.

For **a call recording becomes available**, send:

```json theme={"dark"}
{
  "auth": { "api_key": "YOUR_OPEN_ORGANIZATION_API_KEY" },
  "data": {
    "kind": "recording_ready",
    "interaction_id": "TALKDESK_INTERACTION_ID"
  }
}
```

For **interaction transcription is available**, send `kind: "transcript_ready"` and either `transcript_text` or a complete `transcript` array:

```json theme={"dark"}
{
  "auth": { "api_key": "YOUR_OPEN_ORGANIZATION_API_KEY" },
  "data": {
    "kind": "transcript_ready",
    "interaction_id": "TALKDESK_INTERACTION_ID",
    "transcript": [
      { "id": "turn-1", "speaker": "customer", "text": "Please check my invoice.", "at": "2026-11-04T10:00:10Z" },
      { "id": "turn-2", "speaker": "agent", "text": "I will check it.", "at": "2026-11-04T10:00:15Z" }
    ]
  }
}
```

This is Open's action input format. Verify the actual Talkdesk transcription output and map it before enabling the action; this example does not describe Talkdesk's native transcript format. Supplied speaker labels are preserved. For `transcript_text` exports whose turns start with `Contact:` and `Agent:`, Open displays separate customer and agent messages in their original order, retaining multiline speech. Text without recognizable speaker labels remains one transcript entry. Text-only exports do not supply individual speech timings; use structured `transcript` turns when those timings are available.

Media can arrive before the call update; Open retains it until the linked call ends. Repeated identical media callbacks are accepted without duplicate imports. A different final transcript for the same interaction returns `409`. Media is matched only within the API key's organization. If multiple call attempts share one Interaction ID, automatic media attachment waits for that ambiguity to be resolved instead of choosing a session.

Transcription is asynchronous and separate from call completion and recording availability. Open imports the final transcript when Talkdesk sends the transcript-ready callback; it does not poll Talkdesk for transcripts. There is no fixed arrival time. If a transcript is missing, first check Talkdesk's Transcription tab and the enabled AI Launchpad flow, then the automation's delivery result. Recording credentials alone do not enable transcription or transcript delivery.

### Recording API access

Automatic recording retrieval requires a Talkdesk OAuth client with **Client Credentials** and **`recordings:read`**. The Open organization API key cannot download Talkdesk recordings.

An Open integrations administrator can configure recording access in **Settings → Integrations → Talkdesk**:

1. Select the **Recordings** tab. Under **Recording access**, enter the Talkdesk OAuth **Client ID** and **Client secret**.
2. Select **Update settings** (or **Save settings** for a new connection).
3. Reopen the **Recordings** tab to confirm **Credentials saved**. This confirms storage; verify access with a recorded call.

The secret is never displayed after saving. Leave both fields blank to keep saved credentials, or enter both to replace them. Changing the Talkdesk account or region clears the previous recording credentials; provide credentials for the new account to continue importing recordings. Recording import currently supports United States and Europe accounts.

Create the Talkdesk OAuth client under **Builder → OAuth Clients**. Select **Client Credentials** and grant **`recordings:read`**. These Talkdesk credentials authorize downloads; the separate Open organization API key authenticates incoming callbacks.

Administrators can also configure credentials through the authenticated `POST /backend/talkdesk/settings` endpoint by adding the optional field below to the existing settings request:

```json theme={"dark"}
{
  "account_name": "YOUR_TALKDESK_ACCOUNT",
  "environment": "prd-eu",
  "integration_name": "open-cx",
  "enabled": true,
  "recording_credentials": {
    "client_id": "TALKDESK_OAUTH_CLIENT_ID",
    "client_secret": "TALKDESK_OAUTH_CLIENT_SECRET"
  }
}
```

This uses the signed-in administrator's authentication and requires **settings-integrations:write**. Credentials are stored encrypted and omitted from settings responses; `recording_credentials_configured` reports only whether credentials are saved. Omitting `recording_credentials` preserves existing credentials for the same account and region; setting it to `null` removes them. Changing the account or region clears old credentials unless replacements are supplied. Saving settings, replacing or removing recording credentials, and disconnecting the integration create audit records identifying the acting administrator without including credential values.

Automatic retrieval currently supports US (`prd-us`) and EU (`prd-eu`) accounts and one non-empty customer call recording per interaction. Multiple recording segments, paginated recording lists, and ambiguous call matches need additional handling; Open does not silently select one segment. Failed downloads retry with a fresh download link. Recording-disabled calls are not downloaded. See [Talkdesk's Recordings API](https://docs.talkdesk.com/docs/recordingsapi).

### Other media and call behavior

Redacting an imported transcript message or its session also erases the stored Talkdesk transcript source for that call. Later callback retries cannot restore that transcript or regenerate its summary. When redacting one message, other messages already displayed in the session remain unchanged.

* `recording_url` must be a direct HTTPS audio download. Login pages, API URLs requiring Talkdesk credentials, and redirect URLs cannot be imported. Configure Talkdesk to supply a usable download URL; Open's organization API key does not authenticate downloads from Talkdesk.
* Send the final transcript as `transcript_text`, or use `transcript` with an array of `{ "id", "speaker", "text", "at" }` objects. Speakers are `customer`, `agent`, or `unknown`; turn IDs must be stable across retries. Send one format, once the complete transcript is ready.
* Recording availability depends on your Talkdesk account's recording settings and permissions. Open does not enable recording in Talkdesk.
* Configure recording for each required call direction in [Talkdesk's recording settings](https://support.talkdesk.com/hc/en-us/articles/210267373--Preferences-Call-Recording). An inbound recording does not prove outbound recording is enabled.
* Talkdesk must generate a transcript before it can be imported. Configure the appropriate product, language, agents or queues, and call directions in [AI Launchpad](https://support.talkdesk.com/hc/en-us/articles/13368032305179-Configuring-AI-Launchpad). Check the call's Transcription tab in Talkdesk to confirm one was generated.
* Successful calls close as resolved; missed and other unsuccessful calls close as unresolved. These are human-handled calls.
* Post-call workflows run once for the call. A recording or transcript arriving later can enrich the session and generate its summary; it does not rerun those workflows. A workflow that ran before media arrived may therefore have no summary.
* A summary may be generated from an available recording before Talkdesk's speaker transcript arrives. A summary alone does not confirm transcript delivery.
* Answer, hang-up, transfer, and conference controls remain in Talkdesk. Open displays the session history and available media.

## Verify the setup

1. Make an outgoing call and answer it. Confirm one phone session appears with the correct customer, teammate, direction, and duration.
2. Answer an incoming call, then repeat without answering. Confirm the answered and missed outcomes differ.
3. Confirm any supplied recording plays and the final transcript appears on the correct session.
4. Redeliver a call update. Confirm it updates the existing session without duplicating the call or post-call workflow.

For `401`, check the API key and whether Talkdesk is enabled for its Open organization; the authorization validator also returns `401` for missing synchronization permissions. For `403`, check the key's write permissions. For `400`, check the JSON, timestamps, and external IDs. For `409`, check changed call identity fields or a conflicting final media payload. If Talkdesk reports successful delivery but no session or media appears, provide Open support with the Call ID, Interaction ID, and delivery time; do not send your API key.

### Missing call-end events

If a call stays active in Open after it ends in Talkdesk, check the call-end automation and its delivery result. Open stops treating that Talkdesk call as a busy hold on its agent after 24 hours from the recorded call start, without guessing the outcome, end time, or duration. The session remains pending until a real end event arrives.

Correct the delivery problem and replay the original call-end action with the same Call ID and Interaction ID and the actual outcome and timestamps. This completes the existing session; do not create a new Call ID to recover it. Contact Open support with those IDs and the delivery time if replay is unavailable. This fallback does not change native Open call handling.

### Isolated local tests

All endpoint URLs above are production URLs. To test a local instance, use its test organization's key and the approved public HTTPS address forwarding to that instance. Talkdesk cannot call `localhost`. Keep the test automations separate from production, and update their address when a temporary callback URL changes. For embedded calling, the exact browser origin must be allowed in Talkdesk; you can test callbacks by answering in standalone Talkdesk even when local embedding is unavailable.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.