POST/v1/chat
Stream an assistant answer (SSE)
chat
With several API copies behind a load balancer (the api.<domain> address, 1.62.0), an answer and the buffer of its events live in the memory of the copy that generates it. Resuming the stream with Last-Event-ID works only on that copy.
A repeated request with the same request_id and conversation that reaches another copy after the answer has finished receives the saved answer (token and done, events numbered from 1) without asking the question again. A repeated request that reaches another copy while the answer is still being generated stops that generation and builds the answer anew; no second question is created either. To resume the stream without a new generation, keep the connection to the same copy or repeat the request after the done event.
Authentication
Send an API key in the Authorization header: Authorization: Bearer <key>.
Header parameters
X-View-AsstringFor API keys with the
adminrole only. Makes the request as the data profile<profile>[:viewer|verifier|editor], for exampleemployee:viewer. The installation key cannot use this header (403).
Cookie parameters
kb_view_asstringCookie of the “View as” mode for a session.
POST /auth/view-assets it andDELETE /auth/view-asclears it.
Request body
application/json
items ≥ 1
collectionstringDefault: "default"
tagsarray of string | nullexportstring | nullcard_idsarray of string | nullitems ≤ 50
streambooleanDefault: false
conversation_idstring | nulllength ≤ 64
originstring | nulltoolsboolean | nullbypass_cachebooleanDo not take the answer from the answer cache (the “Get a fresh answer” button under a cached answer). The fresh answer replaces the cached entry.
Default: false
languagestring | nullAnswer language: an ISO 639-1 code (
de,en,ru, …) to answer in that language. Withautoor without the field, the language is detected from the question. The interface passes the language of a suggestion in another language explicitly (Starter.language).scopeChatScope | nullScope of the question: several collections, a source, tags and a period. The collections of the scope replace
collection. A source narrows the answer to its collection (and its own cards). Tags are added totags. The period limits financial answers to that period. You can select only what the user can see (collections:collections.no_access/collections.not_found; source:sources.not_found). Withconversation_id, the scope is saved in the conversation. Without the field, the conversation's scope applies;nullor an empty scope clears it.request_idstringIdempotency key of the question. Send the same key in every retry of the stream for one question (a retry after a disconnect; here
Last-Event-IDdoes not continue the stream and is only logged). A retry with the key of an answer that is already saved does not create a second question: the saved result is sent again as onedoneevent (and atokenwith the text), even if the question or credit limit is exhausted. If the previous answer is still being generated for a disconnected client, that generation stops and the answer is generated anew.length ≤ 64
version_ofinteger (int64)Creates a new version of this question's turn in the conversation (
question_idfrom the feed): an edited question (new text inmessages), a regenerated answer (the same text, usually withbypass_cache), or the same question with anotherquality(for example,preciseafter afastanswer). The previous question and answer pair is kept. The turns after it stay in its branch and are hidden from the feed while the new version is selected (FeedItem.versions,POST /v1/conversations/{conv_id}/versions). The history used for the answer is the selected branch up to this turn. Thequalityof a version does not change the conversation's settings. Requiresconversation_id; a question from another conversation returns404 questions.not_found.qualitystringBalance between speed and accuracy of the search behind the result:
fastis quicker,preciseis more accurate. Default:precise.Allowed values:
fastprecise
Responses
200With `stream=true`: `text/event-stream`. Each event consists of the lines `id: <number>` (the sequence number of the event in the stream, starting at 1) and `data: <JSON>`, followed by an empty line. The `event:` and `retry:` fields are not used; the event type is in the `type` field (`ChatEvent`).
With stream=true: text/event-stream. Each event consists of the lines id: <number> (the sequence number of the event in the stream, starting at 1) and data: <JSON>, followed by an empty line. The event: and retry: fields are not used; the event type is in the type field (ChatEvent).
A question with request_id is answered independently of the connection. A disconnect does not stop the answer: it is completed and saved in the conversation (for up to 10 minutes). Repeating the same request (the same request_id and conversation) attaches to the answer in progress, and with the Last-Event-ID header it receives the events after that number, so the stream continues with the same event numbers. If the stream cannot continue from that number, the repeated request gets the stream from the start: the first event then has a number no greater than Last-Event-ID, and the client starts the answer over. If the answer has already finished and its event buffer has been released (after 3 minutes), the saved result is sent again (token and done, numbered from 1) without asking the question again; otherwise the answer is generated anew. To stop such an answer, call POST /v1/chat/cancel. Without request_id, a client disconnect cancels the answer.
After the first event, while the answer is in progress, the server sends a : ping comment every 15 seconds; skip it. Event order: stage events (progress), meta, sources, data, then the answer text in token events, then done. Before the answer text, sources and data can repeat and tool events can appear; the text can arrive as one token or in parts. A cached answer: meta (with cached), sources, data, token, done. An error after the stream has started arrives as an error event, and the stream closes without done; the HTTP status of the stream is always 200. After done, a followups event with suggested next questions can arrive. Ignore event types you do not handle.
With stream=false: application/json with an AnswerResponse body (plus conversation_id).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
text/event-stream
application/json
answerstringrequiredquestion_idintegerrequiredquerystringcollectionstringrequiredprovenancearray of NumberProvenanceemptystringAllowed values:
no_hitsrestrictedguardrailno_data_for_periodbasisAnswerBasisverificationAnswerVerificationalt_periodsarray of AnswerAltPerioditems ≤ 6
drilldownarray of AnswerDrilldownitems ≤ 20
restrictedRestrictedInfoguardrailGuardrailVerdictverified_onlybooleancachedbooleancache_hitAnswerCacheHitout_of_scopeAnswerOutOfScopeattachmentsarray of Attachmentexport_errorstringtoolsstring | nullWhy tools were used for this answer:
request(asked for explicitly);compare,compute,action(based on the question);needs_calc(a calculation over tables is needed);summary(an overview of a collection or documents);mcp(the organization has connected external MCP servers).Allowed values:
requestcomparecomputeactionneeds_calcsummarymcpnulltool_callsarray of ToolCallInfocalculationsarray of Calculationpending_actionsarray of PendingActionconversation_idstringOnly for
POST /v1/chatwith a conversation.answer_idstringID of the answer object.
400The request is invalid: a parameter value or the state of the object does not allow the action (`detail` is a message).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
401No credentials were sent (neither a session cookie nor an API key), or the key was not found.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
403The action is not allowed: the role is insufficient, there is no access to the collection or card, the request runs in “View as” mode, or the organization is suspended or deleted (`detail` is an object with `code: org_suspended | org_deleted`).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
404The object does not exist or is not available to you. The API does not confirm that a restricted object exists.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
422Validation error: the body or parameters do not match the schema (`detail` is a list of validation errors), or a parameter value is out of range (`detail` is a message).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
429Too many requests (`api.rate_limited`), the organization's quota for the minute, day or month is used up (`api.quota_exceeded`; `error.details` holds `quota`, `limit` and `reset_at`), the organization's limit is reached, or the answer service is busy (`answers.engine_busy`). Wait for the time in the `Retry-After` header.
Response headers
Retry-AfterNumber of seconds to wait before you retry the request.
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
Error codes
Codes this endpoint can return in error.code, besides the general codes of every request.
- 400answers.empty_question
- 409answers.external_ai_disabled
- 400answers.last_message_not_user
- 404answers.no_collections
- 422answers.scope_invalid
- 401auth.not_authenticated
- 403auth.system_scope
- 403collections.no_access
- 404collections.not_found
- 404conversations.not_found
- 422conversations.title_empty
- 429limits.concurrent_answers
- 429limits.questions
- 403org.deleted
- 403org.suspended
- 404sources.not_found
- 403view_as.read_only
Safe retries
Send an Idempotency-Key header (for example a UUID) with each POST and PATCH. A retry with the same key within 24 hours returns the saved response instead of running the request again.
Rate limits
Responses carry the RateLimit and RateLimit-Policy headers and the earlier X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 response has Retry-After in seconds: wait and retry.