Return icon
Request icon
If icon
Parallel icon
Log icon
Sequential icon
SlackIncomingWebhook icon
Pause icon
Subflow icon

Product Order with Human Approval and Finance Sign-Off

Kestra flow with dependent dynamic inputs, stock checks, a Pause approval gate collecting structured onResume inputs, Slack notification, and a chained finance approval subflow.

Categories
Business

Model a real procurement chain in a single declarative flow. This Kestra blueprint demonstrates three advanced patterns together: dynamic, dependent inputs populated live from an API; an inventory-aware ordering decision; and a two-stage human-in-the-loop approval where the first reviewer answers structured questions and a second finance approval runs as a subflow. It uses the public dummyjson product API as a stand-in for your catalog, so it runs out of the box, and it links approvers to a companion Kestra App form through appLink() (an Enterprise Edition and Kestra Cloud feature).

How it works

  1. The category input (SELECT) is populated at execution time by an expression calling the products API with the http() Pebble function; the product input depends on it via dependsOn and reloads its options when the category changes.
  2. The getProductId task (io.kestra.plugin.core.debug.Return) resolves the chosen title to an id with an inline jq filter, defaulting to -1 when not found.
  3. The getProductDetails task (io.kestra.plugin.core.http.Request) fetches the product with allowFailed: true so an unknown product does not crash the flow.
  4. The processOrder task (io.kestra.plugin.core.flow.If) checks the HTTP code and availabilityStatus against the AVAILABLE and LOW variables. In-stock products run a io.kestra.plugin.core.flow.Parallel block that logs inventory, places the order, and fires a restock alert only for low stock. Anything else lands in cancelOrder.
  5. The hitlProcess block (io.kestra.plugin.core.flow.Sequential) runs only when the order was not cancelled. It logs and posts an approval link to Slack (io.kestra.plugin.slack.notifications.SlackIncomingWebhook), embedding the flow inputs and requestor in the appLink() URL, then pauses with io.kestra.plugin.core.flow.Pause. The onResume schema collects a boolean decision, free-text notes, and a cost center from the approver.
  6. After resume, sendToVendor summarizes the decision, sendPurchaseOrderForFinanceApproval (io.kestra.plugin.core.flow.Subflow) launches the purchase-order-finance-approval flow, and financeApprovalStatus reports the manager's verdict. Flow-level outputs expose order, invoice, and purchase order status to callers.

What you get

  • Dependent dropdown inputs whose options come from a live API at execution time.
  • A Pause gate that captures structured, typed decisions instead of a bare resume click.
  • Two chained approval stages with full lineage between parent and subflow.
  • Typed flow outputs consumable by any calling flow or API client.

Who it's for

  • Teams modeling procurement, ordering, or request workflows with multiple sign-offs.
  • Platform engineers learning dynamic inputs, runIf, and onResume patterns.
  • Solutions engineers demonstrating human-in-the-loop orchestration end to end.

Why orchestrate this with Kestra

Approval chains usually end up split across a form tool, a ticketing system, and scripts, with no single record of what was requested, decided, and executed. Kestra keeps the entire chain in one execution graph: inputs are validated and versioned, the pause holds state durably for as long as the approver needs, the structured onResume answers become outputs downstream tasks can branch on, and the finance stage is a reusable subflow other processes can call too. The companion App gives approvers a clean form without granting them access to the Kestra UI.

Prerequisites

  • Outbound HTTP access from the Kestra host to dummyjson.com (or swap in your catalog API).
  • The companion purchase-order-finance-approval flow deployed in the same namespace.
  • A Kestra App bound to this flow so appLink() resolves (EE or Kestra Cloud); without one, replace the link with an execution URL.
  • A Slack incoming webhook for approval notifications.

Secrets

  • SLACK_WEBHOOK: Slack incoming webhook URL used by notifyChannel.

Quick start

  1. Add the SLACK_WEBHOOK secret to your Kestra namespace.
  2. Deploy purchase-order-finance-approval, then this flow.
  3. Execute it, picking a category and product from the dynamically loaded dropdowns.
  4. Open the paused execution (or the App link from Slack), answer the approval questions, and resume.
  5. Resume the finance subflow's pause and check the three flow outputs.

How to extend

  • Point the input expressions at your real product or service catalog API.
  • Replace the Return stubs with real vendor API calls or ERP tasks.
  • Add timeout behavior to the Pause tasks to auto-escalate stale approvals.
  • Route the cost center answer to different finance subflows with a Switch task.
  • Add unit tests for the ordering logic with Kestra's flow testing support.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.