Skip to main content

Manage conversations with the API

Use these operations to read or update an existing conversation, assign ownership, or save an internal note. Each operation takes one request. The corresponding CXP MCP tools use the same business rules with your connected user’s permissions.

Prerequisites

Obtain your API base URL, tenant ID, and a tenant API key with cxm:conversations.read for reads and cxm:conversations.write for writes, or a broader scope allowing the requested action. A write-only scope does not grant read permission. Keep the key on your server. Use an exact conversation ID and, for assignment, an active agent or team ID from the same tenant. See API overview for authentication. Send Authorization: Bearer <tenant-api-key>. Every path below starts with /api/v1/cxm/tenants/{tenantId}. GET requests accept no body. Writes use Content-Type: application/json and a complete JSON body within 32 KiB. Unknown fields and unsupported query parameters are rejected.

Read conversation details

Send GET /conversations/{conversationId} with no query parameters:
The document contains all available projected properties except its root messages property. Its fields can evolve over time. Reads return only the exact requested tenant’s data, even when conversation IDs are shared across tenants. This is the same read used by get_conversation; MCP adds its existing context/result metadata. Projection can lag recent writes. A missing projection returns 200 with document: null; it does not establish whether the durable conversation exists. projectionUpdatedAt is null when unavailable.

Read conversation history

Send GET /conversations/{conversationId}/history?limit=100. The response is {"items":[...],"nextCursor":"..."}. Each item has type: "message" or type: "event" and the corresponding stored record. History includes stored messages, internal notes, and recorded events in oldest-first order, using the same implementation as get_conversation_history. Messages include their actual author, visibility, role, body, and metadata; events include their kind, title, detail, and metadata. Existing History redaction and size limits apply, with redactedPaths, truncatedFields, and sourceByteSizes recording transformations. limit is an integer from 1 to 200, default 100. Pass the opaque nextCursor unchanged as the URL-encoded cursor query parameter to continue for the same tenant and conversation. Continue until nextCursor is null. Only one page is read per request. Byte limits can produce fewer items than the requested limit. Missing or empty history returns 200 with {"items":[],"nextCursor":null}. Unknown, repeated, array, and empty query parameters are rejected. Invalid limits or cursors return 400. Both read endpoints use Cache-Control: no-store. API keys with read access can retrieve internal history as well as customer-visible content.

Update operational fields

Send PATCH /conversations/{conversationId}:
Provide at least one field. Normal status transitions and required custom-field checks apply. Open and Pending can transition to each other or Resolved; Resolved can transition to Open, Pending, or Closed. Closed can only reopen to Open. Simple mode also prevents reopening when the contact already has another non-closed conversation. Non-null Pending fields require the resulting status to be Pending. Omitted Pending fields are preserved while Pending; leaving Pending clears them. Subject, tags, custom fields, contact, organization, and category edits are not part of this endpoint.

Assign or clear ownership

Send PUT /conversations/{conversationId}/assignment:
Use type: "team" with an exact team ID to assign a team. Send {"assignee": null} to clear assignment. Names are not accepted as selectors. Assigning a team sets the conversation’s team association; assigning an agent preserves the current team association; clearing assignment also clears it. Existing realtime ownership rules still apply. This operation does not take over a conversation, accept a routing offer, or join a call. If CXP returns takeover_required, use the normal CXP takeover workflow.

Add an internal note

Send POST /conversations/{conversationId}/internal-notes:
The body must contain non-blank text with at most 20,000 characters, within the 32 KiB JSON limit. CXP fixes the note’s internal visibility and attributes it to API <key name>. You cannot supply a role, author, visibility, attachment, or message ID. The note is never sent to the customer. Normal internal follower notifications and Agent Assist behavior can still run.

Results and execution behavior

Updates and assignments return 200 with a conversation containing its ID, status, priority, Pending fields, assignee, and team association. Notes return 201 with a note containing its ID, creation time, internal visibility, and author label. API-key identifiers are omitted. Success does not mean notification delivery has finished. Merged and non-customer records cannot be changed. Closed conversations reject assignment, notes, and metadata changes unless an update explicitly reopens them. You can reopen and change other allowed metadata in one update, such as {"changes":{"status":"open","priority":"high"}}. Assignment and notes require the conversation to be reopened first. These restrictions apply to the current conversation state when the operation executes. Each invocation is independent. There is no preview/apply step, caller version condition, idempotency key, request deduplication, or automatic retry. A later valid update can replace a value changed since you last read it. A timeout can follow a successful commit; repeating that request may repeat its effects, including creating another identical note. Inspect the conversation or its history before deciding whether another write is needed. Request/correlation headers are for tracing only.

Use the same operations through MCP

Reads use get_conversation and get_conversation_history with Read CXP data and your current Conversation read permission. Tool inputs use the same exact tenantId and conversationId; history also accepts limit and cursor. Connect CXP to ChatGPT or Codex with Modify CXP data. Use update_conversation, assign_conversation, or add_conversation_internal_note. Each tool requires your current Conversation read access plus, respectively, update, assignment, or reply permission. Tool inputs contain tenantId, conversationId, and the payload above. assign_conversation additionally accepts {"assignee":{"type":"me"}} to select your connected tenant user. API keys have no me identity. Notes retain your actual authorship, even if someone else owns the conversation. The tools execute directly and honor normal host approval controls. CXP does not provide a separate confirmation page or independently attest to human approval of each host call. Preparing a brief alone does not save a note.