dokumentasi
API

Gemini generateContent

Markdown

Format asli Google Gemini: untuk Gemini CLI, Google GenAI SDK, dan klien REST.

Panduan lengkap
POSThttps://api.ailoot.ai/v1beta/models/{model}:generateContent
Gemini generateContent
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": "Buat tiga nama untuk kedai kopi."}]}
    ]
  }' 
200 OK
{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [{ "text": "1. «Biji dan Uap» 2. «Gilingan Pagi» 3. «Kedai Kopi di Sudut»" }]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 9,
    "candidatesTokenCount": 27,
    "totalTokenCount": 36
  },
  "modelVersion": "gemini-3.8-flash"
}

Autentikasi

  • x-goog-api-keyheaderwajib

    Kunci sk-…. Dapat juga menggunakan Authorization: Bearer atau x-api-key. Untuk kompatibilitas dengan Google, juga diterima ?key= dalam alamat — dengan prioritas terendah; ?api_key= ditolak dengan 400. Kami menyarankan header agar kunci tidak masuk ke log.

Jalur

  • modelstringwajib

    ID model dengan format Gemini, misalnya gemini-3.8-flash atau gemini-3.1-pro. Total 27.

POSThttps://api.ailoot.ai/v1beta/models/{model}:streamGenerateContent?alt=sse
GEThttps://api.ailoot.ai/v1beta/models

Isi permintaan

  • contentsarraywajib

    Pesan dengan role (user/model) dan parts: text, inlineData/fileData, functionCall/functionResponse. Lampiran harus sesuai dengan jenis input yang diterima model.

  • systemInstructionobjectopsional

    Instruksi sistem berupa teks: {"parts": [{"text": "…"}]}.

  • generationConfigobjectopsional

    generationConfig menerima temperature, topP, topK, maxOutputTokens, thinkingConfig, responseMimeType (text/plain atau application/json), responseSchema atau responseJsonSchema (objek JSON), stopSequences (array string), candidateCount: 1, bilangan bulat seed, nilai numerik presencePenalty dan frequencyPenalty. Rentang yang diizinkan dan fitur bergantung pada model yang tepat; untuk respons JSON, pilih satu bentuk skema yang didukung dan application/json. Untuk model teks responseModalities — hanya ["TEXT"].

  • safetySettingsarrayopsional

    Objek dengan kolom wajib category dan threshold, kolom opsional method. Nilainya harus didukung oleh model yang tepat.

  • toolsarrayopsional

    Deklarasi fungsi klien functionDeclarations dijalankan oleh aplikasi Anda. Model teks juga menerima {"googleSearch": {}} dan {"urlContext": {}}: secara terpisah atau bersama-sama dalam array tools. Google Search maupun URL context tidak dapat digabungkan dengan functionDeclarations dalam satu permintaan. Untuk output gambar, hanya fungsi klien yang tersedia. Alat bawaan lainnya dan explicit cache tidak didukung. Search/URL context dapat memerlukan saldo yang ditahan berdasarkan batas input penuh; nilai aktual toolUsePromptTokenCount dihitung sebagai token input.

  • toolConfigobjectopsional

    functionCallingConfig: mode (AUTO/ANY/NONE/VALIDATED/MODE_UNSPECIFIED), allowedFunctionNames.

Jika model tidak mendukung kolom, lampiran, atau kombinasi alat, permintaan ditolak sebelum dana ditahan — tidak ada pendebitan. Respons berupa HTTP 400 dengan status INVALID_ARGUMENT dan kelas invalid_request (di ErrorInfo.reason — INVALID_REQUEST). JSON yang tidak valid, kesalahan parameter jalur, dan kegagalan validasi lainnya juga mengembalikan 400; baca pesan kesalahan dan Request ID. Fitur bergantung pada model: periksa format dan inputnya di katalog.

PDF, audio, video, dan tautan

