> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aisonar.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate Content

> Generates content using Google Gemini API format

AI Sonar supports the native Google Gemini API shape when the model details advertise Gemini requests and a same-protocol route is currently available. A model or provider name alone does not imply that this route is available, and native Gemini requests never fall back through Chat Completions.

Google ProtoJSON accepts both lowerCamelCase JSON names and original proto `snake_case` field names. AI Sonar preserves camelCase, snake\_case, and mixed requests without normalizing them. If both spellings of one field are present, AI Sonar forwards both without merging them or assigning a local precedence. Unknown fields are also forwarded best-effort; the selected service decides whether they are supported.

## Path Parameters

<ParamField path="model" type="string" required>
  Model name (e.g., `gemini-2.5-pro`, `gemini-3.5-flash`).
</ParamField>

## Query Parameters

<ParamField query="key" type="string">
  API key (alternative to header authentication).
</ParamField>

## Authentication

Gemini endpoints support multiple authentication methods:

* `?key=YOUR_API_KEY` query parameter
* `x-goog-api-key: YOUR_API_KEY` header
* `Authorization: Bearer YOUR_API_KEY` header

## Request Body

<ParamField body="contents" type="array" required>
  Conversation contents.

  Each content object contains:

  * `role` (string): `user` or `model`
  * `parts` (array): Content parts. AI Sonar supports:
    * text parts: `{ "text": "..." }`
    * inline media parts: `inlineData` / `inline_data`
    * URL-based file parts: `fileData` / `file_data`

  AI Sonar does not lowercase roles, infer MIME types, rewrite Base64 data, inject image configuration, or apply a local Gemini tool whitelist. AI Sonar-owned File and Cache resource IDs are the exception: they are ownership-checked and resolved to the service resource created for the same API key.
</ParamField>

<ParamField body="systemInstruction" type="object">
  System instruction for the model.
</ParamField>

<ParamField body="generationConfig" type="object">
  Generation configuration:

  * `temperature` (number): Sampling temperature
  * `topP` (number): Nucleus sampling probability
  * `topK` (integer): Top-K sampling
  * `maxOutputTokens` (integer): Maximum output tokens
  * `stopSequences` (array): Stop sequences
  * `candidateCount` (integer): Requested candidate count; support is determined by the selected service.
  * `responseModalities` (array): Requested output modalities for compatible native routes.
  * `responseMimeType` (string): Output MIME type such as `text/plain` or `application/json`.
  * `responseSchema` (object): JSON schema for structured output when `responseMimeType` requests JSON.
  * `thinkingConfig` / `thinking_config` (object): Thinking budget options for compatible models.
</ParamField>

<ParamField body="safetySettings" type="array">
  Safety filter settings.
</ParamField>

Every lowerCamelCase field shown above may also use its official proto `snake_case` spelling, for example `system_instruction`, `generation_config`, `safety_settings`, `tool_config`, `cached_content`, `file_data.file_uri`, and `inline_data.mime_type`.

## Supported native methods

The current legacy Gemini surface includes model list/get, `generateContent`, `streamGenerateContent`, `countTokens`, `embedContent`, and `batchEmbedContents`. Gemini Interactions and Live are not currently exposed.

## Response

<ResponseField name="candidates" type="array">
  Generated content candidates.
</ResponseField>

