Google ha lanzado webhooks event-driven para la Gemini API, eliminando el polling para jobs largos a través de tres familias de endpoints: Batch (succeeded / cancelled / expired / failed), Interactions (requires_action / completed / failed / cancelled), y Video Generation (video.generated). La implementación sigue la spec Standard Webhooks — firma HMAC-SHA256 para webhooks estáticos (a nivel proyecto), JWT asimétrico (RS256) vía JWKS para webhooks dinámicos (por request), con headers `webhook-signature`, `webhook-id`, y `webhook-timestamp`. Entrega at-least-once, ventana de retry de 24h con backoff exponencial. Ventana anti-replay recomendada: rechazar payloads de más de cinco minutos de antigüedad.
Los dos modos de configuración importan. *Estático*: configurado a nivel proyecto vía un WebhookService API, dispara para cualquier event matching bajo ese proyecto, usa un secreto compartido para validación HMAC. *Dinámico*: override en tiempo de request con un payload `webhook_config`, usa JWT asimétrico firmado por las claves de Google (verificable en `https://generativelanguage.googleapis.com/.well-known/jwks.json`). El modo dinámico también soporta un campo `user_metadata` para enrutamiento — la metadata viaja de ida y vuelta en el payload del webhook, así que un solo endpoint puede hacer fan-out por tenant, usuario, o workflow sin almacenar estado de job-ID por separado. Los payloads son intencionalmente delgados: snapshots de estado con punteros como `output_file_uri` (Batch) o `file_id` y `video_uri` (Video), no salidas crudas. Los servidores responden `2xx` inmediatamente y procesan async para evitar ciclos de retry. El header `webhook-id` te da la primitiva de deduplicación.
Para contexto de ecosistema, esto pone la Gemini API en paridad-plus en entrega de events. La Batch API de OpenAI y los Message Batches de Anthropic ambos corren async con estado que actualmente *pollas* — una corrida batch de 24h significa polling en horario quemando presupuesto de requests esperando la completación. Los webhooks invierten eso: tu aplicación duerme hasta que Google le notifique. Para generación de video específicamente (cargas estilo Veo pueden correr decenas de segundos a minutos por request), el polling es aún más derrochador. El split estático-vs-dinámico está bien pensado: estático para "tengo un equipo corriendo batch jobs, dame un secreto para verificarlos a todos", dinámico para "soy un SaaS corriendo cargas Gemini multi-tenant y necesito que cada webhook de tenant aterrice en su endpoint aislado con su metadata adjunta". Esa es una forma de capacidad útil de copiar si construyes algo similar.
Lecturas prácticas. Si corres jobs Gemini Batch o de video y actualmente polleas, cambia — esto ahorra llamadas API, reduce latencia de cola en la detección de completación, y es estructuralmente más limpio. La ventana anti-replay de 5 minutos más dedup por `webhook-id` significa que tu handler de webhook necesita una capa de idempotencia (la mayoría ya la tienen). Para devs multi-tenant, webhooks dinámicos con `user_metadata` es el patrón correcto — no intentes mapear webhooks estáticos entre tenants parseando job IDs. Compara tu overhead actual de polling OpenAI / Anthropic y decide si vale la pena empujar a esos proveedores a lanzar cobertura Standard Webhooks también. La señal no es "los webhooks son nuevos"; los webhooks son viejos. La señal es que las APIs IA finalmente están recibiendo tratamiento Standard Webhooks, lo que significa que la infraestructura agent-and-batch puede construirse con las mismas primitivas operacionales que el resto de tu stack.
