← All examples
WebhookApprovalDurability

Hold an order for human approval

Turn an incoming order into a durable decision point that survives restarts and records the path that was taken.

The webhook validates its input before a run exists. Once admitted, the workflow prepares a review summary and waits at <approval>. WOML persists the wait before exposing its decision capability, so the process can restart without losing the pending approval.

The workflow

WOML
<woml>
  <workflow
    id="order-approval"
    name="Order approval"
    description="Hold a submitted order for an explicit human decision."
    version="1.0.0"
  >
    <config concurrency="8" timeout="48h" queue="orders" />

    <triggers>
      <webhook
        id="submitOrder"
        path="/webhooks/orders"
        method="POST"
        auth="bearer"
        secret="{{secrets.ORDER_WEBHOOK_TOKEN}}"
      >
        <schema>
          {
            "type": "object",
            "required": ["orderId", "customer", "amount"],
            "properties": {
              "orderId": { "type": "string" },
              "customer": { "type": "string" },
              "amount": { "type": "number", "minimum": 0 }
            },
            "additionalProperties": false
          }
        </schema>
      </webhook>
    </triggers>

    <steps>
      <step id="reviewSummary" name="Prepare review summary">
        <script>
          return {
            orderId: context.payload.orderId,
            customer: context.payload.customer,
            amount: context.payload.amount
          };
        </script>
      </step>

      <approval
        id="reviewOrder"
        name="Review order"
        description="Approve or reject the submitted order."
        timeout="24h"
        on-timeout="reject"
      >
        <when-approved>
          <step id="acceptOrder" name="Accept order">
            <script>
              return {
                orderId: context.steps.reviewSummary.orderId,
                status: "approved"
              };
            </script>
          </step>
        </when-approved>

        <when-rejected>
          <step id="declineOrder" name="Decline order">
            <script>
              return {
                orderId: context.steps.reviewSummary.orderId,
                status: "rejected"
              };
            </script>
          </step>
        </when-rejected>
      </approval>
    </steps>
  </workflow>
</woml>

Run it

Store the bearer token, validate the workflow, and start the webhook listener.

Terminal
woml secrets set ORDER_WEBHOOK_TOKEN
woml check order-approval.woml
woml run order-approval.woml

The approval can also include Slack, Telegram, Discord, WhatsApp, or an imported notification provider. Leaving <notify> out keeps the decision model intact while letting an operator use WOML’s approval HTTP surface directly.