SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
39.8 KB

# Gemini Interactions API, managed agents, Environments API and dynamic/*

Status: DOCUMENTED + LIVE_VERIFIED (2026-09-18 run — see "Live verification" section at the end)

Sources (offline copies under sources/gemini/, retrieved 2026-09-18):

  • Reference: https://ai.google.dev/api/interactions (v1beta, 186 KB, incl. Credentials CRUD and the InteractionSseEvent union), https://ai.google.dev/api/interactions-api (same surface, alternate rendering), https://ai.google.dev/api/interactions-api-v1 (stable v1 subset), https://ai.google.dev/api/environments, https://ai.google.dev/api/all-methods
  • Discovery document generativelanguage v1beta rev. 20260918 (sources/gemini/discovery-v1beta.json): resources environments, environments.files.media, dynamic
  • Guides: https://ai.google.dev/gemini-api/docs/interactions-overview, …/interactions, …/streaming, …/background-execution, …/interactions-breaking-changes-may-2026, …/migrate-to-interactions, …/agents, …/managed-agents-quickstart, …/antigravity-agent, …/deep-research, …/custom-agents, …/agent-environment, …/agent-credentials, …/agent-hooks, …/webhooks, …/aistudio-agents, …/flex-inference, …/priority-inference, …/pricing (section "Pricing for agents"), …/api-versions
  • Model pages: …/models/deep-research-preview-04-2026, deep-research-max-preview-04-2026, deep-research-pro-preview-12-2025, antigravity-preview-05-2026
  • SDK surfaces: google-genai 2.24 (google/genai/_gaos/{interactions,agents,environments,files,credentials,triggers,webhooks}.py), @google/genai 2.23 (dist/genai.d.ts classes Interactions_2, Agents_2, Environments_2, Credentials_2, Triggers_2, Webhooks_2)
  • Live model list sources/gemini/models-api-raw.json (agents visible on this key: deep-research-preview-04-2026, deep-research-max-preview-04-2026, deep-research-pro-preview-12-2025, antigravity-preview-05-2026, antigravity-preview-09-2026)

Last verified: 2026-09-18 (docs only — no live call in this document; see the final section)

Machine-readable twins: generated/fragments/parameters/gemini-interactions.json (258 parameter records), generated/fragments/streaming-events/gemini-interactions.json (39 event records), tmp/gemini-parts/interactions-endpoints.json (40 endpoint records), tmp/gemini-parts/interactions-objects.json (67 object records).


# 1. What it is, and when to use it instead of generateContent

The Interactions API (POST /v1beta/interactions) is Google's newer, stateful surface for Gemini. Since June 2026 the docs call it "Generally Available and recommended for all new projects" while generateContent is "now considered legacy" but fully supported. One endpoint serves both models ("model": "gemini-3.8-flash") and agents ("agent": "deep-research-preview-04-2026", "agent": "antigravity-preview-09-2026", or the id of a custom agent you saved). Every call creates an Interaction resource whose steps[] is the chronological timeline of the turn (thoughts, tool calls/results, model_output).

