> For the complete documentation index, see [llms.txt](https://docs.avis.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.avis.xyz/api-reference/introduction/gemini-compatibility.md).

# Gemini Compatibility

Point the official `@google/genai` SDK — or a raw `fetch`/`curl` client speaking the Gemini REST API — at Avis. Set your real Avis API key in `apiKey` (see Authentication).

### Base URL

```
https://api.avis.xyz/api/gemini
```

> The `@google/genai` SDK appends `/v1beta` to `baseUrl` automatically. Pass `https://api.avis.xyz/api/gemini` — **not** `.../api/gemini/v1beta` — or you'll get a doubled path.

### Switching an existing app

```typescript
import { GoogleGenAI } from '@google/genai'

const ai = new GoogleGenAI({
  apiKey: process.env.AVIS_API_KEY,
  httpOptions: {
    baseUrl: 'https://api.avis.xyz/api/gemini',
  },
})
```

### Endpoints

| Method | Path                                                      | Streaming | Description                                                  |
| ------ | --------------------------------------------------------- | --------- | ------------------------------------------------------------ |
| `HEAD` | `/api/gemini`                                             | —         | Connectivity probe (no auth)                                 |
| `GET`  | `/api/gemini/v1beta/models`                               | —         | List available models                                        |
| `POST` | `/api/gemini/v1beta/models/{model}:generateContent`       | —         | Generate content                                             |
| `POST` | `/api/gemini/v1beta/models/{model}:streamGenerateContent` | ✅         | Generate content, streamed                                   |
| `POST` | `/api/gemini/v1beta/models/{model}:embedContent`          | —         | Embed one content; returns a singular `embedding`            |
| `POST` | `/api/gemini/v1beta/models/{model}:batchEmbedContents`    | —         | Embed multiple contents; returns a plural `embeddings` array |

#### `GET /v1beta/models`

```typescript
const models = await fetch('https://api.avis.xyz/api/gemini/v1beta/models', {
  headers: {
    Authorization: `Bearer ${process.env.AVIS_API_KEY}`,
  },
}).then((r) => r.json())

console.log(models.data[0])
```

#### `POST /models/{model}:generateContent`

```typescript
const response = await ai.models.generateContent({
  model: 'gemini-2.0-flash',
  contents: 'Explain quantum entanglement in one sentence.',
})
console.log(response.text)
```

```json
{
  "candidates": [
    {
      "content": { "parts": [{ "text": "Hello! How can I help you today?" }], "role": "model" },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": { "promptTokenCount": 2, "candidatesTokenCount": 10 }
}
```

#### `candidates[].finishReason`

`finishReason` explains why a candidate stopped generating.

Common values:

| Value                       | Meaning                                                 |
| --------------------------- | ------------------------------------------------------- |
| `STOP`                      | Natural stop / normal completion                        |
| `MAX_TOKENS`                | Reached token limit                                     |
| `SAFETY`                    | Stopped by safety system                                |
| `RECITATION`                | Stopped due to recitation policy                        |
| `LANGUAGE`                  | Stopped due to unsupported/disallowed language handling |
| `BLOCKLIST`                 | Blocked by blocklist rules                              |
| `PROHIBITED_CONTENT`        | Blocked by prohibited-content policy                    |
| `SPII`                      | Blocked due to sensitive PII handling                   |
| `MALFORMED_FUNCTION_CALL`   | Stopped because function/tool call output was malformed |
| `OTHER`                     | Other stop reason                                       |
| `FINISH_REASON_UNSPECIFIED` | No explicit stop reason provided                        |

Notes:

* Value is passed through as returned by upstream.
* Full enum and latest updates: <https://ai.google.dev/api/generate-content#FinishReason>

#### `POST /models/{model}:streamGenerateContent`

```typescript
const stream = await ai.models.generateContentStream({
  model: 'gemini-2.0-flash',
  contents: 'Explain quantum entanglement in one sentence.',
})

for await (const chunk of stream) {
  process.stdout.write(chunk.text ?? '')
}
```

#### `POST /models/{model}:embedContent`

```typescript
const response = await ai.models.embedContent({
  model: 'gemini-embedding-2',
  contents: { parts: [{ text: 'The quick brown fox jumps over the lazy dog.' }] },
})
console.log(response.embedding.values)
```

Only text and `outputDimensionality` are honored on generic embedding models; `taskType` and `title` are rejected. `gemini-embedding-2` / `gemini-embedding-2-preview` additionally accept image, audio, PDF, and video content parts:

```typescript
import { readFileSync } from 'node:fs'

const response = await ai.models.embedContent({
  model: 'gemini-embedding-2',
  contents: {
    parts: [
      { text: 'What is in this image?' },
      {
        inlineData: {
          mimeType: 'image/png',
          data: readFileSync('image.png').toString('base64'),
        },
      },
    ],
  },
})
console.log(response.embedding.values)
```

Image input isn't Gemini-exclusive — `voyage-multimodal-3-5` and `llama-nemotron-embed-vl-1b-v2` also accept it via this same wire shape. `gemini-embedding-2`/`-preview` allow up to 6 images per request.

Audio is Gemini-exclusive (`gemini-embedding-2`/`-preview` only), capped at one part per request, `audio/wav` only, up to 180 seconds:

```typescript
const response = await ai.models.embedContent({
  model: 'gemini-embedding-2',
  contents: {
    parts: [
      { text: 'Transcribe the sentiment of this clip.' },
      {
        inlineData: {
          mimeType: 'audio/wav',
          data: readFileSync('clip.wav').toString('base64'),
        },
      },
    ],
  },
})
console.log(response.embedding.values)
```

Video is also Gemini-exclusive, capped at one part per request, MP4/MOV only, up to 120 seconds:

```typescript
const response = await ai.models.embedContent({
  model: 'gemini-embedding-2',
  contents: {
    parts: [
      { text: 'Describe the action in this clip.' },
      {
        inlineData: {
          mimeType: 'video/mp4',
          data: readFileSync('clip.mp4').toString('base64'),
        },
      },
    ],
  },
})
console.log(response.embedding.values)
```

For audio and video, a `fileData`/`fileUri` (URL) reference is not supported — inline base64 is the only accepted source. Sending audio/video to any other embedding model returns `400`.

#### `POST /models/{model}:batchEmbedContents`

```typescript
const response = await ai.models.batchEmbedContents({
  model: 'gemini-embedding-2',
  requests: [
    { content: { parts: [{ text: 'first document' }] } },
    { content: { parts: [{ text: 'second document' }] } },
  ],
})
console.log(response.embeddings.map((e) => e.values))
```

All requests in a batch must share the same `outputDimensionality`.

### Field support

This proxy is a **thin pass-through**. Request fields mostly follow Gemini-native upstream definitions and are forwarded as-is. Whether a field is honored depends on the resolved provider/model.

### `/v1beta/models` response

| Field                                   | Type            | Required | Notes                                                                                                                                                       |
| --------------------------------------- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                    | `string`        | ✅        | Provider catalog ID, e.g. `google/gemini-2.0-flash`. For Gemini path calls, use the native name after the slash.                                            |
| `name`                                  | `string`        | —        | Human-readable model name                                                                                                                                   |
| `inputModalities`                       | `array<string>` | —        | Supported input modalities for the model                                                                                                                    |
| `outputModalities`                      | `array<string>` | —        | Supported output modalities for the model                                                                                                                   |
| `capabilitiesProviderId`                | `string`        | —        | Provider row selected by priority for capability resolution                                                                                                 |
| `capabilities`                          | `object`        | —        | Effective capability object for the priority-winning provider row. Absent means unconstrained.                                                              |
| `capabilities.text.supportedParameters` | `array<string>` | —        | For text models: accepted generation parameters (e.g. `maxTokens`, `temperature`, `topP`, `tools`, `thinking`).                                             |
| `capabilities.params`                   | `object`        | —        | Per-parameter bounds/constraints keyed by request field name. For image/video models, read from `capabilities.image.params` or `capabilities.video.params`. |
| `capabilities.inputs`                   | `object`        | —        | Accepted content-part inputs (roles, media types, limits).                                                                                                  |
| `capabilities.strictParams`             | `boolean`       | —        | When `true`, unsupported gated params are rejected.                                                                                                         |
| `chatPricing`                           | `object`        | —        | Effective chat pricing metadata for the selected provider row                                                                                               |
| `imagePricing`                          | `object`        | —        | Effective image pricing metadata for the selected provider row                                                                                              |
| `videoPricing`                          | `object`        | —        | Effective video pricing metadata for the selected provider row                                                                                              |
| `threeDPricing`                         | `object`        | —        | Effective 3D pricing metadata for the selected provider row                                                                                                 |
| `embeddingPricing`                      | `object`        | —        | Effective embedding pricing metadata for the selected provider row                                                                                          |

#### `capabilities.params` value shapes

For image/video models, use per-model `capabilities.image.params` or `capabilities.video.params` instead of hardcoding shared limits across models.

| `type`  | Extra fields                                          | Meaning                                                                                        |
| ------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `enum`  | `values: string[]`, `default?`                        | Value must be one of `values`.                                                                 |
| `range` | `min`, `max`, `default?`, `unit?`, `steps?: number[]` | Value must be between `min` and `max`. When `steps` exists, only those exact values are valid. |
| `int`   | `min`, `max`, `default?`                              | Value must be an integer between `min` and `max`.                                              |
| `bool`  | `default?`                                            | Value must be `true` or `false`.                                                               |

### `/v1beta/models/{model}:generateContent`

| Field               | Type               | Required | Notes                                                                                                                                               |
| ------------------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model` (path)      | `string`           | ✅        | Gemini-native model ID in the path, e.g. `gemini-2.0-flash`                                                                                         |
| `contents`          | `array \| string`  | ✅        | Prompt/message content                                                                                                                              |
| `generationConfig`  | `object`           | —        | Generation options (e.g. `temperature`, `topP`, `topK`, `maxOutputTokens`, `stopSequences`, `responseMimeType`, `responseSchema`, `thinkingConfig`) |
| `systemInstruction` | `object \| string` | —        | System instruction block                                                                                                                            |
| `safetySettings`    | `array`            | —        | Safety policy configuration                                                                                                                         |
| `tools`             | `array`            | —        | Tool definitions/function calling                                                                                                                   |
| `toolConfig`        | `object`           | —        | Tool behavior configuration                                                                                                                         |
| `cachedContent`     | `string`           | —        | Reference to cached prompt/content                                                                                                                  |

### `/v1beta/models/{model}:streamGenerateContent`

| Field          | Type                | Required | Notes                                                       |
| -------------- | ------------------- | -------- | ----------------------------------------------------------- |
| `model` (path) | `string`            | ✅        | Gemini-native model ID in the path, e.g. `gemini-2.0-flash` |
| Request body   | `object`            | ✅        | Same request schema as `:generateContent`                   |
| Response type  | `text/event-stream` | ✅        | Streaming response chunks from upstream                     |

### `/v1beta/models/{model}:embedContent`

| Field                         | Type      | Required | Notes                                                                                                                                                                              |
| ----------------------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model` (path)                | `string`  | ✅        | Embedding-capable model ID, e.g. `gemini-embedding-2`                                                                                                                              |
| `contents`                    | `object`  | ✅        | `{ parts: [...] }`. Parts may be `{ text }` or `{ inlineData: { mimeType, data } }`. Image is accepted by several models; audio/PDF/video are `gemini-embedding-2`/`-preview` only |
| `config.outputDimensionality` | `integer` | —        | Output vector dimensionality                                                                                                                                                       |
| `config.taskType`             | —         | —        | Rejected — not honored by normalized embedding                                                                                                                                     |
| `config.title`                | —         | —        | Rejected — not honored by normalized embedding                                                                                                                                     |

Response: `{ embedding: { values: number[] } }`.

### `/v1beta/models/{model}:batchEmbedContents`

| Field          | Type     | Required | Notes                                                   |
| -------------- | -------- | -------- | ------------------------------------------------------- |
| `model` (path) | `string` | ✅        | Embedding-capable model ID                              |
| `requests`     | `array`  | ✅        | Non-empty array of `{ content: { parts: [...] }, ... }` |

Response: `{ embeddings: [{ values: number[] }, ...] }`, in request order.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.avis.xyz/api-reference/introduction/gemini-compatibility.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
