Skip to content

Webhooks

Gunpal Jain edited this page Nov 15, 2026 · 1 revision

Webhooks

Webhooks let Google call your HTTPS endpoint when a long-running job finishes, so you don't have to poll. Events cover batch jobs, interactions and video generation.

The SDK has two pieces:

  • WebhooksClient (namespace GenerativeAI.Clients) registers and manages project-level webhooks: create, get, list, update, delete, ping and rotate the signing secret.
  • Per-request webhook configuration: WebhookConfig on a batch job and InteractionWebhookConfig on an interaction.
Feature Gemini API Vertex AI
WebhooksClient Yes The client builds the Vertex URL (.../projects/{project}/locations/{location}/webhooks); availability depends on the service.
WebhookConfig on BatchClient.CreateAsync Yes No: throws NotSupportedException
InteractionWebhookConfig on interactions Yes Depends on Interactions API availability

Prerequisites

  • NuGet package: Google_GenerativeAI
  • A Gemini API key. See Authentication.
  • A public HTTPS endpoint that accepts POST requests.
using GenerativeAI;
using GenerativeAI.Clients;
using GenerativeAI.Types;

var googleAi = new GoogleAi(apiKey);
WebhooksClient webhooks = googleAi.CreateWebhooksClient();
// or: new WebhooksClient(new GoogleAIPlatformAdapter(apiKey));

Events

Subscribe to events with the constants in WebhookEvents:

Constant Value
WebhookEvents.BatchSucceeded batch.succeeded
WebhookEvents.BatchFailed batch.failed
WebhookEvents.BatchExpired batch.expired
WebhookEvents.InteractionCompleted interaction.completed
WebhookEvents.InteractionFailed interaction.failed
WebhookEvents.InteractionRequiresAction interaction.requires_action
WebhookEvents.VideoGenerated video.generated

Create a webhook

Webhook webhook = await webhooks.CreateAsync(
    "https://example.com/gemini-events",
    new[] { WebhookEvents.BatchSucceeded, WebhookEvents.BatchFailed },
    name: "batch-notifications");

Console.WriteLine(webhook.Id);
// The signing secret is only returned in this response: store it now.
Console.WriteLine(webhook.NewSigningSecret);

CreateAsync(CreateWebhookRequest) is the long form (Name, Uri, SubscribedEvents). Uri and at least one subscribed event are required; otherwise an ArgumentException is thrown.

Get, list, update and delete

var fetched = await webhooks.GetAsync(webhook.Id!);
Console.WriteLine($"{fetched.Uri} {fetched.State}");   // State: WebhookStates.Enabled, Disabled, DisabledDueToFailedDeliveries

// One page at a time (page size defaults to 50, max 1000)...
WebhookListResponse page = await webhooks.ListAsync(pageSize: 50);
// ...or all of them.
await foreach (var w in webhooks.ListAllAsync())
    Console.WriteLine($"{w.Id}: {string.Join(", ", w.SubscribedEvents ?? new List<string>())}");

// Only non-null fields are sent. updateMask is optional (sent as update_mask).
var updated = await webhooks.UpdateAsync(webhook.Id!, new WebhookUpdate
{
    SubscribedEvents = new List<string> { WebhookEvents.InteractionCompleted },
    State = WebhookStates.Enabled
}, updateMask: "subscribed_events,state");

await webhooks.DeleteAsync(webhook.Id!);

IDs with a webhooks/ prefix are accepted.

Ping

Send a test event to the endpoint:

WebhookPingResponse ping = await webhooks.PingAsync(webhook.Id!);

Rotate the signing secret

var rotated = await webhooks.RotateSigningSecretAsync(webhook.Id!,
    WebhookRevocationBehaviors.RevokePreviousSecretsAfterH24);   // or RevokePreviousSecretsImmediately
Console.WriteLine(rotated.Secret);

Webhook.SigningSecrets lists the current secrets (TruncatedSecret, ExpireTime).

Per-request webhooks

Batch jobs (Gemini API only)

Pass a WebhookConfig to BatchClient.CreateAsync. It is sent as batch.webhookConfig:

var batch = googleAi.BatchClient;
var job = await batch.CreateAsync(
    GoogleAIModels.Gemini38Flash,
    source,                       // a BatchJobSource
    destination: null,
    webhookConfig: new WebhookConfig { Uris = new List<string> { "https://example.com/batch-done" } });

WebhookConfig.UserMetadata (Dictionary<string, JsonNode?>) lets you attach your own data to the notification. On Vertex AI, passing a WebhookConfig throws NotSupportedException. See Batch API.

Interactions

var interactions = googleAi.CreateInteractionsClient();
var created = await interactions.CreateAsync(new CreateInteractionRequest
{
    Model = InteractionModels.Gemini38Flash,
    Input = "Write a long report on solar power.",
    Background = true,
    WebhookConfig = new InteractionWebhookConfig { Uris = new List<string> { "https://example.com/interaction-done" } }
});

See Interactions API.

Verifying signatures

The SDK does not include a helper for verifying the signature of incoming webhook requests. Verify deliveries in your endpoint with the signing secret returned by CreateAsync or RotateSigningSecretAsync, following Google's webhook documentation (https://ai.google.dev/gemini-api/docs/webhooks).

Error handling

  • API errors are thrown as GenerativeAI.Exceptions.ApiException (ErrorCode, ErrorStatus, ErrorMessage). A 403/404 usually means webhooks are not enabled for the project.
  • ArgumentException for missing URI, missing events or an empty webhook ID.
  • NotSupportedException for WebhookConfig on a Vertex AI batch job.
try
{
    await webhooks.PingAsync(webhookId);
}
catch (ApiException ex)
{
    Console.WriteLine($"Ping failed: {ex.ErrorCode} {ex.ErrorStatus} {ex.ErrorMessage}");
}

Related pages

Clone this wiki locally