Skip to main content
POST
Append a user message to an existing session and receive the assistant’s answer. This is the multi-turn continuation of a conversation; the scope is taken from the session, so you never resend it. Answers cite their sources: each citation in message.parts deep-links to a recording_id + start_ms. The request body is the same message shape used for initial_message when creating a session, so a client can use one composer for both.

Authentication

Requires an API key. The session is looked up within the key’s project; an unknown session returns 404. An end-user-scoped key can only post to its own sessions.

Path Parameters

id
string
required
Session identifier (as_*).

Request Body

content
string
required
The user’s message (1–10000 characters).
provider
string
LLM provider to use for this turn (gemini, openai, or claude). Defaults to the project/system default.
context_refs
array
@mentioned recordings to attach to this turn: [{ "type": "recording", "id": "rec_..." }] (max 20). Reserved for upcoming features; persisted today.

Response

Returns the ask result — the assistant message and the session it belongs to.

Response Fields

FieldTypeDescription
session_idstringThe conversation session (as_*)
messageobjectThe assistant message
message.partsarrayRich content: text segments and citation parts ({ type, recording_id, start_ms })
message.tokensobjectToken usage { input, output, cached }
sourcesarrayRetrieved chunks fed into the prompt (cross-recording scopes only; empty for recording) — same shape as Search Recordings
The user message is persisted before the model is called, so on an LLM failure (502) you can safely retry with the returned session_id. A recording-scoped session whose transcription isn’t ready returns 409; an oversized single-recording transcript returns 413 (use a cross-recording scope instead).