Skip to main content
POST
cURL
Use POST /chat/query-async/ when you don’t want to hold an HTTP connection open while the agent works. It accepts the same body as POST /chat/query/ plus an optional callback_url, and returns 202 Accepted immediately with a conversation_id — the agent keeps running in the background. Because the response comes back before the answer is ready, you must pick one of two ways to collect the result:
  1. Poll GET /chat/conversation/{conversation_id}/ until it reports Completed.
  2. Callback — pass a callback_url and Voltai POSTs the finished result to it.
Choose one. If you provide a callback_url you don’t need to poll; if you don’t, polling is the only way to get the answer.

Request

Send X-API-KEY in the header. The body must include query and user_id.
  • query (required) — the user’s question.
  • user_id (required) — your identifier for the end-user. Each (API key, user_id) pair allows one concurrent request; a second in-flight request returns 429.
  • callback_url (optional) — an http(s) URL. When set, the final result is POSTed here as JSON once the run finishes. An invalid URL returns 400.
  • chat_id (optional) — UUID of a thread to continue. Omit to start a new thread.
  • reasoning_level (optional) — low, medium (default), or high.
  • topic_names (optional) — list of knowledge topic names to scope retrieval to.

Response (202 Accepted)

The 202 body confirms the turn was accepted; it does not contain the answer.
Hold on to conversation_id — you need it to poll for or correlate the result.

Example Request

Option A — Poll for the result

If you did not pass a callback_url, poll GET /chat/conversation/{conversation_id}/ using the conversation_id from the 202 response. Check the status field on each response:
  • Processing — the agent is still working; wait a moment and poll again.
  • Completed — the answer is ready; the body carries the full POST /chat/query/ payload (final_answer, sources, tools, etc.).
  • Failed — the turn stopped without producing an answer.
A reasonable loop polls every few seconds until status is no longer Processing. This endpoint is read-only and does not consume session capacity.

Option B — Receive a callback

If you pass a callback_url, you don’t need to poll. When the run finishes, Voltai sends a POST to that URL with the same JSON body that POST /chat/query/ returns (final_answer, chat_id, chat_url, conversation_id, sources, tools, content).
Your webhook endpoint should:
  • Accept a POST with a JSON body and return quickly (a 2xx).
  • Use conversation_id to match the callback back to the original request.
  • Handle the failure shape — if the run fails, the callback body is {"chat_id", "conversation_id", "status": "error", "error"} instead of the full answer.
Callback delivery is best-effort. If your endpoint is unreachable the result is still saved, so you can always fall back to GET /chat/conversation/{conversation_id}/.

Errors

  • 400 — missing query/user_id, malformed chat_id, unknown topic_names, or an invalid callback_url.
  • 403 — invalid or missing API key, the key lacks the chat scope, or the org message limit is reached.
  • 409chat_id was supplied but the UUID is already in use by a chat the API key cannot resume (a different organization, or a soft-deleted chat). Pick a different UUID, or omit chat_id to let the server mint one.
  • 429 — the same user_id already has an in-flight request, or the org-wide session cap is reached. Check usage with GET /chat/sessions/.

Authorizations

x-api-key
string
header
required

Body

application/json

Same payload as POST /chat/query/, plus an optional callback_url.

Request body for POST /chat/query-async/. Identical to ChatQuery plus an optional callback_url for webhook delivery of the result.

query
string
required

The user's question.

user_id
string
required

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.

Maximum string length: 255
chat_id
string<uuid>

Existing 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.

reasoning_level
enum<string>
default:medium

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.

Available options:
low,
medium,
high
topic_names
string[]

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.

topic_name
string
deprecated

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.

callback_url
string<uri>

Optional http(s) URL. When provided, the final result is POSTed to this URL as JSON once the agent finishes. Must be a valid http(s) URL or the request returns 400. Omit it if you plan to poll GET /chat/conversation/{conversation_id}/ instead.

Response

The request was accepted and the agent is running in the background. Use conversation_id to poll GET /chat/conversation/{conversation_id}/, or wait for the callback_url webhook if one was supplied.

Acknowledgement returned immediately (202) by POST /chat/query-async/. The answer is not included — fetch it later via GET /chat/conversation/{conversation_id}/ or receive it on your callback_url.

chat_id
string<uuid>
required

Thread identifier for this conversation. Reuse it (as chat_id) in later requests to continue the same thread.

conversation_id
integer
required

Identifier of the turn just created. Poll GET /chat/conversation/{conversation_id}/ with this value to fetch the answer once it is ready.

chat_url
string<uri>
required

Web UI link to this thread.

status
enum<string>
required

Always processing: the turn was accepted and the agent is running in the background.

Available options:
processing