Roxels/ docs
api

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

  1. POST /v1/interviews from your backend with full context.
  2. Return the session_id to the browser.
  3. 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

  1. POST /v1/templates/tpl_…/schedule with count to pre-create N conversations.
  2. Email each join_url to 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:

  1. Track the session_id after creation.
  2. Poll GET /v1/interviews/iv_xxx periodically and check status === "completed".
  3. Read findings and summary when status flips.

Prefer webhooks for this — they're real-time and don't waste API calls.