Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/IconDean/research-agent/llms.txt

Use this file to discover all available pages before exploring further.

POST /api/research/stream runs the same full research pipeline as POST /api/research but delivers results progressively over a Server-Sent Events (SSE) connection. Instead of waiting for a single blocking response, your client receives a real-time stream of typed event messages as the agent plans its strategy, performs web searches, fetches pages, detects gaps, and ultimately assembles the final report. This is the endpoint used by the built-in web UI and is the recommended choice for any user-facing integration.

Request

POST /api/research/stream
HeaderValue
Content-Typeapplication/json

Body fields

question
string
required
The natural-language research question to investigate. Must be between 3 and 2000 characters. Whitespace-only strings are rejected with a 400 error before the stream opens.

Response

Content-Type: text/event-stream The response body is a continuous stream of SSE messages. Each message follows the standard SSE wire format:
data: {"type": "<event_type>", "detail": "<detail_string>"}\n\n
Every event object has exactly two fields:
  • type — a fixed string identifying the event category (see the table below)
  • detail — a string whose content varies by event type
The stream is terminated by an end event. The report or error event always arrives immediately before end.

Event types

The end event is always the final message in the stream, regardless of whether the research succeeded or failed. Always listen for end to know when it is safe to close the connection.
TypeWhen it firesdetail content
startResearch pipeline beginsThe research question as submitted
planAfter the agent produces its research plan"Type: X, Strategy: Y, Queries: Q1, Q2, …"
thinkingAt each internal agent iteration"Iteration N" or a short description of the current reasoning step
searchEach time the agent issues a web searchThe query string sent to the search engine
fetchEach time the agent fetches a web pageThe URL being retrieved
blockA source is rejected during quality evaluation"<URL> (score: X.XX)"
gapsAfter gap-detection analysis completes"Gaps found: N, Follow-up queries: Q1, Q2, …"
reportResearch complete — final outputThe full markdown report string
errorFatal error during researchHuman-readable error message
endAlways the last eventNo meaningful detail (may be an empty string)

Error responses (before stream opens)

StatusCondition
400question is empty or whitespace-only
422Malformed body or question fails length validation
If an error occurs after the stream has already opened (e.g. an API key problem discovered mid-run), it is delivered as an error event followed by an end event — the HTTP status remains 200 at that point.

Examples

curl -X POST http://127.0.0.1:8000/api/research/stream \
  -H "Content-Type: application/json" \
  -d '{"question": "What are the latest advances in nuclear fusion energy?"}' \
  --no-buffer

Example SSE output

data: {"type": "start", "detail": "What are the latest advances in nuclear fusion energy?"}

data: {"type": "plan", "detail": "Type: factual, Strategy: broad survey, Queries: nuclear fusion 2024, NIF ignition, private fusion startups"}

data: {"type": "thinking", "detail": "Iteration 1"}

data: {"type": "search", "detail": "nuclear fusion breakthroughs 2024"}

data: {"type": "fetch", "detail": "https://www.science.org/content/article/fusion-ignition"}

data: {"type": "block", "detail": "https://paywalled-journal.example.com/fusion (score: 0.18)"}

data: {"type": "gaps", "detail": "Gaps found: 2, Follow-up queries: SPARC reactor timeline, fusion investment 2025"}

data: {"type": "report", "detail": "# Nuclear Fusion Energy: Recent Advances\n\n..."}

data: {"type": "end", "detail": ""}

Client-side cancellation

To cancel an in-flight stream from the browser or Node.js, pass an AbortController signal to fetch and call abort() when needed:
const controller = new AbortController();

fetch("http://127.0.0.1:8000/api/research/stream", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ question }),
  signal: controller.signal,
});

// Cancel at any time:
controller.abort();
The server-side generator will be interrupted when the client disconnects. The built-in TypeScript client (api.ts) exposes this pattern via the abort() function returned alongside the done promise.

Build docs developers (and LLMs) love