Approval (PbotApproval)

PbotApproval pauses workflow execution and waits for a person to decide. An approval resumes the workflow. A rejection ends the run and keeps the decision in its record.


Basic Usage

json
{
  "type": "PbotApproval",
  "properties": {
    "comment": "Please review this expense for ${{input.amount}}",
    "request_payload": {
      "expense_id": "@input.id",
      "amount": "@input.amount",
      "category": "@input.category",
      "submitted_by": "@input.employee_name"
    }
  }
}

When execution reaches this step, the run status changes to paused. The workflow stays paused until the approval is submitted.


Properties Reference

Property Type Required Description
comment string Yes Human-readable description of what needs review. Supports {{ }} templates
request_payload object No Structured data presented to the reviewer
approver_role string No Role expected to review the task
expiry_seconds integer No Time allowed for a decision

Approval Flow

sequenceDiagram participant Workflow participant Engine participant Reviewer Workflow->>Engine: PbotApproval step Engine->>Engine: Run status → "paused" Engine-->>Reviewer: Webhook: pbot_approval_requested Note over Reviewer: Reviews context,<br/>makes decision Reviewer->>Engine: POST /approvals/:runId/:stepId alt Approved Engine->>Engine: Run status becomes "waiting_on_wakeup" Engine->>Workflow: Resume at the next step else Rejected Engine->>Engine: Run status becomes "failed" end

1. Workflow pauses

The engine changes the run status to paused and emits a pbot_approval_requested webhook.

2. Reviewer decides

The reviewer sees the comment and request_payload. They submit their decision:

bash
curl -X POST https://your-hyphen.example.com/approvals/{runId}/0 \
  -H "X-Org-Id: acme-corp" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": true,
    "comment": "Reviewed and approved - receipt verified"
  }'
POST/approvals/:runId/:stepId

Submit an approval decision for a paused workflow.

3. Hyphen applies the decision

An approved run resumes from the next step with the decision in context. A rejected run ends with a failed status. In both cases, the approval record keeps the reviewer, decision, comment, and timestamp.


Approval Response Format

Field Type Required Description
approved boolean Yes Whether the reviewer approved
comment string No Reviewer's comment

Context after approval

After an approval resumes the run, the following keys are available in context:

Context Key Value
@__approved Boolean value true
@__comment Comment text from the review decision

Use the context in the next step:

json
{
  "type": "process_expense",
  "properties": {
    "expense_id": "@input.id",
    "approval_comment": "@__comment"
  }
}

Conditional Approval

Combine with filter to only require approval under certain conditions:

json
{
  "type": "PbotApproval",
  "filter": {
    "condition": {
      "or": [
        { "greaterThan": ["@input.amount", 10000] },
        { "equal": ["@input.vendor_status", "new"] }
      ]
    }
  },
  "properties": {
    "comment": "High-value or new-vendor expense requires review",
    "request_payload": {
      "amount": "@input.amount",
      "vendor": "@input.vendor_name"
    }
  }
}

When the filter evaluates to false, the step is skipped and the workflow continues. The @__approved context key is not set in this case.


Listing Pending Approvals

GET/approvals/:runId

List all pending approval requests for a workflow run.


Webhook Notification

When a PbotApproval step pauses a workflow, a pbot_approval_requested webhook event is emitted. Use this to notify reviewers via your application, Slack, email, or any external system.

The webhook payload includes the run_id, step_id, comment, and request_payload so your notification system can provide full context.

→ Next: Form (PbotForm)