Skip to content
Get Started

Agent API

Streaming

response.* SSE events on the Agent API, including the mirobody_tool_call side-channel.

Set stream: true on POST /v1/responses and the reply arrives as standard OpenAI Responses response.* SSE events — every frame is event: <type> + data: <json>, with a monotonic sequence_number. Official SDK stream loops consume it as-is.

from openai import OpenAI
client = OpenAI(api_key="mb_live_...", base_url="https://api.mirobody.ai/v1")
with client.responses.stream(
model="mirobody-flash",
input="How is my fasting glucose trending?",
user="alice",
) as stream:
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
EventMeaning
response.createdThe run started — carries a response snapshot with status: "in_progress".
response.in_progressFollows immediately (OpenAI parity).
response.output_item.addedA new output item opened (reasoning, message, or function_call) — carries output_index + the in-progress item.
response.reasoning_summary_part.added / .doneA reasoning summary part opened / closed.
response.reasoning_summary_text.delta / .doneProvider-supplied reasoning-summary fragments, then the full summary.
response.content_part.added / .doneAn answer content part opened / closed.
response.output_text.delta / .doneAnswer text fragments, then the full text — the channel most clients render.
response.function_call_arguments.delta / .doneA client-tool handoff’s arguments (see Function calling).
response.output_item.doneThe open item completed — carries the finished item.
response.mirobody_tool_callMirobody extension, side-channel — a built-in server tool was called. See below.
response.mirobody_tool_resultMirobody extension, side-channel — a built-in server tool’s result landed. See below.
response.completedTerminal: carries the full final response object (output, usage, tool_steps, health_records, citations).
response.failedTerminal error: carries a response snapshot with status: "failed" and an error object.

Items stream strictly one at a time: reasoning first (when the tier emits it), then the message, then any function_call handoffs — output_index increments per item, and the indexes match the final output array on response.completed.

Built-in server tools (data search, literature, …) are not output items — official SDKs would mis-parse unknown item types, so their trace rides a dedicated event that standard stream loops safely ignore:

event: response.mirobody_tool_call
data: {"type":"response.mirobody_tool_call","sequence_number":7,
"tool_step":{"id":"mtc_0","call_id":"call_1a2b...","name":"query_health_data",
"arguments":"{\"query\": \"fasting glucose last 90 days\"}"}}

It fires when the tool is called; it does not open an output item or advance output_index. Render it if you want an activity feed (“Searching your records…”); skip it and nothing breaks.

response.mirobody_tool_result is its pair, pushed when that tool’s result lands — the other half of the side-channel, equally ignorable:

event: response.mirobody_tool_result
data: {"type":"response.mirobody_tool_result","sequence_number":9,
"tool_step":{"id":"mtc_0","call_id":"call_1a2b...","name":"query_health_data",
"result":"...","truncated":false}}

Match a result to its call by id / call_id. The streamed result is truncated to 4096 characters (truncated: true when clipped); the full value is always on the final response object (response.completed) under tool_steps[].result.

On an upstream error the stream ends with response.failed (not a broken pipe):

event: response.failed
data: {"type":"response.failed","sequence_number":12,
"response":{"id":"resp_...","status":"failed",
"error":{"type":"upstream_error","message":"..."}}}

For the Answers API’s simpler chat.completion.chunk streaming, see Answers API → Streaming.