<ResponseField name="usageMetadata" type="object">
  Token usage information.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.aisonar.dev/v1beta/models/gemini-2.5-pro:generateContent?key=sk-your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [
        {
          "parts": [{"text": "Hello, Gemini!"}]
        }
      ],
      "generationConfig": {
        "temperature": 0.7,
        "maxOutputTokens": 1024
      }
    }'
  ```

  ```python Python theme={null}
  import google.generativeai as genai

  genai.configure(
      api_key="sk-your-api-key",
      transport="rest",
      client_options={"api_endpoint": "api.aisonar.dev"}
  )

  model = genai.GenerativeModel("gemini-2.5-pro")
  response = model.generate_content("Hello, Gemini!")

  print(response.text)
  ```

  ```javascript JavaScript theme={null}
  import { GoogleGenerativeAI } from "@google/generative-ai";

  const genAI = new GoogleGenerativeAI("sk-your-api-key", {
    baseUrl: "https://api.aisonar.dev"
  });

  const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" });
  const result = await model.generateContent("Hello, Gemini!");

  console.log(result.response.text());
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      payload := map[string]interface{}{
          "contents": []map[string]interface{}{
              {
                  "parts": []map[string]string{
                      {"text": "Hello, Gemini!"},
                  },
              },
          },
          "generationConfig": map[string]interface{}{
              "temperature":    0.7,
              "maxOutputTokens": 1024,
          },
      }

      jsonData, _ := json.Marshal(payload)
      req, _ := http.NewRequest("POST",
          "https://api.aisonar.dev/v1beta/models/gemini-2.5-pro:generateContent?key=sk-your-api-key",
          bytes.NewBuffer(jsonData))
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```

  ```php PHP theme={null}
  <?php
  $payload = [
      'contents' => [
          [
              'parts' => [
                  ['text' => 'Hello, Gemini!']
              ]
          ]
      ],
      'generationConfig' => [
          'temperature' => 0.7,
          'maxOutputTokens' => 1024
      ]
  ];

  $ch = curl_init('https://api.aisonar.dev/v1beta/models/gemini-2.5-pro:generateContent?key=sk-your-api-key');

  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_HTTPHEADER => [
          'Content-Type: application/json'
      ],
      CURLOPT_POSTFIELDS => json_encode($payload)
  ]);

  $response = curl_exec($ch);
  curl_close($ch);

  $data = json_decode($response, true);
  echo $data['candidates'][0]['content']['parts'][0]['text'];
  ```
</RequestExample>

## Vision Input Example

For Gemini multimodal requests, place media inside `contents[].parts[]` using either inline bytes or URL-based file references.

Supported media categories in the public Gemini contract:

* image
* audio
* video

For inline media, use either `inlineData` or `inline_data` and pass Base64-encoded file bytes.

For URL-based media, use either `fileData` or `file_data` and pass a public `https` URL.

## Video Input Example

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Please describe this video." },
        {
          "fileData": {
            "mimeType": "video/mp4",
            "fileUri": "https://example.com/demo.mp4"
          }
        }
      ]
    }
  ]
}
```

## Audio Input Example

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Please describe this audio." },
        {
          "fileData": {
            "mimeType": "audio/mpeg",
            "fileUri": "https://example.com/demo.mp3"
          }
        }
      ]
    }
  ]
}
```

## Image Input Example

Use inline image bytes:

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Please describe this image." },
        {
          "inlineData": {
            "mimeType": "image/jpeg",
            "data": "/9j/4AAQSkZJRgABAQ..."
          }
        }
      ]
    }
  ]
}
```

Use an image URL:

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Please describe this image." },
        {
          "fileData": {
            "mimeType": "image/jpeg",
            "fileUri": "https://example.com/demo.jpg"
          }
        }
      ]
    }
  ]
}
```

## Audio Input Example

Use an audio URL:

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Transcribe and summarize this audio." },
        {
          "file_data": {
            "mime_type": "audio/mpeg",
            "file_uri": "https://example.com/sample.mp3"
          }
        }
      ]
    }
  ]
}
```

## Video Input Example

Use a video URL:

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Describe this video briefly." },
        {
          "fileData": {
            "mimeType": "video/mp4",
            "fileUri": "https://example.com/sample.mp4"
          }
        }
      ]
    }
  ]
}
```

<ResponseExample>
  ```json Response theme={null}
  {
    "candidates": [
      {
        "content": {
          "role": "model",
          "parts": [
            {"text": "Hello! How can I assist you today?"}
          ]
        },
        "finishReason": "STOP",
        "safetyRatings": [
          {"category": "HARM_CATEGORY_HARASSMENT", "probability": "NEGLIGIBLE"}
        ]
      }
    ],
    "usageMetadata": {
      "promptTokenCount": 5,
      "candidatesTokenCount": 10,
      "totalTokenCount": 15
    }
  }
  ```
</ResponseExample>
