Conversations & Transcripts
Read a conversation's full transcript over the management API — the same turns, tool activity and attachments your team sees in the Studio. Use it to build an admin transcript viewer, feed a QA pipeline, or archive conversations into your own system.
Every operation here needs an API key with the conversations:read scope.
| Operation | Endpoint |
|---|---|
| List conversations | GET /api/v1/conversations |
| Get one conversation | GET /api/v1/conversations/{id} |
| Get its transcript | GET /api/v1/conversations/{id}/events |
List and get conversations
GET /api/v1/conversations returns data: your 200 most recently active conversations, newest activity first. It takes no paging or filter parameters — for search, filters and page counts use Cases, and for voice calls use Calls.
Each conversation carries:
| Field | Meaning |
|---|---|
id | Conversation id — the one every other operation takes |
customer_id | The customer it belongs to |
workflow_id | The agent that handled it, when one did |
status | active, resolved, escalated or abandoned |
channel_started | The channel it began on |
channels | Every channel it has used |
summary | Present once a summary has been written |
created_at / updated_at | Timestamps |
GET /api/v1/conversations/{id} returns the same shape for one conversation, or 404 not_found.
Get a transcript
http
GET /api/v1/conversations/{id}/events
Authorization: Bearer sk_…Events come back oldest-first. By default each one carries a compact, safe summary:
| Field | Meaning |
|---|---|
id | Event id |
event_type | What happened — user_message, ai_response, tool_call, tool_result, file_upload, and more |
actor | user, ai, human_agent or system |
channel | Where the turn happened |
created_at | Timestamp |
text | Message text, on message events |
tool_name, tool_status | On tool events |
Asking for more detail
Richer payloads are opt-in, so the default response stays small and unchanged for anything you have already built. Pass include with a comma-separated list:
| Value | Adds |
|---|---|
tool_io | tool_input and tool_output on tool events, plus error detail and latency |
files | file_name, mime_type, file_size and a short-lived signed file_url on file_upload events |
http
GET /api/v1/conversations/{id}/events?include=tool_io,filesAttachment links are generated fresh each time you read and expire shortly after, so fetch a file when you need it rather than storing the link.
tool_status describes the CALL, not the outcome
success means the tool was reached and returned. A tool that ran fine and answered "no such order" is still success. Read tool_output for what it actually said.
Paging
| Parameter | Default | Notes |
|---|---|---|
limit | 100 | Maximum 1000 |
after | — | ISO timestamp; returns events strictly after it |
before | — | ISO timestamp; returns events strictly before it |
event_type | — | Comma-separated filter, e.g. user_message,ai_response |
The response carries has_more, and when more remain, next_after — pass that straight back as after to walk a long conversation page by page.
bash
curl -H "Authorization: Bearer sk_…" \
"https://<your-workspace>-api.perfox.ai/api/v1/conversations/$ID/events?limit=200&include=tool_io"If your workspace has PII redaction switched on, tool output was already redacted before it was stored, so what you receive is the redacted form.