Source: https://ailoot.ai/docs/el/api/gemini/
Canonical: https://ailoot.ai/docs/el/api/gemini/
Language: el

[API](https://ailoot.ai/docs/el/) 

# Gemini generateContent

[Markdown](https://ailoot.ai/docs/el/api/gemini/index.md)

Η εγγενής μορφή του Google Gemini: για Gemini CLI, Google GenAI SDK και πελάτες REST.

POST`https://api.ailoot.ai/v1beta/models/{model}:generateContent`

Gemini generateContent

```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": "Πρότεινε τρία ονόματα για μια καφετέρια."}]}
    ]
  }' 
```

```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"),  # χωρίς /v1beta
)

resp = client.models.generate_content(
    model="gemini-3.8-flash",
    contents="Πρότεινε τρία ονόματα για μια καφετέρια.",
)
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" }, // χωρίς /v1beta
});

const resp = await ai.models.generateContent({
  model: "gemini-3.8-flash",
  contents: "Πρότεινε τρία ονόματα για μια καφετέρια.",
});
console.log(resp.text);
```

200 OK

```json
{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [{ "text": "1. «Κόκκος και ατμός» 2. «Πρωινό άλεσμα» 3. «Η καφετέρια της γωνίας»" }]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 9,
    "candidatesTokenCount": 27,
    "totalTokenCount": 36
  },
  "modelVersion": "gemini-3.8-flash"
}
```

## Έλεγχος ταυτότητας

| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
| --- | --- | --- | --- |
| `x-goog-api-key` | header | υποχρεωτικό | Κλειδί `sk-…`. Γίνονται επίσης δεκτά τα `Authorization: Bearer` ή `x-api-key`. Για συμβατότητα με το Google γίνεται επίσης δεκτό το `?key=` στη διεύθυνση — με τη χαμηλότερη προτεραιότητα· `?api_key=` απορρίπτεται με 400. Συνιστούμε την κεφαλίδα, ώστε το κλειδί να μην καταγράφεται στα αρχεία καταγραφής. |

## Διαδρομή

| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
| --- | --- | --- | --- |
| `model` | string | υποχρεωτικό | ID μοντέλου με μορφή Gemini, για παράδειγμα `gemini-3.8-flash` ή `gemini-3.1-pro`. Συνολικά 27. |

POST`https://api.ailoot.ai/v1beta/models/{model}:streamGenerateContent?alt=sse`

GET`https://api.ailoot.ai/v1beta/models`

## Σώμα αιτήματος

| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
| --- | --- | --- | --- |
| `contents` | array | υποχρεωτικό | Μηνύματα με `role` (`user`/`model`) και `parts`: text, inlineData/fileData, functionCall/functionResponse. Τα συνημμένα πρέπει να υποστηρίζονται ως είσοδος από το μοντέλο. |
| `systemInstruction` | object | προαιρετικό | Οδηγία συστήματος σε κείμενο: `{"parts": [{"text": "…"}]}`. |
| `generationConfig` | object | προαιρετικό | `generationConfig` δέχεται `temperature`, `topP`, `topK`, `maxOutputTokens`, `thinkingConfig`, `responseMimeType` (`text/plain` ή `application/json`), `responseSchema` ή `responseJsonSchema` (αντικείμενο JSON), `stopSequences` (πίνακας συμβολοσειρών), `candidateCount: 1`, ακέραιο `seed`, αριθμητικές τιμές `presencePenalty` και `frequencyPenalty`. Τα επιτρεπόμενα εύρη και οι δυνατότητες εξαρτώνται από το συγκεκριμένο μοντέλο· για απάντηση JSON επιλέξτε μία υποστηριζόμενη μορφή σχήματος και `application/json`. Στα μοντέλα κειμένου το `responseModalities` — μόνο `["TEXT"]`. |
| `safetySettings` | array | προαιρετικό | Αντικείμενα με υποχρεωτικά `category` και `threshold`, προαιρετικό `method`. Οι τιμές πρέπει να υποστηρίζονται από το συγκεκριμένο μοντέλο. |
| `tools` | array | προαιρετικό | Οι δηλώσεις πελάτη `functionDeclarations` εκτελούνται από την εφαρμογή σας. Τα μοντέλα κειμένου δέχονται επίσης `{"googleSearch": {}}` και `{"urlContext": {}}`: μεμονωμένα ή μαζί στον πίνακα `tools`. Ούτε το Google Search ούτε το URL context μπορούν να συνδυαστούν με `functionDeclarations` στο ίδιο αίτημα. Για εικόνες εξόδου διατίθενται μόνο συναρτήσεις πελάτη. Άλλα ενσωματωμένα εργαλεία και explicit cache δεν υποστηρίζονται. Τα Search/URL context μπορεί να απαιτούν δέσμευση βάσει ολόκληρου του ορίου εισόδου· τα πραγματικά `toolUsePromptTokenCount` υπολογίζονται ως token εισόδου. |
| `toolConfig` | object | προαιρετικό | `functionCallingConfig`: mode (AUTO/ANY/NONE/VALIDATED/MODE\_UNSPECIFIED), allowedFunctionNames. |

Αν το μοντέλο δεν υποστηρίζει ένα πεδίο, συνημμένο ή συνδυασμό εργαλείων, το αίτημα απορρίπτεται πριν από τη δέσμευση — δεν χρεώνεται τίποτα. Θα λάβετε HTTP `400` με `status` `INVALID_ARGUMENT` και κλάση `invalid_request` (στο `ErrorInfo.reason` — `INVALID_REQUEST`). Το μη έγκυρο JSON, τα σφάλματα παραμέτρων διαδρομής και άλλων ελέγχων επιστρέφουν επίσης `400`· διαβάστε το μήνυμα σφάλματος και το Request ID. Οι δυνατότητες εξαρτώνται από το μοντέλο: ελέγξτε τις μορφές και τις εισόδους του στον κατάλογο.

## PDF, ήχος, βίντεο και σύνδεσμοι

Στα μοντέλα Gemini που υποστηρίζουν την αντίστοιχη είσοδο, το `parts[].inlineData` περιέχει `mimeType` και μη κενά δεδομένα base64· το PDF πρέπει να είναι πραγματικό αρχείο PDF. `fileData` περιέχει δημόσια διεύθυνση `https`στο `fileUri` και τον τύπο MIME του αρχείου. Για το YouTube μπορείτε να παραλείψετε τον τύπο MIME. `http`, ιδιωτικές διευθύνσεις, `gs://` και αντικείμενα Google Files API δεν υποστηρίζονται, ούτε η μεταφόρτωση μέσω Google Files API. Στο βίντεο μπορείτε να προσθέσετε `videoMetadata`: `startOffset`/`endOffset` ως συμβολοσειρά σε δευτερόλεπτα (για παράδειγμα, `1.5s`) και `fps` μεγαλύτερο από 0 και έως 24. Το μέγεθος σώματος, το παράθυρο συμφραζομένων, η επιτρεπόμενη είσοδος και το όριο απάντησης ελέγχονται ανά μοντέλο και μορφή.

| Είσοδος | Υποστηριζόμενοι τύποι MIME |
| --- | --- |
| Ενσωματωμένες εικόνες | image/png, image/jpeg, image/webp |
| Έγγραφα | 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/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac |
| Βίντεο | 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"},
    )
    # Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
    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

# Δώστε ένα πραγματικό τοπικό αρχείο PDF, ήχου ή βίντεο και τον υποστηριζόμενο τύπο MIME του.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
    {"text": "Περίγραψε σύντομα το περιεχόμενο του αρχείου."},
    {"inlineData": {"mimeType": mime,
                    "data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Εναλλακτικό συνημμένο: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Για πραγματική διεύθυνση URL του YouTube: {"fileData": {"fileUri": youtube_url}}
```

## Search και URL context

Οι δηλώσεις πελάτη `functionDeclarations` εκτελούνται από την εφαρμογή σας. Τα μοντέλα κειμένου δέχονται επίσης `{"googleSearch": {}}` και `{"urlContext": {}}`: μεμονωμένα ή μαζί στον πίνακα `tools`. Ούτε το Google Search ούτε το URL context μπορούν να συνδυαστούν με `functionDeclarations` στο ίδιο αίτημα. Για εικόνες εξόδου διατίθενται μόνο συναρτήσεις πελάτη. Άλλα ενσωματωμένα εργαλεία και explicit cache δεν υποστηρίζονται. Τα Search/URL context μπορεί να απαιτούν δέσμευση βάσει ολόκληρου του ορίου εισόδου· τα πραγματικά `toolUsePromptTokenCount` υπολογίζονται ως token εισόδου.

```json
{"tools": [{"googleSearch": {}}, {"urlContext": {}}]}
```

## Εικόνες στην έξοδο

Εικόνες σε απάντηση μορφής Gemini παράγει μόνο το `gemini-3.1-flash-image`. Αυτή η δυνατότητα είναι ξεχωριστή από το `/v1/images/generations`: τα άλλα μοντέλα εικόνας δεν λειτουργούν εδώ. Το μοντέλο δέχεται έως 131072 token εισόδου και παράγει έως 32768 token απάντησης· το πλήρες κόστος της μεγαλύτερης δυνατής απάντησης δεσμεύεται εκ των προτέρων.

`responseModalities` — μη κενό σύνολο TEXT/IMAGE χωρίς επαναλήψεις. `imageConfig.imageSize`: 1K/2K/4K; `aspectRatio`: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9, 1:4, 4:1, 1:8, 8:1. Η είσοδος αυτού του μοντέλου περιλαμβάνει κείμενο και ενσωματωμένες εικόνες PNG/JPEG/WebP· PDF/audio/video/fileData και ενσωματωμένα Search/URL context δεν γίνονται δεκτά εδώ. Η διαθεσιμότητα και οι τιμές για το κλειδί σας εμφανίζονται στον κατάλογο και στο `GET /v1/models`.

```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"},
    )
    # Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
    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

reply = generate("gemini-3.1-flash-image", {
    "contents": [{"role": "user", "parts": [{"text": "Ακουαρέλα: φάρος την αυγή"}]}],
    "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"},
    },
})
index = 0
for candidate in reply.get("candidates", []):
    for part in candidate.get("content", {}).get("parts", []):
        if "text" in part:
            print(part["text"])
        blob = part.get("inlineData", {})
        if blob.get("mimeType", "").startswith("image/") and blob.get("data"):
            index += 1
            extension = {"image/png": "png", "image/jpeg": "jpg",
                         "image/webp": "webp"}.get(blob["mimeType"], "bin")
            pathlib.Path(f"gemini-image-v{index}.{extension}").write_bytes(
                base64.b64decode(blob["data"]))
