Examples

Wait For Approval

Breyta wait-for-approval example for human-in-the-loop orchestration using canonical wait config.

Quick Answer

Use flow/step :wait with :key, explicit :timeout, and a deterministic timeout outcome.
Use a top-level function for approval-to-status mapping and label orchestration branch nodes for readable timelines.

Use Case

Pause execution until an approver chooses approve/reject (or timeout policy is applied).

Full Definition

{:slug :wait-for-approval
 :name "Wait For Approval"
 :concurrency {:type :singleton :on-new-version :supersede}
 :functions [{:id :approval->status
              :language :clojure
              :code "(fn [input] (let [action (keyword (or (get-in input [:approval :action]) \"reject\"))] {:status (if (= :approve action) :approved :rejected)}))"}]
 :triggers [{:type :manual :label "Run" :enabled true :config {}}]
 :flow
 '(let [input (flow/input)
        approval (flow/step :wait :approval
                   {:key (str "approval:order:" (:order-id input))
                    :timeout "1h"
                    :on-timeout :continue
                    :default-value {:action :reject :reason :timeout}
                    :notify {:channels {:http {:connection :sendgrid
                                               :path "/v3/mail/send"
                                               :method :post
                                               :json {:personalizations [{:to [{:email "approver@example.com"}]}]
                                                      :from {:email "approvals@example.com"}
                                                      :subject "Approve Order {{order-id}}"
                                                      :content [{:type "text/plain"
                                                                 :value "Order requires human review.\nApprove: {{approval-url}}\nReject: {{rejection-url}}"}]}}}}})
        decision (flow/step :function :derive-status
                   {:ref :approval->status
                    :input {:approval approval}})
        outcome ^{:label "Approval branch"
                  :yes "Approved"
                  :no "Rejected/timeout"}
                (if (= :approved (:status decision))
                  {:status :approved :approval approval}
                  {:status :rejected :approval approval})]
    outcome)}

Expected Behavior

Run pauses at :approval until action is submitted or timeout is reached.

Operating Notes

  • set explicit :timeout for every wait
  • use business identifiers in wait key/message
  • treat timeout as a deliberate business branch, not an implicit error
  • include order id, concise reason, and enough context for a decision without external lookups

Validation tip:

  1. start run with an :order-id
  2. confirm run enters waiting state
  3. test approve/reject and timeout outcomes

Try Next

As of Feb 13, 2026