# Gemini Interactions API

The Gemini Interactions API is Google's stateful conversation endpoint. Unlike the standard `generateContent`/`streamGenerateContent` endpoints, Interactions uses `previous_interaction_id` for server-side conversation state, flat `outputs[]` instead of nested `candidates[].content.parts[]`, and typed SSE events with an `event_type` field inside each JSON payload.

## Endpoint

Method | Path | Format
--- | --- | ---
POST | /v1beta/interactions | SSE (typed JSON events)

## Quick Start

Set up a minimal mock that responds to a Gemini Interactions request:

quick-start.ts ts

    import { LLMock } from "@copilotkit/aimock";

    const mock = new LLMock();
    mock.on({ userMessage: "hello" }, { content: "Hi there!" });
    await mock.listen(4010);

    // Client sends:
    // POST /v1beta/interactions
    // { model: "gemini-2.5-flash", input: "hello", stream: true }

## Request Format

The Interactions API accepts several input shapes. aimock normalizes all of them into the unified fixture-matching format.

### String Input (Simple Prompt)

string-input.json json

    {
      "model": "gemini-2.5-flash",
      "input": "What is the capital of France?",
      "stream": true
    }

### Turn[] Input (Multi-Turn)

multi-turn-input.json json

    {
      "model": "gemini-2.5-flash",
      "input": [
        { "role": "user", "parts": [{ "type": "text", "text": "Hello" }] },
        { "role": "model", "parts": [{ "type": "text", "text": "Hi there!" }] },
        { "role": "user", "parts": [{ "type": "text", "text": "Tell me a joke" }] }
      ],
      "stream": true
    }

### Content[] with Function Result (Tool Response)

tool-response-input.json json

    {
      "model": "gemini-2.5-flash",
      "input": [
        {
          "role": "user",
          "parts": [
            { "type": "function_result", "name": "get_weather", "call_id": "call_abc123", "result": "72F sunny" }
          ]
        }
      ],
      "previous_interaction_id": "interaction_abc123",
      "stream": true
    }

### Stateful Chaining

The `previous_interaction_id` field links turns together on the server side. Each response includes an `interaction_id` that the client passes as `previous_interaction_id` in the next request, eliminating the need to resend full conversation history.

## Fixture Matching

Fixtures use the same `match` object as all other providers. The most common matchers for Interactions are `userMessage` and `sequenceIndex`.

### userMessage Matching

user-message-match.ts ts

    const fixture = {
      match: { userMessage: "hello" },
      response: { content: "Hi from Gemini Interactions!" },
    };

### sequenceIndex for Multi-Turn Chains

Since the Interactions API is stateful, multi-turn conversations are the primary use case. Use `sequenceIndex` to match by turn position:

sequence-match.ts ts

    const fixtures = [
      {
        match: { sequenceIndex: 0 },
        response: {
          toolCalls: [{ name: "get_weather", arguments: { city: "NYC" } }]
        },
      },
      {
        match: { sequenceIndex: 1 },
        response: { content: "The weather in NYC is 72F and sunny." },
      },
    ];

    const instance = await createServer(fixtures);

    // Turn 1: model calls get_weather tool
    // Turn 2: after tool result, model produces final text

## SSE Event Format

Unlike standard Gemini SSE (bare `data:` chunks), the Interactions API uses typed events. Each SSE line is a `data:` JSON object containing an `event_type` field.

### Event Types

Event Type | Description
--- | ---
`interaction.start` | Opening event with interaction_id and model metadata
`content.start` | Marks beginning of an output part
`content.delta` | Incremental text or function_call chunk
`content.stop` | Marks completion of an output part
`interaction.complete` | Final event with usage metadata and finish reason

### Text Streaming Example

text-sse-events.txt text

    data: {"event_type":"interaction.start","interaction":{"id":"int_abc123","status":"in_progress"},"event_id":"evt_1"}

    data: {"event_type":"content.start","index":0,"content":{"type":"text"},"event_id":"evt_2"}

    data: {"event_type":"content.delta","index":0,"delta":{"type":"text","text":"Hi "},"event_id":"evt_3"}

    data: {"event_type":"content.delta","index":0,"delta":{"type":"text","text":"there!"},"event_id":"evt_4"}

    data: {"event_type":"content.stop","index":0,"event_id":"evt_5"}

    data: {"event_type":"interaction.complete","interaction":{"id":"int_abc123","status":"completed","usage":{"total_input_tokens":5,"total_output_tokens":3,"total_tokens":8}},"event_id":"evt_6"}

### Tool Call Streaming Example

tool-sse-events.txt text

    data: {"event_type":"interaction.start","interaction":{"id":"int_def456","status":"in_progress"},"event_id":"evt_1"}

    data: {"event_type":"content.start","index":0,"content":{"type":"function_call"},"event_id":"evt_2"}

    data: {"event_type":"content.delta","index":0,"delta":{"type":"function_call","id":"tc_abc123","name":"get_weather","arguments":{"city":"NYC"}},"event_id":"evt_3"}

    data: {"event_type":"content.stop","index":0,"event_id":"evt_4"}

    data: {"event_type":"interaction.complete","interaction":{"id":"int_def456","status":"requires_action","usage":{"total_input_tokens":8,"total_output_tokens":12,"total_tokens":20}},"event_id":"evt_5"}

## Recording

To record real Gemini Interactions API traffic, use the `gemini` provider settings (same base URL, same API key). The Interactions endpoint shares the Gemini infrastructure:

record-config.ts ts

    import { LLMock } from "@copilotkit/aimock";

    const mock = new LLMock({
      record: {
        providers: {
          gemini: "https://generativelanguage.googleapis.com",
        },
      },
    });
    await mock.listen(4010);

Unmatched requests to `/v1beta/interactions` are proxied to the real API, and the response is recorded as a new fixture.

## Integration with TanStack AI

TanStack AI provides a `geminiTextInteractions()` adapter for the Interactions API. When your client uses this adapter, point it at your aimock instance and the same fixtures will serve the responses. See the TanStack AI docs for adapter configuration.

## Known Limitations

The Gemini Interactions API is currently in beta. Both the real API and aimock's support for it are subject to change as the API stabilizes.

- Beta API — event types and request shapes may shift between releases.
- Text output + function tools only — the current scope covers text generation and function calling.
- Built-in tools not supported — Google's built-in tools (`google_search`, `code_execution`) are not yet mocked.
- Non-text modalities not supported — image, audio, and video inputs/outputs are not handled by this endpoint.