Conversations
List and read conversations, the history window.
The endpoints below are for when you're building your own chat UI instead
of using the <harnix-chat> widget — they all authenticate with an
end-user token (Authorization: Bearer <token>, see
Authentication), not an API key.
List available agents
GET https://api.harnix.vn/v2/agents
Authorization: Bearer <token>[{ "id": "b6b0f9b2-...", "name": "Support assistant" }]Returns every active agent in the organization — a token isn't tied to a specific agent.
Start a new conversation
POST https://api.harnix.vn/v2/conversations
Authorization: Bearer <token>
Content-Type: application/json
{ "agent_id": "b6b0f9b2-..." }Returns 201 with a ConversationRead: { id, agent_id, title, created_at, last_message_at }. title is null until something sets it
later (the console lets you name conversations).
List conversations
GET https://api.harnix.vn/v2/conversations?agent_id=...&limit=20&before=...
Authorization: Bearer <token>Only returns conversations belonging to the calling end-user — there's
no way for one end-user to read another's conversation, even knowing its
ID. Keyset pagination: use the previous page's next_before as the next
page's before; limit maxes out at 50 (default 50).
{
"items": [{ "id": "77fd...", "agent_id": "b6b0f9b2-...", "title": null, "created_at": "...", "last_message_at": "..." }],
"next_before": "77fd..."
}Read a conversation
GET https://api.harnix.vn/v2/conversations/{conversation_id}?before_seq=...
Authorization: Bearer <token>Returns a ConversationDetail — the conversation's info plus up to 50 of
its most recent messages (messages). Each message has a role (user
or assistant), content, citations (only on assistant messages, or
null), seq (increasing order within the conversation), and run_id
(the run that produced this message, useful for
streaming or review). Use before_seq to page
further back.
pending_approval tells you whether the conversation is paused waiting for
the user to confirm an action: null when it isn't, otherwise
{ run_id, expires_at, calls: [{ call_id, server_name, name, title, arguments }] }
— the same content as the approval frame of the
stream. Use it when the user reopens the page:
rebuild the confirmation prompt from here and answer with
POST /v2/runs/{run_id}/approval,
no need to reopen the stream.
pending_question tells you whether the conversation is paused waiting for
the user to answer questions (ask_user): null when it isn't, otherwise
{ run_id, call_id, expires_at, questions: [...] } — the same content as the
question frame of the stream. Use it when the
user reopens the page: reconstruct the question UI from here and answer via
POST /v2/runs/{run_id}/answer or
send a follow-up message without reopening the stream.
A conversation that isn't yours, or doesn't exist — same
conversation_not_found (404) either way: the endpoint never confirms
that someone else's conversation exists.
Send a message in a conversation
POST https://api.harnix.vn/v2/conversations/{conversation_id}/messages
Authorization: Bearer <token>
Idempotency-Key: 2f6a... (recommended)
Content-Type: application/json
{ "content": "What's our refund policy?" }202 Accepted with { run_id, message_id, conversation_id } — identical
to POST /v2/chat, except the
conversation is already fixed by the URL and the sender is the end-user
holding the token, not an API key.
While the conversation has an action awaiting confirmation
(pending_approval is not null), sending a new message returns
409 approval_pending — approve or decline that action first. Resending
the very message that created the waiting run, with the same
Idempotency-Key, still returns 202 with that run as usual.
In contrast, when the conversation has a question waiting for input
(pending_question is not null), sending a new message does not fail:
the new message is treated as the user's free-text answer to the question.
The endpoint returns 202 with the same waiting run (without creating a
new run or counting against the 3 active runs limit), records the message in
the conversation, and resumes the run. Resending with the same
Idempotency-Key returns the same run without duplicate messages.
The history window
The agent doesn't see the entire conversation history when it answers — only a recent window (configured per agent, see Build an agent). A very long conversation still reads back in full through this API; only what's fed into the model's context is limited.
Next
- Streaming — follow the
run_idyou just got, live. - Idempotency & cancel — including how to approve actions or answer waiting questions.
- Runs & traces — conversation history read through this API is not affected by your organization's trace retention setting.