Repository Public
1# Streaming interactions23When creating an Interaction, you can set `stream: true` to incrementally stream the response using [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) (SSE).45### Python67 from google import genai89 client = genai.Client()1011 stream = client.interactions.create(12 model="gemini-3-flash-preview",13 input="Count to from 1 to 25.",14 stream=True,15 )16 for event in stream:17 if event.event_type == "step.delta":18 if event.delta.type == "text":19 print(event.delta.text, end="", flush=True)2021### JavaScript2223 import { GoogleGenAI } from "@google/genai";2425 const client = new GoogleGenAI({});2627 const stream = await client.interactions.create({28 model: "gemini-3-flash-preview",29 input: "Count to from 1 to 25.",30 stream: true,31 });32 for await (const event of stream) {33 if (event.event_type === "step.delta") {34 if (event.delta.type === "text") {35 process.stdout.write(event.delta.text);36 }37 }38 }3940### REST4142 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \43 -H "x-goog-api-key: $GEMINI_API_KEY" \44 -H "Content-Type: application/json" \45 -H "Api-Revision: 2026-05-20" \46 --no-buffer \47 -d '{48 "model": "gemini-3-flash-preview",49 "input": "Count to from 1 to 25.",50 "stream": true51 }'5253 event: interaction.created54 data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}5556 event: interaction.status_update57 data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}5859 event: step.start60 data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}6162 event: step.delta63 data: {"index":0,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}6465 event: step.stop66 data: {"index":0,"event_type":"step.stop"}6768 event: step.start69 data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}7071 event: step.delta72 data: {"index":1,"delta":{"text":"1, 2, 3, 4, 5, 6, ","type":"text"},"event_type":"step.delta"}7374 event: step.delta75 data: {"index":1,"delta":{"text":"7, 8, 9, 10, 11, 12, 13,","type":"text"},"event_type":"step.delta"}7677 ...7879 event: step.stop80 data: {"index":1,"event_type":"step.stop"}8182 event: interaction.completed83 data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":346,"total_input_tokens":11,"input_tokens_by_modality":[{"modality":"text","tokens":11}],"total_cached_tokens":0,"total_output_tokens":90,"total_tool_use_tokens":0,"total_thought_tokens":245},"created":"2026-05-12T18:44:51Z","updated":"2026-05-12T18:44:51Z","service_tier":"standard","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.completed"}8485 event: done86 data: [DONE]8788## Event types8990Each server-sent event includes a named `event_type` and associated JSON data. The Interactions API uses a symmetric streaming model where all content---text, tool calls, thinking---flows through a consistent **step-based** event.9192Each stream follows this event flow:93941. `interaction.created`: The interaction is created, includes metadata (ID, model, status).952. A series of **steps** , each consisting of:96 - A `step.start` event, indicating the step type (e.g., `model_output`, `thought`, `function_call`).97 - One or more `step.delta` events with incremental data for that step.98 - A `step.stop` event marking the step as complete.993. An `interaction.completed` event with final `usage` statistics.100101When you set `stream: false`, the API returns a single `interaction` object with a `steps` array. Each element in `steps` is the fully assembled version of one `step.start` → `step.delta`(s) → `step.stop` cycle.102103### `interaction.created`104105Sent when the interaction is first created. Contains the interaction ID, model, and initial status.106107 event: interaction.created108 data: {"interaction": {"id": "...", "model": "gemini-3-flash-preview", "status": "in_progress", "object": "interaction"}, "event_type": "interaction.created"}109110### `interaction.status_update`111112Signals an interaction-level status transition. May appear between steps.113114 event: interaction.status_update115 data: {"interaction_id": "...", "status": "in_progress", "event_type": "interaction.status_update"}116117### `step.start`118119Marks the beginning of a new step. Contains the step `type` and `index`. The step type determines which delta types to expect and how the step appears in a non-streaming response:120121| Step Type | Expected Delta Types | Description |122|---|---|---|123| `model_output` | `text`, `image`, `audio` | The model's final response content. |124| `thought` | `thought_signature`, `thought_summary` | Chain-of-thought reasoning. `summary` is only present when `thinking_summaries` is enabled. |125| `function_call` | `arguments_delta` | A request for the client to execute a function. Sets interaction status to `requires_action`. |126| Server-side tools | Varies by tool | Tools executed by the API (e.g., `google_search_call`, `google_search_result`, `code_execution_call`, `code_execution_result`). |127128See the [Interactions API reference](https://ai.google.dev/api/interactions) for the full list.129130 event: step.start131 data: {"index": 0, "step": {"type": "model_output"}, "event_type": "step.start"}132133For function calls, the step includes the function name, id and empty arguments `{}`134135 event: step.start136 data: {"index": 0, "step": {"type": "function_call", "id":"un6k8t18", "name": "get_weather", "arguments":{}}, "event_type": "step.start"}137138### `step.delta`139140Incremental data for the current step. The `delta` object contains a `type` field that determines its shape.141142**Examples:**143144**`text`:** Incremental text token from a `model_output` step:145146 event: step.delta147 data: {"index": 0, "delta": {"type": "text", "text": "Hello, my name is Phil"}, "event_type": "step.delta"}148149 event: step.delta150 data: {"index": 0, "delta": {"type": "text", "text": ", and I live in Germany." }, "event_type": "step.delta"}151152**`image`:** Base64-encoded image data from a `model_output` step:153154 event: step.delta155 data: {"index": 0, "delta": {"type": "image", "mime_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg..."}, "event_type": "step.delta"}156157**`thought_summary`:** Thinking summary content from a `thought` step:158159 event: step.delta160 data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "I need to find the GCD..."}}, "event_type": "step.delta"}161162**`arguments_delta`:** (Partial) JSON string for function call arguments. Must be accumulated across deltas:163164 event: step.delta165 data: {"index": 0, "delta": {"type": "arguments_delta", "arguments": "{\"location\": \"San Francisco, CA\"}"}, "event_type": "step.delta"}166167These are some of the most common delta types. For the complete list of all delta types, see the [Interactions API reference](https://ai.google.dev/api/interactions).168169### `step.stop`170171Marks the end of a step. Contains the step `index`.172173 event: step.stop174 data: {"index": 0, "event_type": "step.stop"}175176### `interaction.completed`177178Sent when the interaction is finished. Contains the final interaction object with `usage` statistics. In non-streaming mode, this is the top-level response object itself. Does not include `steps` in the response.179180 event: interaction.completed181 data: {"interaction": {"id": "v1_abc123", "status": "completed", "usage": {"total_input_tokens": 7, "total_output_tokens": 12, "total_tokens": 19}}, "event_type": "interaction.completed"}182183### `error`184185Sent when an error occurs during the interaction. Contains an error object with a message and code.186187 event: error188 data: {"error":{"message":"Deadline expired before operation could complete.","code":"gateway_timeout"},"event_type":"error"}189190## Streaming with tools191192The Interactions API supports streaming with both client-side tools (function193calling) and server-side tools (Google Search, Code Execution, etc.) in a single194request. During streaming, tool invocations appear as typed steps in the event195stream. For function calls, the `step.start` event delivers the function name,196and `step.delta` events stream the arguments as JSON strings197(`arguments_delta`). You must accumulate these deltas to get the full arguments.198Server-side tools like Google Search are executed automatically by the API,199producing `google_search_call` and `google_search_result` steps.200201### Streaming with function calling202203To perform function calling with streaming, the client must handle a multi-turn204conversation:2052061. **Turn 1 (Function Request):** Call `interactions.create` with `stream: true` and your defined `tools`. The API will stream a `function_call` step. You must accumulate the incremental argument JSON strings (`arguments_delta`) from `step.delta` events until the interaction completes with the status `requires_action`.2072. **Turn 2 (Sending Result):** Call `interactions.create` again, passing the `previous_interaction_id` (matching the ID of the first interaction) and sending a `function_result` block within the `input` array. This resumes the stream, allowing the model to generate its final response.208209### Python210211 from google import genai212213 client = genai.Client()214215 weather_tool = {216 "type": "function",217 "name": "get_weather",218 "description": "Get the current weather in a given location",219 "parameters": {220 "type": "object",221 "properties": {222 "location": {223 "type": "string",224 "description": "The city and state, e.g. San Francisco, CA"225 }226 },227 "required": ["location"]228 }229 }230231 # Turn 1: Request function call232 stream = client.interactions.create(233 model="gemini-3-flash-preview",234 tools=[weather_tool],235 input="What is the weather in Paris right now?",236 stream=True,237 )238239 first_interaction_id = None240 func_call_id = None241 func_call_name = None242 func_args_accumulated = ""243244 for event in stream:245 if event.event_type == "interaction.created":246 first_interaction_id = event.interaction.id247 elif event.event_type == "step.start":248 step = event.step249 if step.type == "function_call":250 func_call_id = step.id251 func_call_name = step.name252 elif event.event_type == "step.delta":253 if event.delta.type == "arguments_delta":254 func_args_accumulated += event.delta.arguments255256 # Turn 2: Execute tool and send the result back to resume stream257 if func_call_id:258 # Execute weather_tool using accumulated arguments259 # args = json.loads(func_args_accumulated)260 dummy_result = {261 "content": [{"type": "text", "text": '{"weather": "Sunny and 22°C"}'}]262 }263264 stream2 = client.interactions.create(265 model="gemini-3-flash-preview",266 previous_interaction_id=first_interaction_id,267 input=[{268 "type": "function_result",269 "name": func_call_name,270 "call_id": func_call_id,271 "result": dummy_result272 }],273 stream=True,274 )275276 for event in stream2:277 if event.event_type == "step.delta":278 if event.delta.type == "text":279 print(event.delta.text, end="", flush=True)280281### JavaScript282283 import { GoogleGenAI } from "@google/genai";284285 const client = new GoogleGenAI({});286287 const weatherTool = {288 type: "function",289 name: "get_weather",290 description: "Get the current weather in a given location",291 parameters: {292 type: "object",293 properties: {294 location: {295 type: "string",296 description: "The city and state, e.g. San Francisco, CA"297 }298 },299 required: ["location"]300 }301 };302303 // Turn 1: Request function call304 const stream = await client.interactions.create({305 model: "gemini-3-flash-preview",306 tools: [weatherTool],307 input: "What is the weather in Paris right now?",308 stream: true,309 });310311 let firstInteractionId = null;312 let funcCallId = null;313 let funcCallName = null;314 let funcArgsAccumulated = "";315316 for await (const event of stream) {317 if (event.event_type === "interaction.created") {318 firstInteractionId = event.interaction.id;319 } else if (event.event_type === "step.start") {320 const step = event.step;321 if (step.type === "function_call") {322 funcCallId = step.id;323 funcCallName = step.name;324 }325 } else if (event.event_type === "step.delta") {326 if (event.delta.type === "arguments_delta") {327 funcArgsAccumulated += event.delta.arguments;328 }329 }330 }331332 // Turn 2: Execute tool and send the result back to resume stream333 if (funcCallId && firstInteractionId && funcCallName) {334 // const args = JSON.parse(funcArgsAccumulated);335 const dummyResult = {336 content: [{ type: "text", text: '{"weather": "Sunny and 22°C"}' }]337 };338339 const stream2 = await client.interactions.create({340 model: "gemini-3-flash-preview",341 previous_interaction_id: firstInteractionId,342 input: [{343 type: "function_result",344 name: funcCallName,345 call_id: funcCallId,346 result: dummyResult347 }],348 stream: true,349 });350351 for await (const event of stream2) {352 if (event.event_type === "step.delta") {353 if (event.delta.type === "text") {354 process.stdout.write(event.delta.text);355 }356 }357 }358 }359360### REST361362**Turn 1:** Request function call363364 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \365 -H "x-goog-api-key: $GEMINI_API_KEY" \366 -H "Content-Type: application/json" \367 -H "Api-Revision: 2026-05-20" \368 --no-buffer \369 -d '{370 "model": "gemini-3-flash-preview",371 "input": "What is the weather in Paris right now?",372 "stream": true,373 "tools": [374 {375 "type": "function",376 "name": "get_weather",377 "description": "Get the current weather in a given location",378 "parameters": {379 "type": "object",380 "properties": {381 "location": {382 "type": "string",383 "description": "The city and state, e.g. San Francisco, CA"384 }385 },386 "required": ["location"]387 }388 }389 ]390 }'391392**Turn 2:** Send the function result using the `previous_interaction_id` and `call_id` from Turn 1393394 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \395 -H "x-goog-api-key: $GEMINI_API_KEY" \396 -H "Content-Type: application/json" \397 -H "Api-Revision: 2026-05-20" \398 --no-buffer \399 -d '{400 "model": "gemini-3-flash-preview",401 "previous_interaction_id": "v1_ChdGUVFJYXBXVUdLVEF4TjhQ...",402 "stream": true,403 "input": [404 {405 "type": "function_result",406 "name": "get_weather",407 "call_id": "CALL_ID",408 "result": {409 "content": [410 {411 "type": "text",412 "text": "{\"weather\": \"Sunny and 22°C\"}"413 }414 ]415 }416 }417 ]418 }'419420### Streaming with multiple tools421422The following example uses both a `function` tool and `google_search` in one request:423424### Python425426 from google import genai427428 client = genai.Client()429430 tools = [431 {"type": "google_search"},432 {433 "type": "function",434 "name": "get_weather",435 "description": "Get the current weather in a given location",436 "parameters": {437 "type": "object",438 "properties": {439 "location": {440 "type": "string",441 "description": "The city and state, e.g. San Francisco, CA"442 }443 },444 "required": ["location"]445 }446 }447 ]448449 stream = client.interactions.create(450 model="gemini-3-flash-preview",451 tools=tools,452 input="Search what it the largest mountain in Europe and what the weather is there right now?",453 stream=True,454 )455 for event in stream:456 if event.event_type == "step.start":457 step = event.step458 print(f"\n--- Step {event.index}: {step.type} ---")459 # Show details for tool steps460 if step.type == "google_search_call":461 print(f" Search ID: {step.id}")462 elif step.type == "google_search_result":463 print(f" Result for: {step.call_id}")464 elif step.type == "function_call":465 print(f" Function: {step.name}({step.arguments})")466 elif event.event_type == "step.delta":467 if event.delta.type == "text":468 print(event.delta.text, end="", flush=True)469 elif event.delta.type == "google_search_call":470 print(f" Queries: {event.delta.arguments}")471 elif event.delta.type == "arguments_delta":472 print(f" Args chunk: {event.delta.arguments}", end="", flush=True)473 elif event.event_type == "interaction.completed":474 print(f"\n\nStatus: {event.interaction.status}")475 if event.interaction.status == "requires_action":476 print("Action required: provide function call results to continue.")477478### JavaScript479480 import { GoogleGenAI } from "@google/genai";481482 const client = new GoogleGenAI({});483484 const tools = [485 { type: "google_search" },486 {487 type: "function",488 name: "get_weather",489 description: "Get the current weather in a given location",490 parameters: {491 type: "object",492 properties: {493 location: {494 type: "string",495 description: "The city and state, e.g. San Francisco, CA"496 }497 },498 required: ["location"]499 }500 }501 ];502503 const stream = await client.interactions.create({504 model: "gemini-3-flash-preview",505 tools: tools,506 input: "Search what it the largest mountain in Europe and what the weather is there right now?",507 stream: true,508 });509 for await (const event of stream) {510 if (event.event_type === "step.start") {511 const step = event.step;512 console.log(`\n--- Step ${event.index}: ${step.type} ---`);513 // Show details for tool steps514 if (step.type === "google_search_call") {515 console.log(` Search ID: ${step.id}`);516 } else if (step.type === "google_search_result") {517 console.log(` Result for: ${step.call_id}`);518 } else if (step.type === "function_call") {519 console.log(` Function: ${step.name}(${JSON.stringify(step.arguments)})`);520 }521 } else if (event.event_type === "step.delta") {522 if (event.delta.type === "text") {523 process.stdout.write(event.delta.text);524 } else if (event.delta.type === "google_search_call") {525 console.log(` Queries: ${JSON.stringify(event.delta.arguments?.queries)}`);526 } else if (event.step.type === "google_search_result") {527 console.log(` Result for: ${event.step.call_id}`);528 } else if (event.delta.type === "arguments_delta") {529 process.stdout.write(` Args chunk: ${event.delta.arguments}`);530 }531 } else if (event.event_type === "interaction.completed") {532 console.log(`\n\nStatus: ${event.interaction.status}`);533 if (event.interaction.status === "requires_action") {534 console.log("Action required: provide function call results to continue.");535 }536 }537 }538539### REST540541 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \542 -H "x-goog-api-key: $GEMINI_API_KEY" \543 -H "Content-Type: application/json" \544 -H "Api-Revision: 2026-05-20" \545 --no-buffer \546 -d '{547 "model": "gemini-3-flash-preview",548 "input": "Search what it the largest mountain in Europe and what the weather is there right now?",549 "stream": true,550 "tools": [551 { "type": "google_search" },552 {553 "type": "function",554 "name": "get_weather",555 "description": "Get the current weather in a given location",556 "parameters": {557 "type": "object",558 "properties": {559 "location": {560 "type": "string",561 "description": "The city and state, e.g. San Francisco, CA"562 }563 },564 "required": ["location"]565 }566 }567 ]568 }'569570 event: interaction.created571 data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}572573 event: interaction.status_update574 data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}575576 event: step.start577 data: {"index":0,"step":{"id":"mkutnkgn","signature":"","type":"google_search_call"},"event_type":"step.start"}578579 event: step.delta580 data: {"index":0,"delta":{"signature":"...","type":"google_search_call","arguments":{"queries":["largest mountain in Europe"]}},"event_type":"step.delta"}581582 event: step.stop583 data: {"index":0,"event_type":"step.stop"}584585 event: step.start586 data: {"index":1,"step":{"call_id":"mkutnkgn","signature":"","type":"google_search_result"},"event_type":"step.start"}587588 event: step.delta589 data: {"index":1,"delta":{"signature":"...","type":"google_search_result","is_error":false},"event_type":"step.delta"}590591 event: step.stop592 data: {"index":1,"event_type":"step.stop"}593594 event: step.start595 data: {"index":2,"step":{"type":"thought"},"event_type":"step.start"}596597 event: step.delta598 data: {"index":2,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}599600 event: step.stop601 data: {"index":2,"event_type":"step.stop"}602603 event: step.start604 data: {"index":3,"step":{"id":"ktr5aysg","type":"function_call","name":"get_weather","arguments":{}},"event_type":"step.start"}605606 event: step.delta607 data: {"index":3,"delta":{"arguments":"{\"location\":\"Mount Elbrus, Russia\"}","type":"arguments_delta"},"event_type":"step.delta"}608609 event: step.stop610 data: {"index":3,"event_type":"step.stop"}611612 event: interaction.completed613 data: {"interaction":{"id":"v1_...","status":"requires_action","usage":{"total_tokens":299,"total_input_tokens":138,"input_tokens_by_modality":[{"modality":"text","tokens":138}],"total_cached_tokens":0,"total_output_tokens":20,"total_tool_use_tokens":0,"total_thought_tokens":141},"created":"2026-05-12T17:24:26Z","updated":"2026-05-12T17:24:26Z","service_tier":"standard","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.completed"}614615 event: done616 data: [DONE]617618## Streaming with thinking619620When the model uses thinking, you'll receive `thought` steps with two distinct delta types: `thought_summary` (incremental text or image summary content), and `thought_signature` (an encrypted representation of the model's internal reasoning, sent as the last delta before `step.stop`). If `thinking_summaries` is enabled, `thought_summary` deltas stream a summary of the model's reasoning. For more details on thinking, see the [Thinking guide](https://ai.google.dev/gemini-api/docs/interactions/thinking).621622### Python623624 from google import genai625626 client = genai.Client()627628 stream = client.interactions.create(629 model="gemini-3-flash-preview",630 input="What is the greatest common divisor of 1071 and 462?",631 generation_config={632 "thinking_summaries": "auto"633 },634 stream=True,635 )636 for event in stream:637 if event.event_type == "step.start":638 print(f"\n--- Step: {event.step.type} ---")639 elif event.event_type == "step.delta":640 if event.delta.type == "thought_summary":641 if event.delta.content.type == "text":642 print(event.delta.content.text, end="", flush=True)643 elif event.delta.type == "text":644 print(event.delta.text, end="", flush=True)645646### JavaScript647648 import { GoogleGenAI } from "@google/genai";649650 const client = new GoogleGenAI({});651652 const stream = await client.interactions.create({653 model: "gemini-3-flash-preview",654 input: "What is the greatest common divisor of 1071 and 462?",655 generation_config: {656 thinking_summaries: "auto",657 },658 stream: true,659 });660 for await (const event of stream) {661 if (event.event_type === "step.start") {662 console.log(`\n--- Step: ${event.step.type} ---`);663 } else if (event.event_type === "step.delta") {664 if (event.delta.type === "thought_summary") {665 if (event.delta.content.type === "text") {666 process.stdout.write(event.delta.content.text);667 }668 } else if (event.delta.type === "text") {669 process.stdout.write(event.delta.text);670 }671 }672 }673674### REST675676 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \677 -H "x-goog-api-key: $GEMINI_API_KEY" \678 -H "Content-Type: application/json" \679 -H "Api-Revision: 2026-05-20" \680 --no-buffer \681 -d '{682 "model": "gemini-3-flash-preview",683 "input": "What is the greatest common divisor of 1071 and 462?",684 "stream": true,685 "generation_config": {686 "thinking_summaries": "auto"687 }688 }'689690 event: interaction.created691 data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}692693 event: interaction.status_update694 data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}695696 event: step.start697 data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}698699 event: step.delta700 data: {"index":0,"delta":{"content":{"text":"**Implementing Euclidean Algorithm**\n\nI've just worked through a detailed example applying the Euclidean algorithm to find the GCD of 1071 and 462, confirming its step-by-step nature. The calculations went smoothly, tracking the remainders until zero. My focus is now solidifying the implementation logic, ensuring accuracy and considering potential edge cases. I'll translate this example into code.\n\n\n","type":"text"},"type":"thought_summary"},"event_type":"step.delta"}701702 event: step.delta703 data: {"index":0,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}704705 event: step.stop706 data: {"index":0,"event_type":"step.stop"}707708 event: step.start709 data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}710711 ...712713## Streaming background interactions714715The Interactions API supports running both models and agents in the background716using `background=True`. You can stream these background interactions to receive717progress updates and intermediate steps as they happen.718719For example, when streaming a720[Deep Research](https://ai.google.dev/gemini-api/docs/interactions/deep-research) agent:721722### Python723724 from google import genai725726 client = genai.Client()727728 stream = client.interactions.create(729 agent="deep-research-preview-04-2026",730 input="Research the latest advances in quantum computing.",731 stream=True,732 background=True,733 agent_config={734 "type": "deep-research",735 "thinking_summaries": "auto"736 }737 )738 for event in stream:739 if event.event_type == "step.start":740 print(f"\n--- Step: {event.step.type} ---")741 elif event.event_type == "step.delta":742 if event.delta.type == "text":743 print(event.delta.text, end="", flush=True)744 elif event.delta.type == "thought_summary":745 if event.delta.content.type == "text":746 print(event.delta.content.text, end="", flush=True)747 elif event.event_type == "interaction.completed":748 print(f"\n\nTotal Tokens: {event.interaction.usage.total_tokens}")749750### JavaScript751752 import { GoogleGenAI } from "@google/genai";753754 const client = new GoogleGenAI({});755756 const stream = await client.interactions.create({757 agent: "deep-research-preview-04-2026",758 input: "Research the latest advances in quantum computing.",759 stream: true,760 background: true,761 agent_config: {762 type: "deep-research",763 thinking_summaries: "auto"764 }765 });766 for await (const event of stream) {767 if (event.event_type === "step.start") {768 console.log(`\n--- Step: ${event.step.type} ---`);769 } else if (event.event_type === "step.delta") {770 if (event.delta.type === "text") {771 process.stdout.write(event.delta.text);772 } else if (event.delta.type === "thought_summary") {773 if (event.delta.content.type === "text") {774 process.stdout.write(event.delta.content.text);775 }776 }777 } else if (event.event_type === "interaction.completed") {778 console.log(`\n\nTotal Tokens: ${event.interaction.usage.total_tokens}`);779 }780 }781782### REST783784 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \785 -H "x-goog-api-key: $GEMINI_API_KEY" \786 -H "Content-Type: application/json" \787 -H "Api-Revision: 2026-05-20" \788 --no-buffer \789 -d '{790 "agent": "deep-research-preview-04-2026",791 "input": "Research the latest advances in quantum computing.",792 "stream": true,793 "background": true,794 "agent_config": {795 "type": "deep-research",796 "thinking_summaries": "auto"797 }798 }'799800 event: interaction.created801 data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.created"}802803 event: interaction.status_update804 data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}805806 event: step.start807 data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}808809 event: step.delta810 data: {"index":0,"delta":{"content":{"text":"***Generating research plan***\n\nTo best answer your request, I'm starting by constructing a comprehensive research plan. This will outline the key areas I need to investigate and the strategy I'll use to connect them."},"type":"thought_summary"},"event_type":"step.delta"}811812 ... (additional thought steps) ...813814 event: step.stop815 data: {"index":0,"event_type":"step.stop"}816817 event: step.start818 data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}819820 event: step.delta821 data: {"index":1,"delta":{"text":"# The Quantum Inflection Point: Exhaustive Analysis of Hardware, Algorithms, and Market Dynamics in 2026\n\n## Executive Summary\n\n..."},"event_type":"step.delta"}822823 event: step.stop824 data: {"index":1,"event_type":"step.stop"}825826 event: interaction.completed827 data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":1117031,"total_input_tokens":428865,"total_output_tokens":22294,"total_thought_tokens":26213},"created":"2026-05-12T17:24:27Z","updated":"2026-05-12T17:24:27Z","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.completed"}828829 event: done830 data: [DONE]831832## Streaming image generation833834The Interactions API supports streaming multiple output modalities simultaneously. By requesting both `text` and `image` in the `response_format`, you can receive interleaved text and generated images in the same stream.835836The following example uses `gemini-3.1-flash-image-preview` (Nano Banana 2) to search for information and generate a story with interleaved illustrations.837838### Python839840 from google import genai841842 client = genai.Client()843844 stream = client.interactions.create(845 model="gemini-3.1-flash-image-preview",846 tools=[{"type": "google_search", "search_types": ["web_search", "image_search"]}],847 input="Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",848 response_format=[849 {"type": "text"},850 {"type": "image"}851 ],852 stream=True,853 )854855 for event in stream:856 if event.event_type == "step.delta":857 if event.delta.type == "text":858 print(event.delta.text, end="", flush=True)859 elif event.delta.type == "image":860 print(f"\n[Image chunk: {len(event.delta.data)} bytes]", end="", flush=True)861862### JavaScript863864 import { GoogleGenAI } from "@google/genai";865866 const client = new GoogleGenAI({});867868 const stream = await client.interactions.create({869 model: "gemini-3.1-flash-image-preview",870 tools: [{ type: "google_search", search_types: ["web_search", "image_search"] }],871 input: "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",872 response_format: [873 { type: "text" },874 { type: "image" }875 ],876 stream: true,877 });878879 for await (const event of stream) {880 if (event.event_type === "step.delta") {881 if (event.delta.type === "text") {882 process.stdout.write(event.delta.text);883 } else if (event.delta.type === "image") {884 console.log(`\n[Image chunk: ${event.delta.data.length} bytes]`);885 }886 }887 }888889### REST890891 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \892 -H "x-goog-api-key: $GEMINI_API_KEY" \893 -H "Content-Type: application/json" \894 -H "Api-Revision: 2026-05-20" \895 --no-buffer \896 -d '{897 "model": "gemini-3.1-flash-image-preview",898 "input": "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",899 "stream": true,900 "tools": [901 { "type": "google_search",902 "search_types": ["web_search", "image_search"]903 }904 ],905 "generation_config": {906 "thinking_summaries": "auto"907 },908 "response_format": [909 { "type": "text" }, { "type": "image"}910 ]911 }'912913 event: interaction.created914 data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3.1-flash-image-preview"},"event_type":"interaction.created"}915916 event: interaction.status_update917 data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}918919 event: step.start920 data: {"index":0,"step":{"type":"model_output"},"event_type":"step.start"}921922 event: step.delta923 data: {"index":0,"delta":{"text":"Here is a short illustrated story about the Colosseum...\n\n### Part 1: The New Flavian Amphitheater\n\n...","type":"text"},"event_type":"step.delta"}924925 ...926927 event: step.stop928 data: {"index":0,"event_type":"step.stop"}929930 event: step.start931 data: {"index":1,"step":{"type":"thought"},"event_type":"step.start"}932933 event: step.delta934 data: {"index":1,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}935936 event: step.stop937 data: {"index":1,"event_type":"step.stop"}938939 event: step.start940 data: {"index":2,"step":{"type":"model_output"},"event_type":"step.start"}941942 event: step.delta943 data: {"index":2,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg...","type":"image"},"event_type":"step.delta"}944945 event: step.delta946 data: {"index":2,"delta":{"text":"### Part 2: The Hypogeum and the Wait\n\n...","type":"text"},"event_type":"step.delta"}947948 ...949950 event: step.stop951 data: {"index":2,"event_type":"step.stop"}952953 event: step.start954 data: {"index":3,"step":{"type":"thought"},"event_type":"step.start"}955956 event: step.delta957 data: {"index":3,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}958959 event: step.stop960 data: {"index":3,"event_type":"step.stop"}961962 event: step.start963 data: {"index":4,"step":{"type":"model_output"},"event_type":"step.start"}964965 event: step.delta966 data: {"index":4,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...","type":"image"},"event_type":"step.delta"}967968 event: step.delta969 data: {"index":4,"delta":{"text":"### Part 3: The Moment of Spectacle\n\n...","type":"text"},"event_type":"step.delta"}970971 ...972973 event: step.stop974 data: {"index":4,"event_type":"step.stop"}975976 event: interaction.completed977 data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":6128,"total_input_tokens":29,"total_output_tokens":6099,"output_tokens_by_modality":[{"modality":"image","tokens":4480}]}},"event_type":"interaction.completed"}978979 event: done980 data: [DONE]981982## Handling unknown events983984In accordance with the API's versioning policy, new event types and delta types may be added over time. Your code should handle unknown event types gracefully---log and skip any events you don't recognize rather than throwing an error.985986## What's next987988- Learn more about the [Interactions API](https://ai.google.dev/gemini-api/docs/interactions).989- Explore [Function calling](https://ai.google.dev/gemini-api/docs/interactions/function-calling) with tools.990- Learn about [Thinking](https://ai.google.dev/gemini-api/docs/interactions/thinking) for enhanced reasoning.991- Try the [Deep Research Agent](https://ai.google.dev/gemini-api/docs/interactions/deep-research) for long-running tasks.992- See the [Interactions API reference](https://ai.google.dev/api/interactions) for all event types and delta types.