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 withcxm: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
SendGET /conversations/{conversationId} with no query parameters:
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
SendGET /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
SendPATCH /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
SendPUT /conversations/{conversationId}/assignment:
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
SendPOST /conversations/{conversationId}/internal-notes:
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 aconversation 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 useget_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.
