New to Kestra?
Use blueprints to kickstart your first workflows.
Kestra flow that takes a multiselect of paused execution ids and an Approve or Reject decision, then resumes each execution through the Kestra API with a signoff value.
Give approvers one screen instead of one email per request. This Kestra blueprint is the backend of an approver console: a reviewer picks any number of paused executions from a multiselect, chooses Approve or Reject, and the flow resumes each approved execution through the Kestra executions API, passing a signoff value into the paused task's onResume inputs. It is designed to sit behind a Kestra App (an Enterprise Edition and Kestra Cloud feature) that lists pending approvals as a form, turning dozens of individual human-in-the-loop gates into a single batch decision.
executionIdsToBeApproved input (MULTISELECT with allowCustomValue: true) carries the ids of paused executions. In the companion App this list is populated dynamically from the executions API; the static values here are placeholders to replace.action input (SELECT) captures the decision, Approve or Reject.logDecision task (io.kestra.plugin.core.log.Log) records who decided what, making every batch approval auditable as an execution.for_each task (io.kestra.plugin.core.flow.ForEach) iterates the selected ids with concurrencyLimit: 1 so resumes happen in order. Its runIf only fires when the action is Approve and at least one execution was selected, so a Reject decision is simply logged without resuming anything.approve task (io.kestra.plugin.core.http.Request) POSTs multipart/form-data to /api/v1/{tenant}/executions/{id}/resume with a bearer token, submitting signoff: true as the onResume input of the paused io.kestra.plugin.core.flow.Pause task in each target flow.Approvals scattered across emails and UI clicks leave no consolidated record and scale linearly with request volume. By making the approval itself a flow, every batch decision gets inputs, logs, timestamps, and an identity attached. The ForEach plus Request combination works against any Kestra tenant, and because the decision is just an execution, you can trigger notifications, SLA timers, or escalation flows from it like any other event. Pair it with a Kestra App form and approvers never need to open individual executions at all.
io.kestra.plugin.core.flow.Pause and accept a signoff value in onResume.kestraUrl and tenant variables for your instance.KESTRA_API_TOKEN: bearer token used by the Request task to call the executions resume API.KESTRA_API_TOKEN to your Kestra namespace and set the kestraUrl and tenant variables.Pause task with a signoff boolean in onResume.signoff: true.expression that queries the executions API for paused runs.io.kestra.plugin.notifications.slack.SlackIncomingWebhook.reason input and forward it in formData so approvals carry a justification.