SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
7.6 KB

# Gemini Batch API (batchGenerateContent / asyncBatchEmbedContent / batches.*)

Status: DOCUMENTED · ACCOUNT_RESTRICTED — every create call (valid docs body on gemini-3.8-flash, tiny inline batch on gemini-3.5-flash-lite, embedding batch, and even invalid bodies) returned 400 FAILED_PRECONDITION "Precondition check failed."; the pricing page lists Batch as "Free Tier: Not available" and this key is on the free tier. GET /v1beta/batches → 200 {} LIVE_VERIFIED. Lifecycle below is therefore documented, not observed. Sources: Batch API guide · Batch API reference · Batch Mode (older twin) · Pricing · Rate limits #batch · Webhooks · discovery v1beta rev. 20260918 · python-genai BatchJob, JobState. Last verified: 2026-09-18. Twins: endpoints fragment (api_family batch), parameters/gemini-batch.json, objects GenerateContentBatch, BatchStats, GenerateContentBatchOutput / InlinedResponse, EmbedContentBatch, lifecycle GenerateContentBatch / EmbedContentBatch.

# 1. Endpoints

Method / path SDK (google-genai) Body Returns Live 2026-09-18
POST /v1beta/models/{model}:batchGenerateContent client.batches.create(model, src, config) {batch: {displayName, inputConfig: {requests:{requests:[{request, metadata}]}} | {fileName}, priority?, webhookConfig?}} Operation (name batches/{id}, metadata = GenerateContentBatch with state) 400 FAILED_PRECONDITION
POST /v1beta/models/{model}:asyncBatchEmbedContent client.batches.create_embeddings same envelope with EmbedContentRequests Operation (metadata EmbedContentBatch) 400 FAILED_PRECONDITION
POST /v1beta/tunedModels/{id}:batchGenerateContent / :asyncBatchEmbedContent — same Operation not tested (tunedModels → 501)
GET /v1beta/batches/{id} client.batches.get(name) — Operation (done, metadata.state, response) bogus names → 400 Could not parse the batch name
GET /v1beta/batches?filter&pageSize&pageToken&returnPartialSuccess client.batches.list() — ListOperationsResponse 200 {}
POST /v1beta/batches/{id}:cancel client.batches.cancel(name) empty {}; op ends with error.code = 1 (CANCELLED) not reachable
DELETE /v1beta/batches/{id} client.batches.delete(name) — {} (does not cancel) not reachable
PATCH /v1beta/batches/{id}:updateGenerateContentBatch?updateMask= — GenerateContentBatch (priority…) GenerateContentBatch 400 FAILED_PRECONDITION (no batch existed)
PATCH /v1beta/batches/{id}:updateEmbedContentBatch?updateMask= — EmbedContentBatch EmbedContentBatch not tested

Node: ai.batches.create / createEmbeddings / get / list / cancel / delete. OpenAI-compatibility layer also exposes Batch (/v1beta/openai/batches).

# 2. Input formats

Inline (whole request < 20 MB; output comes back inline):

json
{"batch": {"display_name": "my-batch", "input_config": {"requests": {"requests": [
  {"request": {"contents": [{"parts": [{"text": "Describe photosynthesis."}]}], "generationConfig": {"temperature": 0.7}}, "metadata": {"key": "request-1"}},
  {"request": {"contents": [{"parts": [{"text": "Reply with OK."}]}], "generation_config": {"responseModalities": ["TEXT","IMAGE"]}}, "metadata": {"key": "request-2"}}
]}}}}

File (JSONL uploaded with the Files API, ≤ 2 GB; output = JSONL responsesFile): one object per line {"key": "request-1", "request": {<GenerateContentRequest>}} (the guide's shell sample also shows bare request objects per line), then {"batch": {"display_name": "…", "input_config": {"file_name": "files/123456"}}}. Each request may carry systemInstruction, tools, generationConfig (incl. responseModalities for image generation with gemini-3-pro-image-preview), cachedContent (standard caching rates apply), other modalities via fileData. The model comes from the URL.

Embeddings: {"request": {"content": {"parts": [{"text": "OK"}]}, "embedContentConfig": {"taskType", "outputDimensionality", "title"}}, "metadata": {...}} on gemini-embedding-2 / -001 (live methods list asyncBatchEmbedContent).

# 3. States and lifecycle

REST state (BatchState) Guide prose / SDK JobState Meaning
BATCH_STATE_PENDING JOB_STATE_PENDING (SDK also QUEUED) created, waiting — initial
BATCH_STATE_RUNNING JOB_STATE_RUNNING (SDK also UPDATING, PAUSED) executing; batchStats.pendingRequestCount decreases
BATCH_STATE_SUCCEEDED JOB_STATE_SUCCEEDED (SDK also PARTIALLY_SUCCEEDED) terminal; done:true, response.inlinedResponses[] or response.responsesFile
BATCH_STATE_FAILED JOB_STATE_FAILED terminal; error (Status)
BATCH_STATE_CANCELLED JOB_STATE_CANCELLED (SDK CANCELLING in between) after :cancel
BATCH_STATE_EXPIRED JOB_STATE_EXPIRED pending/running > 48 h; no results

Poll GET /v1beta/batches/{id}: done false → keep polling; metadata.state; when SUCCEEDED, response.inlinedResponses.inlinedResponses[] = {metadata, response | error} (same order as input) or response.responsesFile → GET https://generativelanguage.googleapis.com/download/v1beta/{responsesFile}:download?alt=media. Results are kept 6 weeks. Target turnaround 24 h ("in majority of cases much quicker"). Webhooks: subscribe to batch.succeeded / batch.failed (POST /v1/webhooks) or set batch.webhookConfig.uris[] per batch. Timestamps: createTime, updateTime, endTime. batchStats = {requestCount, successfulRequestCount, failedRequestCount, pendingRequestCount} (int64 strings).

# 4. Pricing and limits

  • 50 % of the interactive price for every model that lists batchGenerateContent (text, image, TTS models …; see each pricing section's "Batch" table — e.g. gemini-3.1-flash-lite-image $0.0168 per 1K image, gemini-3.1-flash-tts-preview $0.50 / $10). Not available on the free tier. Cached-content hits billed at standard caching rates.
  • Rate limits: 100 concurrent batch requests; per-model enqueued-token caps (tables on the rate-limits page, separate from interactive limits).
  • Inline request ≤ 20 MB; input file ≤ 2 GB; creation is not idempotent; check batchStats.failedRequestCount and per-line status objects.
  • Supported models = those with batchGenerateContent / asyncBatchEmbedContent in models.list (gemini-3.5-transcribe, Lyria, Veo, Live models: no).

# 5. Live log (2026-09-18, $0)

Call Result
POST …gemini-3.5-flash-lite:batchGenerateContent inline 2× "Reply with OK." 400 FAILED_PRECONDITION
POST …gemini-3.8-flash:batchGenerateContent (guide body, 1 request) 400 FAILED_PRECONDITION
body without displayName; body with file_name: files/bogus 400 FAILED_PRECONDITION (identical → gate precedes validation)
POST …gemini-embedding-2:asyncBatchEmbedContent 1 request 400 FAILED_PRECONDITION
GET /v1beta/batches?pageSize=5 200 {}
GET /v1beta/batches/bogus-batch, /batches/123456789 400 INVALID_ARGUMENT Could not parse the batch name

Interpretation: account/plan restriction (Batch has no free tier), not a payload problem. Examples in examples/gemini/batch/ are UNVERIFIED; tests gated by RUN_BATCH_TESTS will xfail/skip on FAILED_PRECONDITION.