The Interactions API provides stateful, server-managed conversations with:
- CRUD lifecycle (
create,get,cancel,delete) - Background execution (
background: true) with polling/cancel - SSE streaming with resumable
last_event_id
This is different from generateContent-style calls, which are stateless and require you to manage conversation state client-side.
Model availability
Model availability for Interactions can vary by account/region. If you see errors like "Model family ... is not supported", try gemini-2.5-flash (or set your own model: explicitly).
Create (non-streaming)
alias Gemini.APIs.Interactions
{:ok, interaction} =
Interactions.create("What is the capital of France?",
model: "gemini-2.5-flash"
)
IO.inspect(interaction.id, label: "interaction.id")
IO.inspect(interaction.status, label: "interaction.status")Agent-based interactions use agent: instead of model::
alias Gemini.APIs.Interactions
{:ok, interaction} =
Interactions.create("Research the history of quantum computing",
agent: "deep-research-pro-preview-12-2025",
background: true,
store: true
)Create (streaming SSE)
Streaming is enabled via stream: true and ends when the server sends [DONE].
alias Gemini.APIs.Interactions
alias Gemini.Types.Interactions.Events.ContentDelta
alias Gemini.Types.Interactions.DeltaTextDelta
{:ok, stream} =
Interactions.create("Write a short poem about Elixir",
model: "gemini-2.5-flash",
stream: true
)
for event <- stream do
case event do
%ContentDelta{delta: %DeltaTextDelta{text: text}} when is_binary(text) ->
IO.write(text)
_ ->
:ok
end
endResumption (last_event_id)
If your stream is interrupted, persist the interaction_id and the last event_id you processed, then resume with get(stream: true, last_event_id: ...).
alias Gemini.APIs.Interactions
alias Gemini.Types.Interactions.Events.InteractionEvent
{:ok, stream} =
Interactions.create("Write a longer story in multiple paragraphs",
model: "gemini-2.5-flash",
stream: true
)
# Simulate a disconnect by stopping early (after a few events),
# while keeping track of the interaction id + last event id we saw.
state =
Enum.reduce_while(stream, %{interaction_id: nil, last_event_id: nil, seen: 0}, fn event, acc ->
acc =
case event do
%InteractionEvent{event_type: "interaction.start", interaction: interaction} ->
%{acc | interaction_id: interaction.id}
_ ->
acc
end
acc = %{acc | last_event_id: Map.get(event, :event_id), seen: acc.seen + 1}
if acc.seen >= 5 do
{:halt, acc}
else
{:cont, acc}
end
end)
{:ok, resumed} =
Interactions.get(state.interaction_id,
stream: true,
last_event_id: state.last_event_id
)
Enum.each(resumed, fn _event -> :ok end)Background + cancel + delete
Note: The API may reject background: true for model-based interactions; background execution is commonly supported for agent interactions.
alias Gemini.APIs.Interactions
{:ok, interaction} =
Interactions.create("Draft a detailed outline for a technical blog post about OTP supervision trees",
agent: "deep-research-pro-preview-12-2025",
background: true,
store: true
)
# Poll until terminal status (completed/failed/cancelled/requires_action)
{:ok, final} = Interactions.wait_for_completion(interaction.id, timeout_ms: 120_000)
# Cancel (only applies while a background interaction is still running)
_ = Interactions.cancel(interaction.id)
# Delete (best-effort cleanup)
:ok = Interactions.delete(interaction.id)Gemini vs Vertex routing (and quota project)
gemini_ex supports both Gemini and Vertex AI auth for Interactions:
- Gemini uses
x-goog-api-keyand requests under/v1beta/.... - Vertex uses
Authorization: Bearer ...and requests under/v1beta1/....- Create is project/location-scoped:
https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project}/locations/{location}/interactions - Get/cancel/delete are not project/location-scoped (Python parity):
https://{location}-aiplatform.googleapis.com/v1beta1/interactions/{id}
- Create is project/location-scoped:
If you configure a Vertex quota project (quota_project_id, VERTEX_QUOTA_PROJECT_ID, or GOOGLE_CLOUD_QUOTA_PROJECT), requests include:
x-goog-user-project: <quota_project_id>