Untuk model Gemini yang mendukung jenis input tersebut, parts[].inlineData berisi mimeType dan data base64 yang tidak kosong; PDF harus berupa file PDF yang valid. fileData berisi alamat publik httpsdi fileUri dan MIME jenis file. Untuk YouTube, MIME boleh tidak diisi. http, alamat privat, gs:// dan objek Google Files API tidak didukung, begitu pula unggahan melalui Google Files API. Untuk video, Anda dapat menambahkan videoMetadata: startOffset/endOffset sebagai string dalam detik (misalnya, 1.5s) dan fps lebih dari 0 dan tidak lebih dari 24. Ukuran isi permintaan, konteks, input yang diizinkan, dan batas respons diperiksa berdasarkan model dan format.

InputMIME yang didukung
Gambar inlineimage/png, image/jpeg, image/webp
Dokumenapplication/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
Audioaudio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac
Videovideo/mp4, video/mpeg, video/mov, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp
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"},
    )
    # Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
    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

# Sediakan berkas PDF, audio, atau video lokal yang nyata beserta jenis MIME yang didukung.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
    {"text": "Jelaskan isi berkas secara singkat."},
    {"inlineData": {"mimeType": mime,
                    "data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Lampiran alternatif: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Untuk URL YouTube yang nyata: {"fileData": {"fileUri": youtube_url}}

Search dan URL context

Deklarasi fungsi klien functionDeclarations dijalankan oleh aplikasi Anda. Model teks juga menerima {"googleSearch": {}} dan {"urlContext": {}}: secara terpisah atau bersama-sama dalam array tools. Google Search maupun URL context tidak dapat digabungkan dengan functionDeclarations dalam satu permintaan. Untuk output gambar, hanya fungsi klien yang tersedia. Alat bawaan lainnya dan explicit cache tidak didukung. Search/URL context dapat memerlukan saldo yang ditahan berdasarkan batas input penuh; nilai aktual toolUsePromptTokenCount dihitung sebagai token input.

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

Output gambar

Output gambar dalam respons berformat Gemini hanya didukung oleh gemini-3.1-flash-image. Fitur ini terpisah dari /v1/images/generations: model gambar lain tidak berfungsi di sini. Model ini memiliki batas input hingga 131072 token dan respons hingga 32768; biaya penuh respons terpanjang ditahan di awal.

responseModalities — himpunan TEXT/IMAGE yang tidak kosong dan tanpa duplikat. 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. Input model ini berupa teks dan PNG/JPEG/WebP inline; PDF/audio/video/fileData serta Search/URL context bawaan tidak diterima di sini. Ketersediaan dan harga untuk kunci Anda dapat dilihat di katalog dan GET /v1/models.

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"},
    )
    # Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
    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": "Lukisan cat air: mercusuar saat fajar"}]}],
    "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)

Siklus lengkap pemanggilan fungsi

Fungsi dijalankan oleh klien. Kembalikan seluruh content asli model beserta thoughtSignature tanpa perubahan, lalu functionResponse dengan name dan id yang sama jika id terdapat dalam functionCall.

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"},
    )
    # Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
    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": "Mengalikan dua bilangan",
    "parameters": {"type": "object", "properties": {
        "a": {"type": "number"}, "b": {"type": "number"}},
        "required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Kalikan 7 dengan 8 menggunakan fungsi"}]}]
for turn in range(4):  # Batasi pengulangan pemanggilan alat; jangan kirim ulang permintaan yang hasilnya belum jelas.
    reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
    content = reply["candidates"][0]["content"]
    contents.append(content)  # Pertahankan semua (ALL) bagian asli dan thoughtSignature tanpa perubahan.
    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")

Respons

  • candidates[].content.partsarray

    Respons model.

  • usageMetadataobject

    promptTokenCount, candidatesTokenCount, totalTokenCount.

Masih ada pertanyaan? Kirim Request ID dan penjelasannya — kami akan membantu.Hubungi dukungan