New to Kestra?
Use blueprints to kickstart your first workflows.
Reusable Kestra subflow that enriches a purchase order with product details, notifies Slack, pauses for manager approval, and returns the decision as outputs.
Make finance sign-off a reusable building block instead of an email thread. This Kestra blueprint is a self-contained approval stage: it receives a product id, requestor, and department, enriches the request with live product details, notifies the finance channel in Slack with a link to an approval form, pauses until a manager decides, and returns managerApproved and managerComments as typed flow outputs. Any parent flow, like the companion product-order-approval-hitl blueprint, can call it with io.kestra.plugin.core.flow.Subflow and branch on the verdict. The approval link uses appLink(), which resolves when a Kestra App (an Enterprise Edition and Kestra Cloud feature) is bound to the flow.
productId, requestor, and department, so callers pass context, not payloads.getProductDetails task (io.kestra.plugin.core.http.Request) fetches the product record from the catalog API (dummyjson.com as a stand-in) using the trimmed productId.appParams task (io.kestra.plugin.core.output.OutputValues) extracts productName, productPrice, and productImageLink from the JSON body. These values are base64-encoded into the App link so the approval form can render a rich card with name, price, and image instead of a bare execution id.hitlProcess block (io.kestra.plugin.core.flow.Sequential), sendApprovalNotification logs the approval URL and notifyChannel (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts it to the finance channel, both embedding the flow inputs and display parameters via {{ appLink() }}&flowInputs=...&appParams=....waitForApproval task (io.kestra.plugin.core.flow.Pause) suspends the execution with an onResume schema of a BOOLEAN decision and a STRING reason. The execution holds durably until the manager submits the form or resumes from the UI.managerApproved (BOOL) and managerComments (STRING), giving parent flows a clean, typed contract.Subflow.Approval logic embedded in every business flow gets duplicated, drifts, and becomes impossible to audit consistently. Extracting the gate into a subflow gives you one implementation with one notification format, one decision schema, and one place to change policy. Kestra's Pause holds state server-side for as long as the decision takes, the parent-child execution link preserves lineage from request to verdict, and the onResume inputs turn a human decision into structured data the rest of the pipeline consumes like any other output.
appLink() resolves (EE or Kestra Cloud); without one, replace the link with the execution URL.product-order-approval-hitl blueprint as an example caller.SLACK_WEBHOOK: Slack incoming webhook URL used by notifyChannel.SLACK_WEBHOOK secret to your Kestra namespace.productId such as 1.managerApproved and managerComments outputs on the execution.io.kestra.plugin.core.flow.Subflow and branch on the outputs.runIf.timeout on the Pause and notifying a second approver.io.kestra.plugin.jdbc.postgresql.Query for reporting.managerApproved.