Aspect models/*:generateContent (legacy) Interactions API
Path POST /v1beta/models/{model}:generateContent (+ :streamGenerateContent) POST /v1beta/interactions (stream via body stream: true); stable POST /v1/interactions
Casing camelCase (generationConfig, systemInstruction) snake_case everywhere (generation_config, previous_interaction_id) — camelCase fields are rejected with 400
Request shape contents[] { role, parts[] } input: string | Content | Content[] | Step[]
Response shape candidates[].content.parts[] steps[] typed by type (model_output, thought, function_call, google_search_call…) + usage
State stateless only optional server-side state: previous_interaction_id (default store=true)
Long-running none (client timeout ~60 s) background: true + polling GET /interactions/{id} or resumable SSE (?stream=true&last_event_id=) + cancel
Agents none Deep Research, Antigravity (Linux sandbox), custom managed agents, cron triggers
Sandboxes none environment param + Environments API (files PUT/GET, egress allowlist, credentials)
Structured output responseMimeType / responseSchema polymorphic response_format (text/image/audio/video)
Tools tools[].functionDeclarations, googleSearch, … flat tools[] {type: function | google_search | google_maps | code_execution | url_context | file_search | mcp_server | computer_use}
Thinking thinkingConfig.thinkingBudget/includeThoughts generation_config.thinking_level (minimal/low/medium/high) + thinking_summaries (auto/none); thought steps with signature
Tiers — service_tier: flex (-50 %), standard, priority (+75–100 %)
Webhooks Batch/video LROs webhook_config per request (dynamic) or static webhooks with interaction.* events
Not (yet) available — Batch API, automatic function calling (Python), explicit caching (implicit caching works), custom safety settings, remote MCP on Gemini 3 models

Use generateContent when you need Batch, explicit caching, custom safety settings, or an SDK/language not yet covered. Use Interactions for anything agentic, multi-turn, long-running, sandboxed, or when you want new features (all new models/tools launch there first).


# 2. Architecture

flowchart LR
  subgraph Client
    C[App / SDK<br/>google-genai · @google/genai · curl]
  end
  subgraph API["generativelanguage.googleapis.com"]
    I["POST /v1beta/interactions<br/>GET · DELETE · /cancel"]
    ST[(Stored Interactions<br/>store=true · 55 d paid / 1 d free)]
    A["/v1beta/agents<br/>custom agent defs"]
    T["/v1beta/triggers<br/>cron runs"]
    CR["/v1beta/credentials<br/>write-only secrets"]
    W["/v1/webhooks<br/>static endpoints"]
  end
  subgraph Runtime
    M[Gemini model]
    DR[deep-research-* agent]
    AG[antigravity-* agent<br/>harness]
    TOOLS[server tools<br/>google_search · url_context · code_execution<br/>file_search · google_maps · mcp_server]
  end
  subgraph Sandbox["Environment (Linux sandbox, 4 vCPU / 16 GB)"]
    FS[(/workspace files)]
    PX[egress proxy<br/>allowlist + header/credential injection]
    HK[.agents/hooks.json<br/>pre/post tool hooks]
  end
  C -- "model | agent, input, tools, previous_interaction_id, background, stream" --> I
  I <--> ST
  I --> M
  I --> DR
  I --> AG
  M --> TOOLS
  DR --> TOOLS
  AG --> TOOLS
  AG <--> FS
  AG --> HK
  FS --> PX --> Internet((Internet / MCP servers))
  CR -. "referenced by id" .-> PX
  A -. "agent: <id>" .-> I
  T -- "CreateInteractionRequest on schedule" --> I
  I -- "SSE: interaction.created → step.start/delta/stop → interaction.completed" --> C
  I -- "background: id → poll GET / stream GET?stream=true&last_event_id" --> C
  I -- "webhook_config / static webhooks: interaction.completed|failed|cancelled|requires_action" --> W --> C
  C -- "PUT /upload/v1beta/environments/{id}/files/{path}<br/>GET .../files/{path}?alt=media" --> FS
  M -- "function_call step (status requires_action)" --> C
  C -- "input: function_result + previous_interaction_id" --> I

Chaining: the id of a completed interaction goes into previous_interaction_id of the next request; only the conversation history is carried over — tools, system_instruction, generation_config are interaction-scoped and must be re-sent. Chaining onto an in_progress interaction returns 400. Managed agents additionally need environment (the environment_id from the previous response) to keep the sandbox.


# 3. Resource tree (every endpoint)

Host https://generativelanguage.googleapis.com. Auth: header x-goog-api-key: $GEMINI_API_KEY (never in the URL). Optional header Api-Revision: 2026-05-20 (current schema; 2026-05-07 = legacy schema, removed 2026-06-08).

Family Method & path Purpose Notes
interactions POST /v1beta/interactions create (model or agent) body stream: true → SSE; background: true → async
interactions GET /v1beta/interactions/{id} get / poll ?stream=true[&last_event_id=] resumes SSE
interactions DELETE /v1beta/interactions/{id} delete stored record empty body; later GET → 404
interactions POST /v1beta/interactions/{id}/cancel cancel background run one guide shows …/{id}:cancel (UNVERIFIED alias)
interactions (v1) POST /v1/interactions, GET/DELETE /v1/interactions/{id}, POST /v1/interactions/{id}/cancel stable subset reference page renders /v1beta/ URLs (doc bug); path from api-versions guide; SDK http_options.api_version="v1"
credentials POST /v1beta/credentials create secret types bearer_token, oauth2, environment_variable
credentials GET /v1beta/credentials list page_size (50, max 1000), page_token
credentials GET /v1beta/credentials/{id} get metadata never returns secrets
credentials PATCH /v1beta/credentials/{id} rotate body must repeat type; ?update_mask=
credentials DELETE /v1beta/credentials/{id} delete fails if referenced by active triggers
agents POST /v1beta/agents create custom managed agent id, base_agent, agent_config, system_instruction, tools, base_environment
agents GET /v1beta/agents list page_size/page_token (SDK)
agents GET /v1beta/agents/{id} get
agents DELETE /v1beta/agents/{id} delete existing envs/interactions unaffected
triggers POST /v1beta/triggers cron-scheduled agent run schedule, time_zone, interaction
triggers GET /v1beta/triggers, GET /v1beta/triggers/{id} list / get
triggers PATCH /v1beta/triggers/{id} pause/resume {"status": "paused" | "active"}
triggers DELETE /v1beta/triggers/{id} delete history kept
triggers POST /v1beta/triggers/{id}/executions run now
triggers GET /v1beta/triggers/{id}/executions executions (status, interaction_id, environment_id)
webhooks POST/GET /v1/webhooks, GET/PATCH/DELETE /v1/webhooks/{id}, POST /v1/webhooks/{id}/rotate_secret static project webhooks documented on /v1; shared with Batch/video; SDK also has ping (path UNVERIFIED)
environments POST /v1beta/environments create sandbox discovery flatPath environments:create; body sources[], network, from_environment
environments GET /v1beta/environments list page_size/page_token (REST page) vs pageSize/pageToken (discovery, guide curl)
environments GET /v1beta/environments/{id} get status: active | expired
environments DELETE /v1beta/environments/{id} delete otherwise 7-day idle TTL
environments GET /v1beta/environments/{env}/files[/{path}] list dir / file metadata / download ?alt=media → bytes or POSIX tar; ?recursive=true; page_size 100 (max 1000)
environments PUT /upload/v1beta/environments/{env}/files/{path} upload / extract archive ?overwrite=true, ?extract=true; resumable via X-Goog-Upload-*; max 2 GiB; without /upload/ prefix → 400
environments (legacy) GET /v1beta/files/environment-{env}:download?alt=media whole-sandbox tar superseded by …/files?alt=media
dynamic POST /v1beta/dynamic/{dynamicId}:generateContent GenerateContentRequest on a dynamic/* resource discovery-only, semantics undocumented
dynamic POST /v1beta/dynamic/{dynamicId}:streamGenerateContent streamed variant same

SDK mapping (google-genai ≥ 2.3 / @google/genai ≥ 2.3): client.interactions.{create,get,delete,cancel}, client.agents.{create,list,get,delete}, client.credentials.{create,list,get,update,delete}, client.triggers.{create,list,get,update,delete,run,list_executions}, client.webhooks.{create,list,get,update,delete,ping,rotate_signing_secret}, client.environments.{list,get,delete,create} + client.environments.files.{list,download,upload}. Java: com.google.genai.gaos.*.


# 4. The Interaction object and its lifecycle

Top-level response fields: id (v1_Chd…), object: "interaction", status, model or agent, agent_config, environment_id (only when an environment was requested), steps[], usage, errors[] {code, message}, created, updated, plus echoes of the request (input, tools, system_instruction, response_format, generation_config (input only), previous_interaction_id, labels, service_tier, webhook_config). SDKs add the convenience property output_text.

POST returns only the model-generated steps; GET returns the full timeline including the initial user_input step.

stateDiagram-v2
  [*] --> queued: background=true
  [*] --> in_progress
  queued --> in_progress
  in_progress --> requires_action: function_call step emitted
  requires_action --> in_progress: next POST with function_result + previous_interaction_id
  in_progress --> completed
  in_progress --> incomplete: max_output_tokens / max_total_tokens budget hit
  in_progress --> failed
  in_progress --> cancelled: POST /interactions/{id}/cancel
  completed --> [*]
  incomplete --> [*]: continue with previous_interaction_id (+ environment)
  failed --> [*]
  cancelled --> [*]
status Meaning
queued waiting for processing (background)
in_progress executing (model, tools, sandbox)
requires_action paused for client input (function call)
completed done, output available
incomplete finished with truncated results (token budget); agent context preserved, continue via previous_interaction_id
failed error (tool failure, rate limit…)
cancelled stopped by client
budget_exceeded deprecated — now reported as incomplete

usage: total_input_tokens, total_output_tokens, total_thought_tokens, total_cached_tokens, total_tool_use_tokens, total_tokens, *_tokens_by_modality[] {modality, tokens}, grounding_tool_count[] {type: google_search|google_maps, count}.


# 5. Create request fields (POST /v1beta/interactions)

Field Type Required Notes
model string one of model/agent 24 ModelOption values on the reference page (gemini-2.5-, gemini-3-flash-preview, gemini-3.1-pro-preview[-customtools], gemini-3.1-flash-lite, gemini-3.5/3.6/3.7/3.8-flash, image models, gemma-4-, lyria-3-*, robotics-er)
agent string one of model/agent deep-research-pro-preview-12-2025, deep-research-preview-04-2026, deep-research-max-preview-04-2026, antigravity-preview-05-2026 (reference) / antigravity-preview-09-2026 (guides), or a custom agent id
input string | Content | Content[] | Step[] yes string prompt; content blocks; or a step history (user_input, model_output, function_call, function_result, thought…)
system_instruction string no interaction-scoped; additive with the agent's AGENTS.md
tools[] Tool[] no see §6; interaction-scoped
response_format ResponseFormat | ResponseFormat[] no type = text/image/audio/video; array = multi-modal output
stream boolean no (false) SSE response
store boolean no (true) false = stateless, incompatible with background and with later previous_interaction_id
background boolean no (false) async; requires store=true; effectively required for Deep Research
generation_config object model only max_output_tokens, seed, stop_sequences, thinking_level, thinking_summaries, tool_choice (auto/any/none/validated or {allowed_tools:{mode,tools[]}}), speech_config, transcription_config, video_config.task; temperature appears in guides but not on the reference page (UNVERIFIED); Antigravity rejects temperature/top_p/top_k/stop_sequences/max_output_tokens with 400
agent_config object agent only {type: "antigravity", model, max_total_tokens} · {type: "deep-research", collaborative_planning, thinking_summaries, visualization} · {type: "dynamic"} · CodeMenderAgentConfig (named, undocumented)
environment "remote" | env id | EnvironmentConfig agents {type: "remote", environment_id?, sources[], network, env}
previous_interaction_id string no server-side history; 400 if previous still in_progress
labels map no user metadata
safety_settings SafetySetting[] no listed on the reference but overview says custom safety settings are not supported (UNVERIFIED)
service_tier flex | standard | priority no flex −50 %, best-effort (429/503, no fallback); priority +75–100 %, 0.3× rate limit, graceful downgrade (check x-gemini-service-tier response header)
webhook_config {uris[], user_metadata} no dynamic webhook (JWKS-signed) for completion events

Path/query/headers: path segment api_version (v1beta | v1); headers x-goog-api-key (required), Content-Type: application/json, Api-Revision (optional).


# 6. Content, Tool, ResponseFormat and Step variants

Content (type): text {text, annotations[]} · image {data|uri, mime_type: image/png|jpeg|webp|heic|heif|gif|bmp|tiff, resolution: low|medium|high|ultra_high} · audio {data|uri, mime_type (wav, mp3, aiff, aac, ogg, flac, mpeg, m4a, l16, opus, alaw, mulaw, webm), channels, sample_rate} · document {data|uri, mime_type: application/pdf|text/csv} · video {data|uri, mime_type (mp4, mpeg, mpg, mov, avi, x-flv, webm, wmv, 3gpp), name, processing: "static"|"agentic"|{type:"static", fps, start_offset, end_offset}, resolution}. Annotations: file_citation, place_citation, url_citation, word_info (ASR word timing/diarization).

Tools (tools[].type):

type Fields Executed by Steps produced
function name, description, parameters (JSON Schema) client function_call → status requires_action; reply with function_result {call_id, result, is_error}
google_search search_types[]: web_search | image_search server google_search_call/result (+ url_citation)
google_maps latitude, longitude, enable_widget server google_maps_call/result (+ place_citation)
code_execution — server (Python ≥ 3.10; Antigravity: bash/python/node in sandbox) code_execution_call/result
url_context — server url_context_call/result
file_search file_search_store_names[], metadata_filter, top_k server file_search_call/result (+ file_citation)
mcp_server name, url, headers, credential, allowed_tools server (streamable HTTP) mcp_server_tool_call/result; not on Gemini 3 models yet; Antigravity needs ^[a-z0-9_-]+$ names
computer_use environment: browser|mobile|desktop, disabled_safety_policies[], enable_prompt_injection_detection, excluded_predefined_functions[] model gemini-2.5-computer-use-preview-10-2025 —

ResponseFormat (type): text {mime_type: application/json|text/plain, schema} · image {aspect_ratio (14 values 1:1…4:1), image_size: 512|1K|2K|4K, mime_type: image/jpeg, delivery: inline|uri} · audio {mime_type: audio/mp3|ogg_opus|l16|wav|alaw|mulaw, sample_rate, bit_rate, delivery} · video {aspect_ratio: 16:9|9:16, resolution: 360p|720p|1080p|4k, duration, delivery}.

Steps (steps[].type): user_input {content[]} · model_output {content[]} · thought {signature, summary[]} · function_call {id, name, arguments} · function_result {call_id, name, result, is_error} · code_execution_call {id, arguments{code, language}, signature} / code_execution_result {call_id, result, is_error} · google_search_call {id, arguments{queries[]}, search_type} / google_search_result {call_id, result[]{search_suggestions}} · google_maps_call/result · url_context_call {arguments{urls[]}} / url_context_result {result[]{url, status: success|error|paywall|unsafe}} · file_search_call/result · mcp_server_tool_call {id, name, server_name, arguments} / mcp_server_tool_result {call_id, result} · processing_call/result (server-side media processing).


# 7. Streaming events (SSE), in order

Transport: text/event-stream; each frame is event: <event_type> + data: <JSON>; the JSON repeats event_type and may carry event_id (resume token for GET ?stream=true&last_event_id=). Stream ends with event: done / data: [DONE].

# event_type Payload Notes
1 interaction.created interaction {id, model|agent, object, status: in_progress} first
2 interaction.status_update interaction_id, status may repeat between steps; breaking-changes guide says it is superseded by interaction.in_progress / interaction.requires_action (neither defined in the reference — UNVERIFIED)
3 step.start index, step {type, …} for function_call: id, name, arguments: {}
4 step.delta (×n) index, delta {type, …}, metadata.total_usage? delta types: text, text_annotation_delta, image, audio, video, document, thought_signature, thought_summary, arguments_delta (partial JSON — accumulate), function_result, code_execution_call/result, google_search_call/result, google_maps_call/result, url_context_call/result, file_search_call/result, mcp_server_tool_call/result, processing_call/result
5 step.stop index, step_usage?, usage? steps 3–5 repeat per step (thought → model_output, tool pairs…)
6 interaction.completed interaction {id, status, usage, …} (no steps) last data event
— error error {code, message} any time (not_found, gateway_timeout…)
7 done [DONE] terminal marker (guide)

Legacy (Api-Revision: 2026-05-07, removed 2026-06-08): interaction.start, content.start, content.delta, content.stop, interaction.complete. Unknown event types must be skipped, not treated as errors.


# 8. Background mode and cancellation

  • "background": true → immediate response with id and status queued/in_progress. Supported for models and managed agents; mandatory in practice for Deep Research (tasks of several minutes, max 60 min).
  • Poll GET /v1beta/interactions/{id} until a terminal status, or stream GET …/{id}?stream=true (reconnect with last_event_id).
  • POST /v1beta/interactions/{id}/cancel → cancelled (small lag possible). DELETE removes the record (later GET → 404).
  • Chaining onto an in_progress interaction → 400. Managed agents need previous_interaction_id and environment (the returned environment_id).
  • Requires store=true (default). Webhooks (webhook_config or static) fire interaction.completed | failed | cancelled | requires_action.

# 9. store, retention, deletion, ZDR notes

  • Default store=true: needed for previous_interaction_id, background, and AI Studio logs.
  • Retention: Paid tier 55 days (configurable in AI Studio Logs to 7/14/28/55 days), Free tier 1 day; automatic deletion afterwards; manual DELETE /interactions/{id} anytime.
  • store=false = stateless: send the full steps history in input each turn; incompatible with background=true; cannot be used as previous_interaction_id later. Implicit caching still works in stateless mode.
  • No explicit "zero data retention" program is described for this API; data is processed per the Gemini API terms. Not documented: whether store=false also excludes the request from abuse-monitoring logs → UNVERIFIED.
  • Environments: idle snapshot after 15 min, retained 7 days since last active, then TTL-deleted (expired id → 404). Credentials: secrets write-only, never returned.

# 10. Agents

# Deep Research (deep-research-preview-04-2026, deep-research-max-preview-04-2026, deep-research-pro-preview-12-2025)

  • Autonomous plan → search → read → synthesize loop producing cited reports; Interactions-only (not via generateContent). Preview. Always background: true.
  • agent_config {type: "deep-research", collaborative_planning, thinking_summaries: auto|none, visualization: off|auto}. Collaborative planning: turn 1 returns a plan; refine with previous_interaction_id keeping collaborative_planning: true; approve with false/omit.
  • Default tools google_search, url_context, code_execution; also mcp_server, file_search. No custom function tools, no structured output, max research time 60 min (typically < 20). Inputs: text, image, PDF, audio, video; output text (+ images when visualization on).
  • Live list: input limit 131 072 (API) vs 1 048 576 (model page) — discrepancy noted; output 65 536.

# Antigravity (antigravity-preview-05-2026 reference / antigravity-preview-09-2026 guides & live list)

  • General-purpose managed agent (Antigravity IDE harness) in a Google-hosted Linux sandbox: runs bash/python/node, manages files, browses. Context compaction at ~135 k tokens. Preview; free tier has a quota.
  • agent_config {type: "antigravity", model: gemini-3.8-flash (default) | 3.7-flash | 3.6-flash | 3.5-flash | 3.5-flash-lite, max_total_tokens} — budget → incomplete, continue with previous_interaction_id + environment.
  • Default tools code_execution, google_search, url_context; filesystem tools implicit via environment; plus function (stateful mode only) and mcp_server (streamable HTTP; lowercase names). Unsupported: file_search, computer_use, google_maps, structured output, audio/video/document inputs, temperature/top_p/top_k/stop_sequences/max_output_tokens.
  • Hooks: mount .agents/hooks.json (+ scripts) — pre_tool_execution (allow/deny with reason) and post_tool_execution on code_execution, view_file, write_to_file, replace_file_content, list_dir, delete_file; command or http handlers (timeout 30 s); failures = allow.
  • Triggers: POST /v1beta/triggers {schedule, time_zone, display_name, max_consecutive_failures=5, execution_timeout_seconds=600, interaction}; pause/resume via PATCH status; run now / list executions under /executions.

# Custom (managed) agents — POST /v1beta/agents

{id, description, base_agent: "antigravity-preview-09-2026", agent_config {type: antigravity, model}, system_instruction, tools[], base_environment: "remote" | env id | {type: remote, sources[], network}}. Invoke with agent: "<id>" (+ environment: "remote"); each invocation forks the base environment. Overridable per interaction: system_instruction, tools, environment.network; not the model. Files: .agents/AGENTS.md (instructions), .agents/skills/<name>/SKILL.md, .agents/hooks.json. Reserved id prefixes: antigravity-, veo-, omni-, lyria-, imagen-, gemma-, gemini-, google-, youtube-, android-, chrome-, pixel-, waze-, fitbit-, nest-, kaggle-. Limits: 1 000 agents, no versioning, no sub-agents.

# Credentials — /v1beta/credentials

type required fields injection
bearer_token token (+ header_name=Authorization, prefix=Bearer) header on allowlisted domain / MCP server
oauth2 client_id, client_secret, refresh_token, token_url (+ scopes) live exchange at creation; auto-refresh
environment_variable value, injection_location: header|query|body (+ trusted_domains) sandbox var gets __GEMINI_CRED_<id>__; proxy substitutes on the wire

Referenced from environment.network.allowlist[].credential, tools[](mcp_server).credential, environment.env.<VAR>.credential. Errors: 400 invalid_request, 404 not_found, 409 aborted (duplicate id); unknown/camelCase fields rejected.


# 11. Environments API (sandboxes)

Lifecycle: Created (interaction with environment: "remote"/config, or POST /v1beta/environments) → Active while an interaction runs → Idle (snapshot after 15 min) → Offline (7 days, resumable by id) → Deleted (TTL or DELETE). Fixed resources: 4 vCPU, 16 GB RAM; Ubuntu with Python 3.12 (numpy, pandas, requests, google-genai, beautifulsoup4, pyyaml, ast-grep-cli), Node.js 22 (create-next-app, create-vite, typescript), git/curl/jq/ripgrep/gcloud…; packages installed persist with the same environment_id. Startup ≈ 5 s.

environment forms: "remote" (fresh), "env_abc123" (reuse), {type: "remote", environment_id?, sources[], network, env}.

  • sources[]: repository (≤ 500 MB, https://github.com/...), gcs (≤ 2 GB, gs://…), inline (≤ 1 MB/file, 2 MB total, optional encoding: base64); target never /.
  • network: omitted = unrestricted; "disabled"; or {allowlist: [{domain, credential?, transform?}]} — *.example.com does not match the root; add {domain: "*"} as catch-all; new rules replace old ones when reusing an env; credential applied first, transform headers win on conflict. Loopback blocked for HTTP hooks.
  • env: literal strings (plaintext, visible to the agent) or {credential: "<id>"}.

Files: GET /v1beta/environments/{env}/files[/{path}] (JSON listing / metadata; recursive, page_size 100 max 1000) and ?alt=media (raw bytes for a file, POSIX tar for a directory; recursive=true for nested). PUT /upload/v1beta/environments/{env}/files/{path} with raw bytes (Content-Type), ?overwrite=true (else 409), ?extract=true for tar/tar.gz; resumable protocol with X-Goog-Upload-Protocol: resumable, X-Goog-Upload-Command: start, X-Goog-Upload-Header-Content-Length/Type → X-Goog-Upload-URL; max 2 GiB. Response {files[]: EnvironmentFile {name, path, type: FILE|DIRECTORY, size_bytes, mime_type, created, modified}}. Legacy GET /v1beta/files/environment-{env}:download?alt=media.

Field casing caveat: the REST page and guides use snake_case (file_count, last_accessed, size_bytes, network, from_environment, page_size) while the discovery doc uses camelCase (fileCount, lastAccessed, sizeBytes, networkMode: DISABLED, networkAllowlist, fromEnvironment, pageSize) and the guide curl uses ?pageSize=10 — which the server accepts for JSON bodies is UNVERIFIED (Google APIs normally accept both).

Pricing: environment compute (CPU, memory, sandbox execution) not billed during preview; only model tokens + tool fees.


# 12. dynamic/* endpoints

The discovery document (rev. 20260918) exposes generativelanguage.dynamic.generateContent and dynamic.streamGenerateContent at POST /v1beta/dynamic/{dynamicId}:generateContent|:streamGenerateContent with the standard GenerateContentRequest/GenerateContentResponse schemas (model path param pattern ^dynamic/[^/]+$). No guide or reference page mentions a dynamic/{id} resource; the only related documented concept is agent_config {type: "dynamic"} (DynamicAgentConfig, the sole config type in the v1 surface) and "dynamic webhooks". Status: DOCUMENTED (discovery) + DOCUMENTATION_INCOMPLETE; nothing in the live model list starts with dynamic/.


# 13. Breaking changes (May 2026) and migration notes

  • outputs[] → steps[] with type discriminators; POST returns output steps only, GET the full timeline. Stateless clients must replay steps (not outputs) in input.
  • Streaming renamed: interaction.start→interaction.created, content.*→step.*, interaction.complete→interaction.completed; function-call arguments now stream as arguments_delta partial JSON.
  • response_format became polymorphic; response_mime_type removed; generation_config.image_config moved to response_format {type: image}.
  • Timeline: opt-in May 7 (Api-Revision: 2026-05-20, SDK Python/JS ≥ 2.0.0), default flip May 26 (Api-Revision: 2026-05-07 to opt out), legacy removed June 8, 2026.
  • From generateContent: camelCase → snake_case; contents[] → input; candidates[0].content.parts → steps[-1].content / output_text; thinkingConfig → thinking_level; server tools become explicit *_call/*_result steps; previous_interaction_id replaces resending history.

# 14. Pricing (from pricing.md "Pricing for agents" + agent guides)

Item Price / rule
Model interactions standard Gemini list rates per model (input / cached / output / thinking tokens); tool fees per existing structure (Search grounding excludes retrieved tokens; url_context / file_search include them)
service_tier: flex 50 % of standard, best-effort
service_tier: priority +75–100 % over standard; downgraded requests billed standard
Deep Research agent all model inference at list rates incl. intermediate/reasoning tokens + tool fees. Estimates: Deep Research ≈ 80 searches, ~250k input (50–70 % cached), ~60k output → ~$1–3 / task; Max ≈ 160 searches, ~900k input, ~80k output → ~$3–7 / task
Antigravity / managed agents tokens at list rates (typically 100k–3M per interaction; up to 3–5M ≈ $5); estimates: research $0.30–1.00, content generation $0.30–1.30, process design $0.25–0.80, data analysis $0.70–3.25. Environment compute not billed in preview. Free tier has a free quota
Environments / credentials / triggers / webhooks API calls no separate price documented

# 15. Limits and quotas (documented)

  • Interactions retention 55 d (paid) / 1 d (free); Deep Research max 60 min; Antigravity compaction ~135k; agent input context 1 048 576 (model pages) / 131 072 (inputTokenLimit in live list for deep-research-*), output 65 536.
  • Environments: 4 vCPU / 16 GB; sources 500 MB (git) / 2 GB (gcs) / 1 MB per inline file, 2 MB total; upload ≤ 2 GiB; idle 15 min; TTL 7 days; ≈5 s startup; text/image files only for the agent.
  • Agents: 1 000 per project; base_agent only antigravity-preview-09-2026; model locked per agent.
  • Credentials list: page_size default 50, max 1000. Files listing: default 100, max 1000.
  • Triggers: max_consecutive_failures 5, execution_timeout_seconds 600 by default.
  • Priority tier rate limit 0.3× standard; flex shares standard limits. Rate limits per model/tier are account-specific (not recorded here).
  • Antigravity function calling only in stateful mode; MCP SSE transport unsupported; Gemini 3 models: remote MCP "coming soon".

# 16. SDK snippets (tiny prompts, key from env only)

curl (create, non-streaming)

bash
curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Api-Revision: 2026-05-20" \
  -d '{"model": "gemini-3.5-flash-lite", "input": "Reply with OK.", "generation_config": {"max_output_tokens": 16}}'

curl (stream) — add "stream": true and --no-buffer; events arrive as event: step.delta / data: {...}. curl (background + poll + cancel + delete)

bash
ID=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" -H "x-goog-api-key: $GEMINI_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.5-flash-lite", "input": "Reply with OK.", "background": true}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')
curl -s "https://generativelanguage.googleapis.com/v1beta/interactions/$ID" -H "x-goog-api-key: $GEMINI_API_KEY"
curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions/$ID/cancel" -H "x-goog-api-key: $GEMINI_API_KEY"
curl -s -X DELETE "https://generativelanguage.googleapis.com/v1beta/interactions/$ID" -H "x-goog-api-key: $GEMINI_API_KEY"

Python (google-genai ≥ 2.3)

python
from google import genai            # reads GEMINI_API_KEY from the environment
client = genai.Client()
it = client.interactions.create(model="gemini-3.5-flash-lite", input="Reply with OK.",
                                generation_config={"max_output_tokens": 16})
print(it.status, it.output_text)
for ev in client.interactions.create(model="gemini-3.5-flash-lite", input="Reply with OK.", stream=True):
    print(ev.event_type)
follow = client.interactions.create(model="gemini-3.5-flash-lite", input="Again.", previous_interaction_id=it.id)
client.interactions.delete(id=it.id)
# agents / sandboxes
# client.interactions.create(agent="deep-research-preview-04-2026", input="...", background=True)
# client.interactions.create(agent="antigravity-preview-09-2026", input="...", environment="remote")
# client.environments.list(page_size=10); client.environments.files.download(environment=env_id, path="src/main.py")

TypeScript (@google/genai ≥ 2.3)

ts
import { GoogleGenAI } from "@google/genai";      // GEMINI_API_KEY from env
const ai = new GoogleGenAI({});
const it = await ai.interactions.create({ model: "gemini-3.5-flash-lite", input: "Reply with OK.",
                                          generation_config: { max_output_tokens: 16 } });
console.log(it.status, it.output_text);
const stream = await ai.interactions.create({ model: "gemini-3.5-flash-lite", input: "Reply with OK.", stream: true });
for await (const ev of stream) console.log(ev.event_type);
await ai.interactions.delete(it.id);

# Live verification (2026-09-18)

Run of 2026-09-18 on gemini-3.5-flash-lite (raws tmp-live/gemini-tools/h*.json, env*.json, f2_*.json; examples examples/gemini/interactions/* all executed; tests tests/gemini/test_interactions.py pass).

Probe Result
POST /v1beta/interactions {model, input:"Reply with OK.", generation_config:{max_output_tokens:16}} 200 {id:"v1_Chd…", object:"interaction", status:"completed", model, created, updated, service_tier:"standard", steps:[{type:"thought", signature}, {type:"model_output", content:[{type:"text", text:"OK."}]}], usage:{total_tokens, total_input_tokens, input_tokens_by_modality, total_cached_tokens, total_output_tokens, total_tool_use_tokens, total_thought_tokens, raw_prompt_token, model_invocation_token_counts}} — note steps, not outputs
stream:true (+ previous_interaction_id) SSE event:/data: frames, order interaction.created → interaction.status_update → step.start(thought) → step.delta{type:"thought_signature"} → step.stop → step.start(model_output) → step.delta{type:"text"} → step.stop → interaction.completed (+ terminal data: [DONE])
previous_interaction_id chaining 200; the model recalled the earlier turn ("You asked me to reply."); the response does not echo previous_interaction_id
GET /v1beta/interactions/{id} 200 (adds generation_config echo); ?include_steps=true → 400; after DELETE → 404 Requested entity was not found
DELETE /v1beta/interactions/{id} 200 {}
GET /v1beta/interactions (list, undocumented) 404 empty body
store:false 200, no id in the response
function tool + generation_config.tool_choice{allowed_tools{mode:"any"}} status:"requires_action", step {id:"call_…", type:"function_call", name, arguments}; function_result{name, call_id, result:[{type:"text",text}]} + previous_interaction_id → completed. Top-level tool_choice → 400 Unknown parameter 'tool_choice'; camelCase (generationConfig) → 400 Did you mean 'generation_config'?
{"type":"google_search"} 429 too_many_requests (same free-tier quota block as generateContent googleSearch)
{"type":"computer_use","environment":"browser"} on gemini-3.5-flash-lite 200 completed (model answered without acting)
agent:"deep-research-preview-04-2026", background:true 200 {id, object, agent, status:"in_progress", created, updated, service_tier} → POST …/{id}/cancel → 200 status:"cancelled" → GET cancelled → DELETE 200
Environments GET /v1beta/environments → 200 {}; POST /v1beta/environments {} → 200 {id}; GET /v1beta/environments/{id} → {id, status:"active", storage:{tier:"free", project_used_bytes:"0", project_limit_bytes:"1073741824"}, file_count:"0", size_bytes:"0", created, updated}; GET …/files/ → 404 once, 200 {} once; DELETE → 200 {}; discovery spelling GET /v1beta/environments:list → 200
Rate limiting a burst of ~10 creates within a minute produced HTTP 429 too_many_requests (retry a minute later succeeded)

Not exercised: credentials, custom agents, triggers, webhooks, environment file upload/download, dynamic/*, antigravity agents.