print("All returned images:", index)
```

## Πλήρης κύκλος κλήσης συναρτήσεων

Ο πελάτης εκτελεί τις συναρτήσεις. Επιστρέψτε όλο το αρχικό content του μοντέλου με το thoughtSignature χωρίς αλλαγές, έπειτα το functionResponse με τα ίδια name και id, εφόσον το id υπήρχε στο functionCall.

```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"},
    )
    # Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
    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": "Πολλαπλασιασμός δύο αριθμών",
    "parameters": {"type": "object", "properties": {
        "a": {"type": "number"}, "b": {"type": "number"}},
        "required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Πολλαπλασίασε το 7 με το 8 με τη βοήθεια της συνάρτησης"}]}]
for turn in range(4):  # Περιορίστε τον κύκλο εκτέλεσης των εργαλείων· μην ξαναστέλνετε αίτημα του οποίου το αποτέλεσμα είναι ασαφές.
    reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
    content = reply["candidates"][0]["content"]
    contents.append(content)  # Διατηρήστε όλα (ALL) τα αρχικά τμήματα και το thoughtSignature αμετάβλητα.
    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")
```

## Απάντηση

| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
| --- | --- | --- | --- |
| `candidates[].content.parts` | array |  | Η απάντηση του μοντέλου. |
| `usageMetadata` | object |  | `promptTokenCount`, `candidatesTokenCount`, `totalTokenCount`. |

Η χρεώσιμη απάντηση Gemini φτάνει ολόκληρη μετά τον υπολογισμό του κόστους, και όχι λέξη προς λέξη. Η ροή Gemini δεν περιέχει βοηθητικές γραμμές — αφήστε επαρκές περιθώριο στο χρονικό όριο του πελάτη.

Έχετε ερωτήσεις; Στείλτε μας το Request ID και μια περιγραφή — θα σας βοηθήσουμε να βρείτε την αιτία.[Επικοινωνία με την υποστήριξη](mailto:support@ailoot.ai)

## Ailoot · Η εταιρεία και το χαρτοφυλάκιο έργων της





Η Ailoot στηρίζεται στη συσσωρευμένη λειτουργική εμπειρία, τη μεγάλη πελατειακή βάση, τη σταθερή εξυπηρέτηση και τον συνεχή έλεγχο KPI.





Η εταιρεία και το χαρτοφυλάκιο έργων της: εκατομμύρια πελάτες· μηνιαίες πωλήσεις δισεκατομμυρίων.





Η Ailoot αξιοποιεί αυτή τη λειτουργική εμπειρία για πρόσβαση μέσω API σε λειτουργίες AI στα προϊόντα, τους πράκτορες, τις εφαρμογές και τους αυτοματισμούς των πελατών.
