AI

Send a chat message

Sends a message to the AI and creates a quest to process it. By default (async) the call returns immediately with a quest id; poll GET /api/v1/quests/{id} for the reply. Send wait: true to block until the reply is ready and receive it inline. A wait: true turn is bounded at about 45 seconds: one that runs longer is ended (unused credits refunded) and answered with a 504 naming the quest in quest_id. Send long or tool-heavy turns (large attachments, tool calls) in the default async mode and poll instead. A tool that produced machine-readable state reports it under toolPayloads - an array of { type, payload } entries in emission order, alongside (never instead of) the prose reply - on the wait: true body and on the polled quest. A turn can FAIL after the ACK - reported on the polled quest as type: "error", since the ACK was already sent. A terminal status: "stopped" (a missing session, a user-cancelled turn) is ALSO a failure even without type: "error" - it carries an explanatory string in reply/replies rather than an answer. type is the failure signal for the classified failure classes (an abort, a provider timeout, credit exhaustion); errorCode is an optional refinement present only when the failure is a classified billing reason. A recovered stuck quest is NOT in that list: one that still has renderable content resolves as a success by design. QUEST_ERROR_CODES has two members, but only insufficient_credits is raised as a quest errorCode by any current throw site on this endpoint - spend_cap_exceeded is thrown only by the embed chat route's pre-flight, which fires outside the process try/catch that would classify it onto a quest. A caller must treat type: "error" OR a terminal status: "stopped" as failure even when errorCode is absent, and must not read reply as an answer without checking those first. Authenticate with an API key (b4m_live_) or a JWT. Session resolution: pass sessionId to continue an existing notebook. An API-key caller that omits it gets a BRAND-NEW notebook rather than the notebook the human last had open, and newConversation: true forces a new notebook for any auth mode; both return the new id as sessionId, so the caller can continue the conversation by passing it back. A first-party JWT caller that omits sessionId keeps the last-opened-notebook fallback. Sending sessionId and newConversation together is a 422.

post/api/chat

Request

  • Base URL: https://your-deployment.example.com
  • URL: https://your-deployment.example.com/api/chat
  • Auth: one of:
    • HTTP bearer
    • API key in header x-api-key

Request body

sessionIdstring nullable
newConversationboolean
messagestring required
organizationIdstring
modelstring
temperaturenumber
max_tokensnumber
maxTokensnumber
maxOutputTokensnumber
streamboolean
historyCountnumber
fileIdsstring[]
waitboolean
enableToolsboolean
toolMode'fast' | 'smart'
toolsstring[]

Explicit tool ids to offer the model. A non-empty array enables tools on its own; no companion toolMode or enableTools is required. Merged with the auto-selected set under toolMode: "smart", and ignored under toolMode: "fast". This list ADDS to what is offered rather than restricting it - the server still offers tools of its own (for example knowledge retrieval when the session has reachable documents). Unrecognized ids are dropped rather than rejecting the request; the response reports the surviving set as tools.effectiveTools and the ids that are not tools in this deployment as tools.unrecognizedTools, since no endpoint enumerates the valid ids. unrecognizedTools is reported under every toolMode - it describes the ids, not what the mode did with them - so under toolMode: "fast" an id can be absent from effectiveTools (the mode discarded it) without being unrecognized. Both reported lists are deduplicated, and unrecognizedTools names at most the first 10 distinct ids.

enableQuestMasterboolean
enableMementosboolean
enableAgentsboolean
promptMode'raw' | 'grounded' | 'surface'
skip_auto_offersboolean

Suppress tools the server would otherwise attach on its own for this session (the knowledge-base search offer, in-app view navigation, blog drafting/editing/publishing, skill invocation, and every tool from a connected MCP server). Native tools you request explicitly in tools are unaffected, but an MCP server tool cannot be named through this field, so with this flag set a caller with an MCP server connected sees none of its tools regardless of tools. One system-prompt block goes with them: withholding in-app view navigation also drops the view-registry block that exists only to describe it. No other prompt content changes. This does not switch off retrieval: a session with forced knowledge retrieval still retrieves, and documents already attached to the session are still placed in the prompt directly. Any promptMode suppresses these too, so false has no effect alongside one.

includePromptDetailsboolean
includeSystemPromptboolean
systemPromptstring

System-prompt text for this request only, never persisted. Rendered as a defended block appended after every other system-prompt source, with prose instructing the model to defer to organization, session and data-lake guidance. Over the cap is a 422, never truncated.

Example request

{
  "message": "How do I reset my password?",
  "toolMode": "smart"
}

Response

Message accepted - NOT a completed turn. The default (async) path returns this queued ACK; the outcome arrives on GET /api/v1/quests/{id} (see the sendChatMessage200PollResult schema). With wait: true the body is instead the completed turn: the ACK fields plus the reply (response/responses), toolPayloads, createdAt, performance timings and, when requested, promptDetails/promptText. A turn that FAILS still resolves with 200, never a 4xx, on both that wait: true body and the polled quest (GET /api/v1/quests/{id}) - the prose explaining why lands in reply/response like any other answer, so the reply text alone cannot tell a failure from an answer. type is the field that can: both surfaces carry it unconditionally, so match on type: "error" first - it covers credit exhaustion, a provider timeout or overload, and an in-process aborted turn; a real answer carries the turn's actual completion type instead ("message" for an ordinary reply). Two related states do NOT set type: "error": a user-cancelled turn resolves as status: "stopped" with type left at "message", and a recovered stuck quest that still has renderable content resolves as a success (status: "done", no error) by design, to avoid destroying content to report a failure. errorCode then names the failure reason, but only for the billing failures that have one - "insufficient_credits" today; it is absent on every other type: "error" turn, so never use its absence to infer success. On a real answer errorCode is absent from the wait: true body. The body also carries sessionId, the notebook the turn was recorded in - for an API-key caller that sent none (or any caller sending newConversation: true), that is the freshly created notebook's id; pass it back as the request's sessionId to continue. Contrast the tts/music/soundEffects contracts, which reject synchronously with a 422 carrying the same errorCode vocabulary.

OR

Changes

No recorded changes to this operation across all 1 revision of this API.