API reference

Chat and streaming

Ask a question over HTTP and read the answer as a stream of typed server-sent events.

Ask

POST /api/chat

The body carries the question, the connection to ask it against, and optionally a thread to continue and a model to use. Omitting the model uses the deployment default. See choosing a model.

The response is a text/event-stream.

Events

Each event has a type. Read them as a state machine rather than concatenating everything into a string.

EventMeaning
tokenA fragment of the assistant's prose. Append in order.
tool_callThe agent invoked a tool. Carries the tool name and arguments.
interruptThe run paused for input, most commonly SQL approval.
chartA rendered figure. Carries its spec and data.
usageToken and credit accounting for the turn.
doneThe turn is complete. Nothing further will arrive.

Always handle interrupt

A client that ignores interrupt will appear to hang: the stream is open and healthy, but the run is waiting on a decision that is never coming.

Resuming after an interrupt

POST /api/chat/resume

Post the decision (approve, approve-with-edits, or reject) along with the identifiers from the interrupt event. The run continues on the same thread with its context intact, and a new stream opens for the remainder.

See SQL approval for what the three outcomes do.

A minimal client

const res = await fetch("/api/chat", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({ message, configKey }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();

for (;;) {
  const { done, value } = await reader.read();
  if (done) break;
  for (const line of decoder.decode(value).split("\n")) {
    if (!line.startsWith("data:")) continue;
    const event = JSON.parse(line.slice(5));
    switch (event.type) {
      case "token":
        appendText(event.value);
        break;
      case "chart":
        renderChart(event.spec);
        break;
      case "interrupt":
        await promptForApproval(event);
        break;
    }
  }
}

On this page