Source: https://ailoot.ai/docs/en/connect/google-genai/
Canonical: https://ailoot.ai/docs/en/connect/google-genai/
Language: en

[Connection](https://ailoot.ai/docs/en/) 

# Google GenAI SDK

[Markdown](https://ailoot.ai/docs/en/connect/google-genai/index.md)

Native Gemini format: the Google GenAI SDK for Python and JavaScript, and direct REST requests.

## [](https://ailoot.ai/docs/en/connect/google-genai/#install)Installation

```bash
pip install google-genai
```

```bash
npm install @google/genai
```

## [](https://ailoot.ai/docs/en/connect/google-genai/#client)Connection

The URL is `https://api.ailoot.ai` without `/v1beta`: the SDK builds the `/v1beta/models/<model>:generateContent` path itself. In Python, set the URL through `HttpOptions(base_url=…)`; in JavaScript, through `httpOptions.baseUrl`. The SDK sends the key in the header named `x-goog-api-key`.

```python
from google import genai
from google.genai import types
import os

client = genai.Client(
    api_key=os.environ["AILOOT_API_KEY"],
    http_options=types.HttpOptions(base_url="https://api.ailoot.ai"),  # without /v1beta
)

resp = client.models.generate_content(
    model="gemini-3.8-flash",
    contents="Come up with three names for a coffee shop.",
)
print(resp.text)
```

```js
import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
  apiKey: process.env.AILOOT_API_KEY,
  httpOptions: { baseUrl: "https://api.ailoot.ai" }, // without /v1beta
});

const resp = await ai.models.generateContent({
  model: "gemini-3.8-flash",
  contents: "Come up with three names for a coffee shop.",
});
console.log(resp.text);
```

```bash
curl "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:generateContent" \
  -H "x-goog-api-key: $AILOOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {"role": "user", "parts": [{"text": "Come up with three names for a coffee shop."}]}
    ]
  }' 
```

## [](https://ailoot.ai/docs/en/connect/google-genai/#body)Supported inputs

- Top-level fields: `contents`, `systemInstruction`, `generationConfig`, `safetySettings`, `tools` and `toolConfig`.
- `generationConfig` accepts `temperature`, `topP`, `topK`, `maxOutputTokens`, `thinkingConfig`, `responseMimeType` (`text/plain` or `application/json`), `responseSchema` or `responseJsonSchema` (a JSON object), `stopSequences` (an array of strings), `candidateCount: 1`, an integer `seed`, numeric `presencePenalty` and `frequencyPenalty`. Supported ranges and capabilities depend on the exact model; for a JSON response, choose one supported schema format and `application/json`. For text models, `responseModalities` — only `["TEXT"]`.
- `safetySettings` — an array of objects with `category`, `threshold` and optional `method`; choose values according to the documentation for the exact model.
- For Gemini models that support the relevant input, `parts[].inlineData` contains `mimeType` and non-empty base64 data; a PDF must be an actual PDF file. `fileData` contains a public `https` URL in `fileUri` and the file's MIME type. The MIME type can be omitted for YouTube. `http`, private URLs, `gs://` and Google Files API objects are not supported, nor are uploads through the Google Files API. For video, you can add `videoMetadata`: `startOffset`/`endOffset` as strings in seconds (for example, `1.5s`) and `fps` greater than 0 and no greater than 24. Request body size, context, supported inputs, and response limits are checked for the model and format.
- Client-side `functionDeclarations` are executed by your application. Text models also accept `{"googleSearch": {}}` and `{"urlContext": {}}`: individually or together, in the array named `tools`. Neither Google Search nor URL context can be combined with `functionDeclarations` in the same request. Only client-side functions are available for image output. Other built-in tools and explicit cache are not supported. Search/URL context may require a reserve based on the full input limit; the actual tokens reported in `toolUsePromptTokenCount` are counted as input tokens.
- If the model does not support a field, attachment, or tool combination, the request is rejected before funds are reserved, and nothing is charged. You will receive HTTP `400` with `status` `INVALID_ARGUMENT` and class `invalid_request` (in `ErrorInfo.reason` — `INVALID_REQUEST`). Invalid JSON, path parameter errors, and other validation errors also return `400`; read the error message and Request ID. Capabilities vary by model: check its formats and inputs in the catalog.

| Input | Supported MIME types |
| --- | --- |
| Inline images | image/png, image/jpeg, image/webp |
| Documents | application/pdf; text/plain, text/html, text/css, text/csv, text/xml, text/rtf, text/markdown, text/javascript, application/x-javascript, text/x-python, application/x-python |
| Audio | audio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac |
| Video | video/mp4, video/mpeg, video/mov, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp |

```python
import json, os, urllib.request

def generate(model, payload):
    req = urllib.request.Request(
        "https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
        data=json.dumps(payload).encode(),
        headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
                 "Content-Type": "application/json"},
    )
    # One send. After a timeout, check the Request ID in your usage history before retrying.
    with urllib.request.urlopen(req, timeout=300) as response:
        print("Request ID:", response.headers.get("X-Request-ID"))
        return json.load(response)

import base64, pathlib, sys

# Supply a real local PDF, audio or video file and its supported MIME type.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
    {"text": "Briefly describe the contents of the file."},
    {"inlineData": {"mimeType": mime,
                    "data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Alternative attachment: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# For a real YouTube URL: {"fileData": {"fileUri": youtube_url}}
```

## [](https://ailoot.ai/docs/en/connect/google-genai/#function-loop)Complete function-call workflow

Send the declaration, receive functionCall, run your function, return functionResponse, and request the next response. Preserve the model’s entire content, including thoughtSignature; do not create the signature yourself.

```python
import json, os, urllib.request

def generate(model, payload):
    req = urllib.request.Request(
        "https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
        data=json.dumps(payload).encode(),
        headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
                 "Content-Type": "application/json"},
    )
    # One send. After a timeout, check the Request ID in your usage history before retrying.
    with urllib.request.urlopen(req, timeout=300) as response:
        print("Request ID:", response.headers.get("X-Request-ID"))
        return json.load(response)

tools = [{"functionDeclarations": [{
    "name": "multiply", "description": "Multiply two numbers",
    "parameters": {"type": "object", "properties": {
        "a": {"type": "number"}, "b": {"type": "number"}},
        "required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Multiply 7 by 8 using the function"}]}]
for turn in range(4):  # Bound the tool loop; do not resend a request whose result is unclear.
    reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
    content = reply["candidates"][0]["content"]
    contents.append(content)  # Keep ALL original parts and thoughtSignature unchanged.
    results = []
    for part in content.get("parts", []):
        call = part.get("functionCall")
        if not call:
            continue
        if call["name"] != "multiply":
            raise ValueError("Unexpected function")
        args = call["args"]
        result = {"name": call["name"], "response": {"value": args["a"] * args["b"]}}
        if "id" in call:
            result["id"] = call["id"]
        results.append({"functionResponse": result})
    if not results:
        print(content)
        break
    contents.append({"role": "user", "parts": results})
else:
    raise RuntimeError("Tool loop limit reached")
```

## [](https://ailoot.ai/docs/en/connect/google-genai/#stream)Streaming responses

```python
for chunk in client.models.generate_content_stream(
    model="gemini-3.8-flash",
    contents="Describe a sunset over the sea",
):
    print(chunk.text, end="", flush=True)
```

```bash
curl -N "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: $AILOOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents": [{"role": "user", "parts": [{"text": "Describe a sunset over the sea"}]}]}' 
```

Ailoot delivers billed Gemini responses after calculating their cost: streaming text arrives in full when the model finishes, rather than word by word. Gemini streams contain no control lines, so allow extra time in your client timeout for long responses.

## [](https://ailoot.ai/docs/en/connect/google-genai/#models)Available models

27 identifiers are available in Gemini format: `gemini-3.8-flash`, `gemini-3.1-pro`, `gemini-pro-agent`, `gemini-3.8-flash-tiered`, `gemini-3.8-flash-medium`, `gemini-3.8-flash-low`, `gemini-3.8-flash-high`, `gemini-3.7-flash`, `gemini-3.7-flash-tiered`, `gemini-3.7-flash-medium`, `gemini-3.7-flash-low`, `gemini-3.7-flash-high`, `gemini-3.6-flash`, `gemini-3.6-flash-tiered`, `gemini-3.6-flash-medium`, `gemini-3.6-flash-low`, `gemini-3.6-flash-high`, `gemini-3.5-flash-lite`, `gemini-3.1-pro-preview`, `gemini-3.1-pro-low`, `gemini-3.1-pro-high`, `gemini-3.1-flash-lite`, `gemini-3-flash`, `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-2.5-flash-thinking`, `gemini-2.5-flash-lite`.

Gemini models are also available in Anthropic Messages format, which is useful for clients that support only that format: [Anthropic SDK](https://ailoot.ai/docs/en/connect/anthropic-sdk/).

Still have questions? Send your Request ID and a description — we'll help you troubleshoot.[Contact support](mailto:support@ailoot.ai)

## Ailoot · The company and its project portfolio





Ailoot combines established operating experience, a large client base, stable service and ongoing KPI control.





The company and its project portfolio: millions of customers; monthly sales in the billions.





Ailoot brings that operating experience to API access for AI features in customer products, agents, applications and automations.
