Gemini long-running operations (Operation, */operations, batches, generatedFiles)
Status: DOCUMENTED · partly LIVE_VERIFIED 2026-09-18 (list model operations 200, list generatedFiles 200, list batches 200, error shapes for bogus names) · no real operation could be created with this key (Veo not run for cost; batch/tuning gated — see their pages).
Sources: Batch reference — Resource: Operation · Veo guide — asynchronous operations · Tuning reference · All methods · Webhooks · discovery v1beta rev. 20260918.
Last verified: 2026-09-18. Twins: endpoints fragment (api_family operations, files, batch), objects Operation, Status, GeneratedFile, lifecycles Operation (predictLongRunning / Veo), GeneratedFile, GenerateContentBatch.
1. The Operation resource (google.longrunning)
{"name": "models/veo-3.1-generate-preview/operations/abc123", "metadata": {"@type": "…", …}, "done": false}
{"name": "batches/123456789", "metadata": {"@type": "type.googleapis.com/google.ai.generativelanguage.v1beta.GenerateContentBatch", "state": "BATCH_STATE_PENDING", …}, "done": false}
{"name": "…", "done": true, "response": {"@type": "…", …}} // exactly one of response | error when done
{"name": "…", "done": true, "error": {"code": 3, "message": "…", "status": "INVALID_ARGUMENT", "details": []}}| Field | Meaning |
|---|---|
name |
server-assigned; the resource path you poll |
metadata |
service-specific progress (@type + fields): Veo none/progress; batch → the GenerateContentBatch / EmbedContentBatch (with state, batchStats); tuning → CreateTunedModelMetadata {tunedModel, totalSteps, completedSteps, completedPercent, snapshots[]} |
done |
false while running |
response |
success payload (PredictLongRunningResponse.generateVideoResponse, GenerateContentBatchOutput, TunedModel) |
error |
google.rpc.Status {code, message, details[]}; code 1 = CANCELLED after batches/*:cancel |
2. Who returns operations, and where to poll
| Producer | Operation name pattern | Poll (GET) | List | Cancel | Delete |
|---|---|---|---|---|---|
models/{m}:predictLongRunning (Veo) |
models/{m}/operations/{id} |
GET /v1beta/{name} |
GET /v1beta/models/{m}/operations (filter, pageSize, pageToken, returnPartialSuccess) |
— (none in discovery) | — |
models/{m}:batchGenerateContent, :asyncBatchEmbedContent |
batches/{id} |
GET /v1beta/batches/{id} |
GET /v1beta/batches |
POST /v1beta/batches/{id}:cancel |
DELETE /v1beta/batches/{id} (does not cancel) |
tunedModels create |
tunedModels/{id}/operations/{op} |
GET /v1beta/{name} |
GET /v1beta/tunedModels/{id}/operations |
— | — |
| generated media | generatedFiles/{id}/operations/{op} |
GET /v1beta/{name} |
GET /v1beta/generatedFiles (files, not operations) |
— | — |
| file search / corpora (other agents) | fileSearchStores/{s}/operations/{op}, fileSearchStores/{s}/upload/operations/{op}, corpora/{c}/operations/{op} |
GET /v1beta/{name} |
— | — | — |
GET /v1beta/{name} works with the full name string returned by the producer — the guide's Veo loop is literally curl "${BASE_URL}/${operation_name}". SDK: client.operations.get(operation) (Python), ai.operations.getVideosOperation({operation}) (Node); batches have their own client.batches.get.
3. Polling guidance and alternatives
- Veo: poll every ~10 s; total latency 11 s – 6 min. Batch: minutes to 24 h (expiry 48 h); poll every 20–60 s or use webhooks.
- Webhooks (launched 2026):
POST /v1/webhooks?webhook_id=…withsubscribed_events: ["batch.succeeded","batch.failed"], or per-requestwebhookConfig.uris[](batch and SDKGenerateVideosConfig.webhook_config). ReplacesGET /operationspolling for batch and long-running operations. - Results retention: Veo files 2 days (→
files/{id}:download?alt=media), batch response files 6 weeks, uploaded files 48 h.
4. generatedFiles
GeneratedFile {name: "generatedFiles/abc-123", state: GENERATING | GENERATED | FAILED, mimeType, error}; GET /v1beta/generatedFiles?pageSize&pageToken → {generatedFiles[], nextPageToken}. Live: 200 {} (empty project). Operation variant generatedFiles/{id}/operations/{op} (bogus ids → 400 INVALID_ARGUMENT "Request contains an invalid argument.").
5. Observed error shapes (2026-09-18)
| Request | HTTP | error.status |
error.message |
|---|---|---|---|
GET /v1beta/models/veo-3.1-lite-generate-preview/operations/bogus-op |
403 | PERMISSION_DENIED | You do not have permission to access the Operation with ID bogus-op or it may not exist. |
GET /v1beta/models/veo-3.1-lite-generate-preview/operations |
200 | — | {} |
GET /v1beta/generatedFiles/bogus/operations/bogus |
400 | INVALID_ARGUMENT | Request contains an invalid argument. |
GET /v1beta/tunedModels/bogus-model/operations/bogus |
400 | INVALID_ARGUMENT | same |
GET /v1beta/batches/bogus-batch / batches/123456789 |
400 | INVALID_ARGUMENT | Could not parse the batch name |
GET /v1beta/batches?pageSize=5 |
200 | — | {} |
Note the asymmetry: an unknown model operation is a 403 (existence hidden), an unknown batch is a 400 parse error. All error bodies follow {error: {code, message, status, details?}}.