Skip to main content
GET
/
v1
/
api
/
conversations
/
{id}
Get a conversation
curl --request GET \
  --url https://api.hq.zone/v1/api/conversations/{id} \
  --header 'Authorization: Bearer <token>'
{
  "agent": {
    "display_name": "<string>",
    "avatar_url": "<string>",
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "slug": "<string>"
  },
  "channel_kind": "<string>",
  "conversation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "mode": "<string>",
  "participants": "<unknown>",
  "read_only": true,
  "surface": "<string>",
  "viewing_as": "<string>",
  "title": "<string>"
}

Authorizations

Authorization
string
header
required

Personal Access Token. Send as Authorization: Bearer hq_pat_....

Path Parameters

id
string<uuid>
required

Conversation id

Query Parameters

view
string | null

?view=admin opts into "see every conv in tenant", honored only when the caller is workspace_users.is_admin = true. Falls back silently to participant view otherwise so a crafted URL from a non-admin doesn't leak the existence of admin mode via a 403.

q
string | null

Free-text filter. Case-insensitive substring match over the conv title, the agent display name, and the latest-message preview (the three things a row shows). Empty/blank = no filter.

page
integer<int64> | null

1-based page index. Clamped to >= 1.

page_size
integer<int64> | null

Rows per page. Clamped to 1..=100; defaults to 25.

sort
string | null

recent (default, newest activity first), oldest, or title (A-Z, untitled convs sink to the end).

mode
string | null

Which lane: fast lists only the no-VM "ask" threads; anything else (default) lists the standard agent threads. The two lanes are surfaced as separate tabs in Studio.

channel_kind
string | null

Optional channel filter. When set to a known channel kind (e.g. email) the list returns ONLY threads of that kind - this backs the admin Email > Threads tab. When unset, the default list EXCLUDES email so external-correspondence threads don't bleed into the main Home conversation list (they live under the Email section instead). Unknown values yield an empty set rather than an error.

Response

Conversation metadata

agent
object
required
channel_kind
string
required

Origin channel: web / slack / teams / schedule. Studio renders schedule threads read-only (a record of a scheduled run, not a live chat) and offers "start a fresh conversation" instead.

conversation_id
string<uuid>
required
mode
string
required

standard (sandbox agent thread) or fast (no-VM "ask" thread). Studio shows a "Convert to agent" affordance on fast threads.

participants
any
required

Directory of every user the thread references (message authors + <@U…> mentions), keyed by UID -> { name, avatar_url }. The SPA renders <@U…> mention chips from this. {} for single-party (web/DM) convs.

read_only
boolean
required

True when this conversation is read-only from web/extension: a multi-party Slack/Teams channel thread (owned by Slack/Teams). The SPA disables the composer + shows a "happening in the channel" hint. The API enforces this independently (prepare_turn refuses such turns).

surface
string
required

Conversation surface: channel (multi-party Slack/Teams thread) / dm / web / extension. Drives read_only.

viewing_as
string
required

"participant" (default) or "admin" when the caller elevated via ?view=admin AND is workspace_users.is_admin. The SPA renders an "Admin view" banner when this is admin so the user knows they're looking at someone else's conv.

title
string | null

Display label for the conversation. User-set (Studio rename) or auto-derived (title.derive worker); NULL until one exists, in which case the SPA falls back to a message preview / "Untitled".