Gemini API: Event-Driven Webhooks for Batch and Long-Running Operations

Gemini CLI

Google launched event-driven webhook support in the Gemini API on May 4, 2026, eliminating the need for developers to poll for job completion on long-running operations. Instead of repeatedly calling GET /operations, the API now pushes an HTTP POST payload to a developer-registered endpoint the instant an asynchronous task finishes. The feature targets batch processing jobs, Deep Research tasks, and video generation workflows β€” operations that can span minutes to hours. Both static (project-level HMAC-secured) and dynamic (per-request JWKS-secured) webhook configurations are supported.


Why Polling Is a Problem for Agentic Workflows

As the Gemini API has expanded to support increasingly complex agentic workloads β€” from processing thousands of prompts in bulk via the Batch API to generating long-form videos with Veo and running multi-step Deep Research tasks β€” developers have faced a frustrating architectural constraint: there was no way to know when a job finished without writing a polling loop.

Polling is expensive. It burns API quota, adds code complexity, and introduces artificial latency between a job completing and an application reacting. For workloads that take minutes or even hours, a polling interval tight enough to feel responsive becomes wasteful at scale.

Google addressed this on May 4, 2026, by launching event-driven webhook support for the Gemini API β€” a push-based notification system that turns long-running operations into fire-and-forget jobs.

How It Works

When a Gemini API job completes (or fails, or is cancelled), the API delivers a real-time HTTP POST payload to a URL registered by the developer. The payload is a thin notification containing the job ID, output file URI, timestamps, error details if applicable, and optional metadata. The developer's server acknowledges with a 2xx status, then processes the result asynchronously.

The system guarantees at-least-once delivery, retrying failed deliveries for up to 24 hours. Every webhook request is signed following the Standard Webhooks specification, using webhook-signature, webhook-id, and webhook-timestamp headers. This signing scheme prevents replay attacks and allows servers to verify the request authentically originated from Google.

Two Configuration Modes

Google supports two distinct webhook architectures to cover different use cases:

Static webhooks are registered at the project level in AI Studio or via the API. They fire for all matching events across the project and use symmetric HMAC-based signing. The signing secret is returned only once at creation β€” losing it requires rotation.

Dynamic webhooks are configured per-request, passed directly when submitting a batch job or interaction. They use asymmetric JWT signatures verified against Google's public JWKS endpoints, making them well-suited for routing specific tasks to dedicated handlers or isolating jobs across different services.

Supported Operations and Event Types

Webhooks work across the following Gemini API surfaces:

  • Batch API β€” batch.succeeded, batch.failed, batch.cancelled, batch.expired
  • Interactions API β€” interaction.requires_action, interaction.completed, interaction.failed
  • Video generation β€” video.generated

The interaction.requires_action event is especially notable for agentic use cases: it allows an agent to pause mid-task, push a function-call request to the developer's server, and resume only after the server provides the tool result β€” without the agent needing to maintain an open connection.

Developer Implementation

The recommended implementation pattern keeps webhook handlers fast. Servers should respond with a 2xx status within a few seconds to prevent retries, then process the actual job output asynchronously in a background queue. Google provides a complete end-to-end cookbook in the google-gemini/cookbook GitHub repository, including a webhooks quickstart notebook.

The Gemini Python SDK exposes webhook registration and signature verification helpers. A minimal dynamic webhook configuration looks like:

response = client.batches.create(
    model="gemini-3-flash",
    src="gs://my-bucket/input.jsonl",
    config={"webhook": {"uri": "https://myserver.example/webhook"}}
)

For static webhooks, developers register the endpoint once and all qualifying events are routed there automatically, with no per-request configuration required.

What This Means for Developers

For developers running high-volume batch inference pipelines β€” document processing, evaluation suites, fine-tuning data generation β€” webhooks replace an entire class of polling infrastructure. Jobs that previously required a scheduled cronjob or a sleeping thread to detect completion can now be event-driven from end to end.

The feature is available now for all developers using the Gemini API with no additional pricing implications noted at launch.