New to Kestra?
Use blueprints to kickstart your first workflows.
Retry a Gemini call for transient noise, fall back across three model versions on a sustained outage, cap concurrency, and alert Slack only when the fallback fires.
Preview-tier LLM APIs go UNAVAILABLE under load, and a webhook-triggered classification flow cannot just wait for the provider to recover. This blueprint keeps an inbound classification pipeline running when Gemini returns a 503 by retrying transient failures, falling back across three model versions in order, capping concurrent runs so the flow does not blow through its own Gemini quota, and posting one Slack message whenever the fallback path actually fires.
on_request trigger (io.kestra.plugin.core.trigger.Webhook) starts one execution per inbound request, exposing the payload as trigger.body.classify_request (io.kestra.plugin.gemini.ChatCompletion) calls gemini-3.1-pro-preview first, with a retry policy of 5 attempts on a 1-second constant interval and allowFailure: true so a persistent failure does not kill the execution outright.classify_fallback_1 calls gemini-3-pro-preview, gated by runIf so it only runs when the first call produced no prediction.classify_fallback_2 calls gemini-3.5-flash-lite, gated by a runIf that checks both prior tasks failed to produce a prediction.notify_if_fallback_used (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) fires only when a fallback task actually ran, giving the team visibility into outage cadence without paging on every retry.concurrency block (behavior: QUEUE, limit: 10) caps simultaneous executions so a burst of inbound requests cannot exhaust the Gemini quota or hammer the fallback chain in parallel.A hand-rolled script can retry once and catch an exception, but keeping retry, allowFailure, and concurrency consistent across every task as the flow grows is where glue code drifts. Kestra applies retry and fallback declaratively per task, exposes runIf to gate each fallback on the exact prior outputs, and enforces the concurrency queue at the flow level so the guarantee holds no matter how many tasks get added later. Every attempt, retry, and fallback is visible in one execution's history.
subject and message fields.GEMINI_API_KEY: API key shared by all three classification calls.WEBHOOK_KEY: the signing key for the inbound Webhook trigger.SLACK_WEBHOOK: incoming webhook URL for the fallback notification..../executions/webhook/company.team/gemini-model-fallback-resilience/{{ secret('WEBHOOK_KEY') }}.classify_request succeeds under normal conditions.model on classify_request to confirm the fallback chain and Slack alert fire correctly.