Chat Query
Ask a question to the Voltai agent and continue an existing thread with chat_id.
POST /chat/query/ to ask a question and optionally continue the same conversation by sending back the returned chat_id. The agent automatically chooses which topics, tools, and subagents to use; you can scope retrieval to specific knowledge topics with topic_names and bias the agent’s reasoning depth with reasoning_level.
Send your API key in the X-API-KEY header. The body must include query and user_id.
Request Notes
-
user_id(required) — your application’s identifier for the end-user making the request. Each(API key, user_id)pair is limited to one concurrent request. If the same user already has a request in flight, the endpoint returns429. -
chat_id(optional) — must be a valid UUID. Behavior:- Omitted → the server mints a fresh UUID and creates a new chat.
- UUID matches an existing chat in your organization → the new turn is appended to that thread.
- UUID is well-formed but not yet used → the server creates a new chat under that UUID. This lets clients pin their own thread IDs for idempotency or app-side correlation.
- UUID already belongs to a chat you cannot resume (different org or soft-deleted) →
409. - UUID malformed →
400.
-
reasoning_levelcontrols how thorough the agent should be. Defaults tomedium.low— favor quick answers and minimal tool use.medium— default.high— favor thorough multi-step reasoning with more tool calls.
medium. -
modeis a legacy field kept for backwards compatibility. The current agent pipeline does not branch on it; whatever you send is echoed back unchanged on the response. Usereasoning_levelinstead. -
topic_names(optional) — list of knowledge topic names to scope retrieval to (e.g.["Family A", "Family B"]). Each name must match a topic in your organization (case-insensitive). If omitted or[], topic scope is chosen automatically. If any name does not match a topic, the endpoint returns400. -
topic_name(deprecated) — singular alias fortopic_names. Whentopic_namesis omitted,topic_nameis wrapped into a one-element list. Prefertopic_namesfor new integrations.
Response Notes
- The endpoint returns a single JSON object, not an array.
final_answeris the cleaned answer text. Internal markup (<answer>,<ref>,<abbr>, citation tokens) is stripped.chat_idis the chat thread UUID. Pass it back on subsequent requests to continue the conversation.chat_urlis the web UI link for this thread:https://voltai.ai/{org_name}/chat/{chat_id}, where{org_name}is the resolved organization’sname.conversation_idis the integer identifier of this specific question/answer turn. A newconversation_idis returned for every/chat/query/request, including follow-ups in the samechat_id. Use it to fetch the same turn later viaGET /chat/conversation/{conversation_id}/.sourceslists evidence cited by the agent. Each entry includes:id— stable identifier; use it to join citation tokens that appear infinal_answer(e.g.[0351-E1]) back to a specific source.source_name— filename for library / PDF chunks; page or item title for web, fetched URLs, and connector sources (Slack, Jira, Confluence, Salesforce, SharePoint, Assembla); display label for part sources.page— 1-indexed page number for paginated library sources;nullotherwise.type— source type tag (text,web,part, etc.).url— link to view the source. May benullfor sources without a canonical link.display_name— human-readable label for the tool that surfaced the source (e.g."Library Search","Web Search","Part Detail").
toolsis the ordered list of tool calls the agent made while answering — same data SSE clients receive astool_call/tool_outputframes. Each entry hasid,name,display_name,title,input,output,status, and an optionalsubagent_instance_id.contentis the raw transcript of the turn: an ordered list oftextandtoolitems as the agent produced them.textitems concatenate tofinal_answer;toolitems mirrortools.thinkingis retained for backwards compatibility with the legacy multi-agent orchestrator. Under the current agent pipeline it is always""— usetoolsandcontentto inspect the reasoning trail.modeechoes whatever value you sent (or"AUTO"if omitted). It does not reflect any internal routing decision.
Concurrency & Sessions
Each(API key, user_id) pair is limited to one concurrent request. If a second request arrives for the same pair while one is still in progress, the API returns 429 with error code user_session_limit_exceeded.
There is also an organization-wide session limit. If all org-level seats are occupied, the API returns 429 with error code session_limit_exceeded.
Use GET /chat/sessions/ to check current session usage and see which user IDs are active.
Streaming with Server-Sent Events
SetAccept: text/event-stream to receive incremental output instead of the single JSON response.
The stream begins with one start event, then interleaved text, tool_call, tool_output, todos, and interrupt events as the agent runs, and ends with either one done event (success) or one error event (failure). Comment frames (: keepalive) may appear between frames while the server waits on the model; ignore them.
| Event | Description |
|---|---|
start | Sent once at the top of the stream so clients can render thread context immediately. Carries chat_id, chat_url, conversation_id. |
text | Incremental answer text. msg.delta is the fragment to append; msg.subagent_instance_id is non-null when the delta comes from a subagent (intermediate reasoning, not user-facing). |
tool_call | The agent started a tool call. msg contains id, name, display_name, title, input, and subagent_instance_id. |
tool_output | The corresponding tool call finished. msg contains id, output, status (running | success | error). |
todos | Snapshot of the agent’s TODO list for multi-step plans. Replaces (not appends) any prior list for the same subagent_instance_id. |
interrupt | Human-in-the-loop interrupt. The agent is asking you to approve or reject an action. |
done | Terminal success frame with the same payload as the non-streaming JSON response (including tools, content, sources). |
error | Terminal failure frame. Sent if the stream fails after the 200 response status has been committed. |
msg.delta text from every main-agent text event (those with subagent_instance_id == null) reproduces a close approximation of final_answer; rely on the done event’s final_answer for the canonical cleaned string.
Example Request
Scoped to one or more topics (optional)
Follow-up Request (continuing a thread)
Example Response
Example SSE Stream
409 — Chat ID conflict
429 — Per-User Limit
429 — Org-Level Limit
Authorizations
Headers
Set to text/event-stream to opt into Server-Sent Events streaming. Any other value (or omitting the header) returns the standard JSON response.
application/json, text/event-stream Body
Query payload for the Voltai agent.
Provide query and user_id. Topic scope is chosen automatically unless you pass topic_names. The agent decides its own reasoning depth — use reasoning_level to bias it.
The user's question.
Your application's identifier for the end-user making the request. Used for per-user session tracking and concurrency enforcement. Each (API key, user_id) pair is limited to one concurrent request.
255Existing chat thread to continue. Must be a valid UUID. If it matches a chat in your organization, the new turn is appended; if the UUID is well-formed but not yet used, the server creates a new chat under that UUID (useful for client-side idempotency / correlation). Omit to let the server mint a fresh UUID. A UUID that already belongs to a chat the API key cannot resume returns 409.
Bias for how much intermediate reasoning the agent should do. low favors quick answers, high favors thorough multi-step reasoning. Unknown values fall back to medium.
low, medium, high Legacy reasoning-mode selector kept for backwards compatibility with older clients. Under the current agent pipeline this is a no-op — the value is validated and echoed back on the response, but it does not change behavior. Use reasoning_level instead.
AGENTIC, FAST, AUTO Optional. Names of knowledge topics to scope retrieval to. Each must match a topic in your organization (case-insensitive). If omitted or empty, topic scope is chosen automatically. If any name does not match a topic, the request returns 400.
Deprecated singular alias for topic_names. When topic_names is omitted, topic_name (if present) is wrapped into a one-element list. Prefer topic_names for new integrations.
Response
Agent response. Returned as a single JSON object by default, or as a Server-Sent Events stream when the request includes Accept: text/event-stream.
Agent response.
Cleaned answer text returned by the agent. Internal markup (<answer>, <ref>, <abbr>, citation tokens) is stripped.
Aggregated reasoning string from the legacy multi-agent orchestrator: per-agent entries are concatenated in execution order, each prefixed by a header line and separated by a blank line. Empty under the current agent pipeline — use tools and content to inspect the reasoning trail instead.
Thread identifier: the Chat UUID for this conversation. Reuse this value in subsequent requests to continue the same thread.
Web UI link to this thread: https://voltai.ai/{organization_name}/chat/{chat_id} using the resolved organization's name.
Identifier of the specific question/answer turn within the thread. A new conversation_id is generated for every /chat/query/ request. Use it with GET /chat/conversation/{conversation_id}/ to fetch this exact turn later.
Evidence cited by the agent. Each entry is annotated with the tool that surfaced it (display_name) and a stable id for joining back to citation tokens in final_answer.
Echo of the request mode. Retained for backwards compatibility; current agent behavior does not depend on it.
Every tool call the agent made while answering this turn, in execution order. Lets non-streaming clients see the same reasoning trail that SSE clients receive as live tool_call / tool_output frames.
Raw agent transcript for the turn: an ordered list of text and tool items as the agent produced them. text items concatenate to final_answer; tool items mirror the entries in tools.
Text fragment emitted by the agent (main agent or a subagent). Concatenate all main-agent text items in order to reconstruct the agent's prose.
- Option 1
- Option 2