Conversations API
A conversation is one run of a template. This API creates conversations server-side, lists them, retrieves the transcript and committed data, and inspects the underlying session.
Some legacy endpoint names use "interviews" (e.g. /v1/interviews) — the same resource. New code should treat "conversation" as the canonical noun. The endpoint paths stay as interviews for backwards compatibility.
Start a conversation
curl -X POST https://api.roxels.ai/v1/interviews \
-H "Authorization: Bearer sk-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_a1b2c3",
"persons": [
{ "name": "Ada Lovelace", "external_id": "user_123" }
],
"context": {
"plan": "pro",
"signed_up_at": "2026-05-01"
}
}'Body fields:
| Field | Type | Description |
|---|---|---|
template_id |
string | The template this conversation will run. |
persons |
array | Participants. Most flows have one. external_id is your stable identifier. |
context |
object | Arbitrary key/value context the agent has access to. Renders into template variables like {{context.plan}}. |
Response:
{
"id": "iv_xxx",
"session_id": "sess_yyy",
"template_id": "tpl_a1b2c3",
"status": "created",
"join_url": "https://app.roxels.ai/join/i/iv_xxx",
"created_at": "..."
}join_url is the canonical URL to share with the participant — visiting it joins the conversation. Or pass session_id to the embed (Roxels.start({ sessionId })) to host it inside your own page.
List conversations
curl "https://api.roxels.ai/v1/interviews?template_id=tpl_a1b2c3&limit=50" \
-H "Authorization: Bearer sk-your-key-here"Query parameters:
| Param | Description |
|---|---|
template_id |
Filter to one template. |
status |
Filter by status (created, joined, completed, failed, etc.). |
since |
ISO-8601 timestamp; return conversations created after this. |
cursor, limit |
Pagination. |
Response:
{
"items": [
{
"id": "iv_xxx",
"session_id": "sess_yyy",
"template_id": "tpl_a1b2c3",
"status": "completed",
"started_at": "...",
"ended_at": "...",
"duration_seconds": 412,
"summary": "..."
}
],
"next_cursor": null,
"has_more": false
}Get a conversation
Returns the full record — transcript, all committed goal data, the summary, the timing.
curl https://api.roxels.ai/v1/interviews/iv_xxx \
-H "Authorization: Bearer sk-your-key-here"Response (abbreviated):
{
"id": "iv_xxx",
"session_id": "sess_yyy",
"template_id": "tpl_a1b2c3",
"status": "completed",
"started_at": "...",
"ended_at": "...",
"duration_seconds": 412,
"persons": [{ "name": "Ada Lovelace", "external_id": "user_123" }],
"summary": "Ada signed up for the Pro plan and wants to use the platform for...",
"findings": {
"name": "Ada Lovelace",
"use_case": "customer onboarding automation"
},
"transcript": [
{ "role": "assistant", "text": "Hi! Welcome.", "timestamp": "..." },
{ "role": "user", "text": "Thanks, hi.", "timestamp": "..." }
],
"outputs": {
"webhooks": [{ "url": "...", "attempts": 1, "status": "success" }]
}
}| Field | Description |
|---|---|
summary |
LLM-generated narrative summary of the conversation. |
findings |
All committed goal data, keyed by goal id. The structured result of the conversation. |
transcript |
Full chat history (both directions). |
outputs |
Status of each output (webhook, frontend callback, chained API) that fired. |
Get recorded frames
If the participant shared their screen, the conversation has frame captures (per-segment thumbnails). Retrieve them with:
curl https://api.roxels.ai/v1/interviews/iv_xxx/frames \
-H "Authorization: Bearer sk-your-key-here"Response: an array of frame objects with timestamps and signed URLs (the URLs are short-lived; refetch when needed).
Session credentials (advanced)
If you need to join a session from a custom client (not the embed), get LiveKit credentials directly:
curl https://api.roxels.ai/v1/sessions/sess_yyy/join \
-H "Authorization: Bearer sk-your-key-here"Response:
{
"ws_url": "wss://...",
"token": "...",
"participant_identity": "..."
}For embed integrations (modal, compact, headless), you never need this — the embed handles it.
Patterns
Create-then-embed
- POST
/v1/interviewsfrom your backend with full context. - Return the
session_idto the browser. Roxels.start({ sessionId, display: "modal" }).
This is the recommended path when context is sensitive (the user shouldn't be able to tamper with it). See Embed install.
Schedule-then-share
- POST
/v1/templates/tpl_…/schedulewithcountto pre-create N conversations. - Email each
join_urlto the respective participants.
Useful for bulk outbound conversations (research interviews, customer touchpoints).
Backend-polling for completion
If you need to react to completion from your backend and webhooks aren't an option:
- Track the
session_idafter creation. - Poll
GET /v1/interviews/iv_xxxperiodically and checkstatus === "completed". - Read
findingsandsummarywhen status flips.
Prefer webhooks for this — they're real-time and don't waste API calls.
Read next
- Webhooks overview — Real-time delivery instead of polling.
- Persons — Persistent identity for resumption.
- Templates API — Manage the templates that conversations run.
- Headless mode — Drive a conversation from your own UI.