Chat & streaming
POST /v1/chat answers a question over one case. Set stream: true to receive Server-Sent Events while
the answer is generated.
Request
Section titled “Request”interface ChatRequest { case: "papers" | "cordis" | "patents" | "trials"; question: string; sessionId?: string; // continue a conversation stream?: boolean; // default false}Non-streaming
Section titled “Non-streaming”You get a single ChatResponse once generation finishes.
Streaming events
Section titled “Streaming events”With stream: true the response is text/event-stream. Each event is event: <type> followed by one
data: line with JSON:
| Event | Data | When |
|---|---|---|
delta |
{ "text": "…" } |
Every few tokens; concatenate in order |
citations |
{ "citations": [...], "clusters": [...] } |
Once evidence is final (usually near the end) |
done |
{ "sessionId": "…" } |
Last event of a successful answer |
error |
{ "message": "…" } |
Generation failed; the stream ends |
event: deltadata: {"text":"Knowledge graphs give LLMs "}
event: deltadata: {"text":"structured context [1]."}
event: citationsdata: {"citations":[{"nodeIndex":412,"nodeId":"paper_412","title":"…","snippet":"…","score":0.87}],"clusters":[]}
event: donedata: {"sessionId":"c6f1…"}Examples
Section titled “Examples”const ac = new AbortController();let answer = "";
for await (const ev of vol.chatStream({ case: "papers", question: "What is RAPTOR?" }, ac.signal)) { if (ev.type === "delta") answer += ev.text; if (ev.type === "citations") render(ev.citations, ev.clusters); if (ev.type === "done") sessionId = ev.sessionId; if (ev.type === "error") throw new Error(ev.message);}// ac.abort() stops generation earlyimport json, os, requests
with requests.post( "https://vol.example.com/api/v1/chat", headers={"X-API-Key": os.environ["VOL_API_KEY"], "Accept": "text/event-stream"}, json={"case": "papers", "question": "What is RAPTOR?", "stream": True}, stream=True, timeout=300,) as r: r.raise_for_status() event = "message" for line in r.iter_lines(decode_unicode=True): if not line: continue if line.startswith("event:"): event = line[6:].strip() elif line.startswith("data:"): data = json.loads(line[5:]) if event == "delta": print(data["text"], end="", flush=True) elif event == "citations": citations = data["citations"] elif event == "error": raise RuntimeError(data["message"])curl -N https://vol.example.com/api/v1/chat \ -H "X-API-Key: $VOL_API_KEY" -H "Content-Type: application/json" -H "Accept: text/event-stream" \ -d '{"case":"papers","question":"What is RAPTOR?","stream":true}'Conversations
Section titled “Conversations”Store the sessionId from done (or from the non-streaming response) and send it with the next question.
Follow-ups such as “and in clinical trials?” are then resolved in context.
Errors before the stream starts
Section titled “Errors before the stream starts”Authentication, validation and rate-limit errors are returned as normal JSON errors with a non-2xx status
before any event is sent; the SDK throws VolApiError from the first iteration.
- React:
<VolChat>or theuseVolChathook. - Any site: the
<vol-chat>Web Component.