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

# Gemini native API

> Use generateContent and streamGenerateContent with the native Gemini format.

## Endpoint

```http theme={null}
POST https://api.viviai.cc/v1beta/models/YOUR_GEMINI_MODEL:generateContent
```

The model ID belongs in the URL. Replace `YOUR_GEMINI_MODEL` with an available model ID; do not add another `models/` prefix.

## Authentication

```http theme={null}
x-goog-api-key: YOUR_API_KEY
Content-Type: application/json
```

Use your ViVi-API key.

## Request parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `contents` | array | Yes | Current message and relevant history. |
| `contents[].role` | string | No | `user` for the user, `model` for assistant replies. |
| `contents[].parts` | array | Yes | Content blocks; text uses `{"text":"content"}`. |
| `systemInstruction` | object | No | Top-level instructions using parts. |
| `generationConfig` | object | No | Generation settings. |
| `generationConfig.maxOutputTokens` | integer | No | Output token limit. |
| `generationConfig.temperature` | number | No | Model-dependent sampling control. |
| `generationConfig.topP` | number | No | Nucleus sampling control. |

> [!NOTE]
>
> Gemini uses `contents` and `parts`, and its assistant role is `model`. Do not send an OpenAI `messages` body to this endpoint.

## Request examples

Set `VIVI_API_KEY` to your ViVi-API key in your shell environment. See [Quickstart](https://docs.viviai.cc/en/index.md) to create a key. Install requests with `python -m pip install requests`. cURL uses Bash syntax.

```bash cURL theme={null}
curl --fail-with-body \
  "https://api.viviai.cc/v1beta/models/YOUR_GEMINI_MODEL:generateContent" \
  -H "x-goog-api-key: $VIVI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {"role": "user", "parts": [{"text": "Explain APIs in three sentences."}]}
    ]
  }'
```

```python Python theme={null}
import os
import requests

model = "YOUR_GEMINI_MODEL"
response = requests.post(
    f"https://api.viviai.cc/v1beta/models/{model}:generateContent",
    headers={"x-goog-api-key": os.environ["VIVI_API_KEY"]},
    json={
        "contents": [
            {"role": "user", "parts": [{"text": "Explain APIs in three sentences."}]}
        ]
    },
    timeout=120,
)
response.raise_for_status()
data = response.json()
candidates = data.get("candidates", [])
if not candidates:
    raise RuntimeError(f"No candidates returned: {data.get('promptFeedback', data)}")
parts = candidates[0].get("content", {}).get("parts", [])
print("".join(p.get("text", "") for p in parts if not p.get("thought")))
```

## Response

Illustrative response:

```json theme={null}
{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [{"text": "An API is an interface that applications use to communicate."}]
    },
    "finishReason": "STOP"
  }],
  "usageMetadata": {
    "promptTokenCount": 20,
    "candidatesTokenCount": 15,
    "totalTokenCount": 35
  }
}
```

Read all text parts from `candidates[].content.parts`, not just the first part. Inspect `finishReason` for completion or blocking; common values include `STOP` and `MAX_TOKENS`. If there are no candidates, check `promptFeedback`. Usage is reported in `usageMetadata`; fields vary by model.

## System instructions and multi-turn conversations

```json theme={null}
{
  "systemInstruction": {
    "parts": [{"text": "You are a patient programming assistant. Answer in English."}]
  },
  "contents": [
    {"role": "user", "parts": [{"text": "I am learning Python."}]},
    {"role": "model", "parts": [{"text": "What would you like to learn first?"}]},
    {"role": "user", "parts": [{"text": "Explain lists."}]}
  ],
  "generationConfig": {"maxOutputTokens": 1024}
}
```

For ordinary text conversations, include history in order. Preserve complete content blocks when using tools, thought signatures, or multimodal features. Saving only displayed text may omit required data.

## Streaming

Use streamGenerateContent with the alt=sse query parameter:

```bash theme={null}
curl --no-buffer --fail-with-body \
  "https://api.viviai.cc/v1beta/models/YOUR_GEMINI_MODEL:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: $VIVI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {"role": "user", "parts": [{"text": "Write a short welcome message."}]}
    ]
  }'
```

Parse the JSON in each SSE data event. Read `candidates[].content.parts` rather than OpenAI delta fields. Do not rely on an OpenAI-style `[DONE]` marker.

## Integration notes

* Use `/v1beta/models/...`, not `/v1/v1beta/...`.
* Keep the model in the URL and generation settings in the JSON body.
* Images, files, and tool use depend on model and channel support.
* Read the HTTP status and error body; see [troubleshooting](https://docs.viviai.cc/en/faq.md).

Protocol reference: [Google Gemini generateContent](https://ai.google.dev/api/generate-content). Availability and optional features depend on ViVi-API support.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.