If you’ve ever built a production AI pipeline that runs long jobs — processing thousands of prompts overnight, kicking off a Deep Research agent, or generating a long video — you’ve almost certainly dealt with the polling problem. Your code is in a constant loop. GIVE Asking every few seconds “Is the job done yet?” The waste is not only expensive, but it also adds delay. At scale, this can become a problem for reliability. Google has just released the fix.
Google Introduced The event-driven webhook for the Gemini API — a push-based notification system that eliminates the need for inefficient polling. This feature, which is now available to all developers who use the Gemini API, targets an important pain point for AI workflows that are agentic or high volume.
The Scale Effect on Polling
It is important to define Long-Running Operation in order to better understand what the problem is. Gemini API can send real-time notifications when Long-Running Operations or asynchronous operations are complete. This eliminates the need for polling the API and reduces latency.
Before webhooks, the only option was continuous polling — repeatedly calling Get /operations To check whether a task has been completed. As Gemini shifts toward agentic workflows and high-volume processing — like Deep Research, long video generation, or processing thousands of prompts via the Batch API — operations can take minutes or even hours. It is costly to poll for long periods of time, both in terms of compute capacity and API usage.
It is easy to fix conceptually: Instead of asking your code for the answer, you should ask it directly. “are you done?” The Gemini API will call your server repeatedly the moment that a job is completed. It does this by sending a live HTTP POST to your endpoint.
Both static and dynamic configuration modes are available
Gemini’s API offers two different ways of configuring webhooks. Static webhooks are project-level endpoints configured with the WebhookService API and are suited for global integrations like notifying Slack or syncing a database — they are registered once per project and trigger for any matching event. Dynamic webhooks can be overridden at the request level and pass in a URL for triggering a webhook. webhook_config They are ideal for routing jobs that have a defined payload to specific endpoints. For example, in queues for agent orchestration.
Static webhooks can be compared to a constant instruction for your postman: “Always deliver packages to the front desk.” The term dynamic webhooks is more like: “For this one shipment, send it to my home address.” Dynamic webhooks have an additional feature. user_metadata field, which lets you attach arbitrary key-value metadata to a job at dispatch time — for example, {"job_group": "nightly-eval", "priority": "high"}. These metadata are sent with each job notification. They can be very useful when you want to send different types of jobs to different downstream processors, without having to build a separate tracking layer.
Standard Webhooks (HMAC), JWKS, and HMAC: Security Architecture
This implementation is most interesting in terms of security. Google’s implementation follows the Standard Webhooks specification. The signature of each request is used. webhook-signature, webhook-idThen, webhook-timestamp The headers ensure that the idempotency is maintained and prevent replay attacks.
For static webhooks, the signing is done with HMAC (Hash-based Message Authentication Code) using a symmetric shared secret, which is provided once at creation time and must be stored securely in your environment variables — the API returns this signing secret only once and it cannot be retrieved again. You have to rotate the key if you’ve lost it. It is possible to rotate the rotation point. revocation_behavior parameter — specifically REVOKE_PREVIOUS_SECRETS_AFTER_H24This option allows you to revoke the secret immediately in case of an incident.
Google instead uses public-key JWKS for dynamic webhooks. Your listener will need to extract the JSON Web Token signature (JWT), and then verify it with Google’s certificate endpoints. https://generativelanguage.googleapis.com/.well-known/jwks.json. For this type of verification, the RS256 algorithm will be used.
This means your server never blindly trusts incoming requests — every webhook hit can be cryptographically verified before you act on it. This means that your server will never blindly trust incoming requests — every webhook hit can be cryptographically verified before you act on it. webhook-timestamp Header is especially important. Best practices recommend always validating the timestamp of payloads and rejecting those older than 5 minutes in order to prevent replay attacks.
The Event Catalogue and Thin Payloads
A notable architectural choice is to use a thin payload. Gemini webhooks send a snapshot with status information and pointing to the results rather than delivering the actual output files. This is done in order to avoid congestion on bandwidth. The fields of that snapshot are determined by the type of event.
In batch jobs, the notification of a job completed is carried over. Id Then, you can. output_file_uri pointing to your results — for example, a Cloud Storage path like gs://my-bucket/results.jsonl. Video generation is done using the video.generated The event will deliver a unique set of fields. file_id You can also find out more about the following: video_uri. The server side handler should branch on type of event before it reads the data payload fields.
Three categories are covered by the event calendar: batch jobs, (batch.succeeded, batch.cancelled, batch.expired, batch.failedInteractions API Operations (interaction.requires_action, interaction.completed, interaction.failed, interaction.cancelledVideo generation (video.generated). Google has provided code samples that developers can use to write code. batch.completed Instead of batch.succeeded — both appear across the documentation, so match whichever your implementation uses.
For readers who are unfamiliar, the Interactions API is Gemini’s API for multi-turn async agent conversations. The Interactions API is Gemini’s API for async multi-turn agent conversations. interaction.requires_action event is particularly useful — it fires when a function call is pending and your application needs to step in and take an action before the agent can continue.
Deliveries Guarantees and Best practices
Google guarantees “at-least-once” The delivery can be retried up to 24 times using an exponential backoff. The “at-least-once” Your endpoint might receive the exact same event several times in high congestion conditions. Consistent webhook-id To deduplicate them, header can be used. You should receive a response from your server. 2xx status code immediately upon valid signature detection and queue any heavier parsing internally — prolonged listener hold times trigger the retry cycle, which is the opposite of what you want.
The Key Take-Aways
- No more polling loops — The Gemini API now pushes a signed HTTP POST to your server the instant a long-running job (Batch API, Deep Research, video generation) completes, eliminating the need to repeatedly call
Get /operations. - There are two webhooks for different architectures — Static webhooks handle project-level global integrations secured via HMAC; Dynamic webhooks bind to individual job requests via JWKS signatures and support
user_metadataCustom routing logic is available in the agent-orchestration pipes. - The security is integrated, not bolted-on — Every notification is cryptographically signed per the Standard Webhooks spec using
webhook-signature,webhook-idThen,webhook-timestampheaders. Use headers to prevent replay attacks and reject payloads older that 5 minutes.webhook-idto deduplicate at-least-once deliveries. - Payloads that are thin, but not results in the raw — Webhook notifications carry status pointers, not output data. Batch event return
output_file_uriVideo events are returningfile_idYou can also find out more about the following:video_uri. Never forget to respond2xximmediately and process asynchronously — slow responses trigger exponential-backoff retries for up to 24 hours.
Check out the Technical details here. Also, feel free to follow us on Twitter Don’t forget about our 130k+ ML SubReddit Subscribe Now our Newsletter. Wait! What? now you can join us on telegram as well.
You can partner with us to promote your GitHub Repository OR Hugging Page OR New Product Launch OR Webinar, etc.? Connect with us


