DocubixDocs
Dashboard

Streaming Chat

Stream answers with Server-Sent Events.

Endpoint

POST/chat/stream

Same request body as POST /chat. Returns text/event-stream.

A stateless streaming variant is also available at POST /query/stream.

SSE protocol

The stream uses Server-Sent Events:

text
event: meta
data: {"conversation_id":"..."}

data: ATP is
data:  adenosine
data: [DONE]
  • event: meta — sent first with the conversation_id
  • data: ... — answer token chunks
  • data: [DONE] — stream finished

JavaScript example

javascript
const response = await fetch("https://api.docubix.com/chat/stream", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    api_key: "rag_live_your_api_key_here",
    message: "What is ATP?"
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const blocks = buffer.split("\n\n");
  buffer = blocks.pop() ?? "";

  for (const block of blocks) {
    for (const line of block.split("\n")) {
      if (line.startsWith("data: ")) {
        const data = line.slice(6);
        if (data === "[DONE]") return;
        process.stdout.write(data);
      }
    }
  }
}

React example

tsx
"use client";

import { useState } from "react";

export function ChatStream() {
  const [answer, setAnswer] = useState("");

  async function ask(message: string) {
    setAnswer("");
    const res = await fetch("https://api.docubix.com/chat/stream", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        api_key: process.env.NEXT_PUBLIC_DRAGON_KEY,
        message
      })
    });

    const reader = res.body!.getReader();
    const decoder = new TextDecoder();
    let buffer = "";

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      buffer += decoder.decode(value, { stream: true });
      const blocks = buffer.split("\n\n");
      buffer = blocks.pop() ?? "";
      for (const block of blocks) {
        for (const line of block.split("\n")) {
          if (!line.startsWith("data: ")) continue;
          const token = line.slice(6);
          if (token === "[DONE]") return;
          setAnswer((prev) => prev + token);
        }
      }
    }
  }

  return <pre>{answer}</pre>;
}

Next.js route example

Proxy streaming through your server so the API key stays private:

typescript
// app/api/chat/route.ts
import { NextRequest } from "next/server";

export async function POST(req: NextRequest) {
  const body = await req.json();

  const upstream = await fetch("https://api.docubix.com/chat/stream", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      api_key: process.env.DRAGON_API_KEY,
      message: body.message,
      conversation_id: body.conversation_id
    })
  });

  return new Response(upstream.body, {
    headers: { "Content-Type": "text/event-stream" }
  });
}