New to Kestra?
Use blueprints to kickstart your first workflows.
Use a Kestra Flow trigger and ZulipExecution to alert a Zulip stream on FAILED flows in a namespace, with retry and timeout.
This flow is a centralized, namespace-level alerting hook. It does not run on a schedule and has no upstream data of its own. Instead, a Flow trigger watches every execution under the company namespace and reacts whenever one finishes in a FAILED state. When that happens, the ZulipExecution task renders the execution metadata and posts it to a Zulip stream, so on-call engineers see one consistent alert instead of wiring a notification into each individual flow.
The flow itself lives in the reserved system namespace so it is not matched by its own company namespace condition. This is the recommended pattern for instance-wide alerting flows: it keeps monitoring flows out of your business namespaces and avoids any risk of the alert reacting to its own executions. Because this flow IS the failure alerter, it deliberately has no flow-level errors block of its own (that would risk an alert-on-the-alerter loop); instead it hardens the single notification task with retry and a timeout.
ZulipExecution does not retry and does not raise on a non-200 response, so on its own a transient Zulip or network blip at the exact moment an upstream flow fails would drop the alert silently. To reduce that risk the task carries a retry (constant, three attempts, 30s apart) and a timeout (PT30S) so a hung POST cannot wedge the worker. Delivery is still best-effort: because the task does not raise on a non-200 status, a persistent Zulip outage can still lose a message, so treat this as a notification convenience rather than a guaranteed-delivery channel.
ZulipExecution auto-renders a built-in execution metadata block (link, ID, namespace, flow name, start date, duration, terminal status, and the failing task when applicable). The customMessage you see in the YAML is appended to that block, not a replacement for it, so the message in Zulip is the rich metadata followed by your custom note.
io.kestra.plugin.core.trigger.Flow trigger listens for state transitions across the instance.ExecutionStatus condition limits it to the FAILED terminal state. WARNING is intentionally excluded by default: in a busy namespace, WARNING is common (allowed-failure tasks, soft assertions) and lumping it with FAILED trains operators to ignore the channel. To opt in, add WARNING to the in: list, ideally routing it to a separate channel or topic.ExecutionNamespace condition with prefix: true scopes it to the company namespace and all of its children (for example company.team, company.payroll).ZulipExecution is given executionId: {{ trigger.executionId }} so it reports on the original failed execution rather than this alerting execution.There is no built-in throttle or dedup: a flow that fails repeatedly (a flapping schedule) will post one message per failure. If that is a concern, add a MultipleCondition or a cooldown flow in front of this hook.
ZULIP_WEBHOOK: the full Zulip incoming webhook URL, including the integration path and API key, in the form https://yourZulipDomain.zulipchat.com/api/v1/external/INTEGRATION_NAME?api_key=API_KEY. Used by ZulipExecution to post the alert.ZULIP_WEBHOOK in your Kestra namespace or environment.ExecutionNamespace condition to the namespace you want to monitor, and set the channel input to your target stream.ZulipExecution is a notification task and does not write files to internal storage, so there is no {{ outputs.notify_zulip.uri }} artifact. Success is observed as a message appearing in the configured Zulip stream and a SUCCESS state on the notify_zulip task in the Logs tab. If delivery fails, the task does not raise on a non-200 response, so check the task logs.