Skip to main content
Both the Research Agent (/v1/research-agent) and the Workflows execution endpoint (/v1/workflow/execute) return a single, long-lived HTTP response that streams a sequence of typed events using Server-Sent Events (SSE). This page is the canonical reference for that stream: the event format, every public message type, the typical order of events in a request, and a complete handler you can copy into your codebase.

The SSE format

Each event is a single line beginning with data: , followed by a JSON document terminated by a newline:
Lines that do not start with data: are heartbeats or comments and should be ignored. The stream ends after a COMPLETE (or ERROR) event.
The Research Agent and Workflows use slightly different envelopes:
  • Research Agent wraps the event in a message field: {"chat_id": "...", "message": {"type": "...", ...}}
  • Workflows wraps it in a delta field: {"request_id": "...", "execution_id": "...", "delta": {"type": "...", ...}}
Examples in this guide use the Research Agent envelope. For Workflows, read the typed event from event["delta"] instead of event["message"].

Message types

Eleven public message types may appear in the stream. The type field is the only field guaranteed to be present on every message and is the discriminator your handler should dispatch on. Every message also carries an optional message_id (groups related chunks; see below) and a role (defaults to "assistant"; sub-agents may use other role names).

Typical lifecycle

A request that runs to completion emits events in roughly this order. Some types are optional and depend on the request configuration.
A request that hits a recoverable problem may also emit LLM_RETRY (informational, agent retries automatically) or TOOL_ERROR (per-tool failure; the agent may try a different approach). An unrecoverable failure emits ERROR and terminates the stream without a COMPLETE event.

Per-type reference

PLANNING

Emitted when the agent’s research plan changes. The full plan is sent each time; clients should replace any previously displayed plan with the latest version rather than diffing.
Step statuses: NOT_STARTED, IN_PROGRESS, COMPLETED, SKIPPED, FAILED.

THINKING

The agent’s intermediate reasoning between tool calls. content may be a partial chunk; concatenate consecutive chunks that share the same message_id to assemble a single reasoning block.
THINKING is informational. Many integrations suppress it from the user-facing UI and show only ANSWER content.

ACTION

Notification that the agent is calling a tool. Useful for showing per-tool progress in the UI (e.g., “Searching for earnings transcripts…”).
The corresponding result arrives later as an AUDIT message.

AUDIT

Detailed traces of tool executions. Each entry in audit_traces carries an audit_type discriminator and a tool_id that matches references in subsequent GROUNDING messages.
Audit trace types include SearchAuditV1, MarkdownAuditV1, StructuredReportAuditV1, SubAgentStartedAuditV1, and SubAgentCompletedAuditV1. The full schema for each is defined in the OpenAPI specs.

GROUNDING

Citations linking spans of the upcoming ANSWER text to their sources. Each reference carries start and end character offsets into the cumulative answer text. See the Grounding and citations guide for the full citation-rendering pattern, including the buffering requirement.

ANSWER

A chunk of the final answer text. Multiple ANSWER events fire as the model generates output. Concatenate content values in arrival order to reassemble the full answer. Grounding offsets index into this cumulative concatenated text.

STRUCTURED_OUTPUT

Only emitted when the request included a structured_output_schema. Fires once, after the final ANSWER chunk, with the extracted JSON. See the request schema for constraints on the input schema (top-level must be an object or list-of-objects).

LLM_RETRY

Informational: the agent is retrying a transient LLM failure (rate limit, timeout, etc.). No client action is required; the agent will continue automatically. Log if useful for observability.

TOOL_ERROR

A specific tool failed. The agent may recover by calling a different tool or synthesizing without that source. The stream continues. See Error handling for guidance on what to surface to users.

ERROR

Unrecoverable. The stream terminates without a COMPLETE event. Surface this to the user.

COMPLETE

End of stream. Carries the final token consumption breakdown and, for Research Agent requests, a checkpoint_id that can be passed as from_checkpoint_id in a follow-up request. See Conversation continuity.

message_id and chunk grouping

The optional message_id field groups chunks that belong to a single logical unit. The most common case is ANSWER: a long answer arrives as many small ANSWER events, all sharing the same message_id. Clients can use the id to detect a new answer turn versus a continuation of the current one. For most use cases, simply concatenating consecutive ANSWER chunks in arrival order works.

Canonical Python streaming handler

The handler below dispatches on type, reassembles the answer text, collects grounding references, and prints a useful per-event log. It is the reference implementation the rest of the docs build on.
For Workflows, the same handler works after two changes: post to https://agents.bigdata.com/v1/workflow/execute with a workflow payload, and read the typed event from event["delta"] instead of event["message"].

Forward compatibility

New message types may be added in future API versions. Clients should treat unknown type values as informational and continue processing the stream rather than raising. The else branch in the handler above demonstrates this pattern.

Next steps

Grounding and citations

How GROUNDING references map to answer text spans, and how to render inline citations.

Error handling

The difference between ERROR, TOOL_ERROR, and LLM_RETRY, plus HTTP-level failure modes.

Conversation continuity

Resuming Research Agent chats with checkpoints and Workflows runs with execution IDs.

Research Agent quickstart

Build your first Research Agent request end-to-end.