Approval (PbotApproval)

PbotApproval pauses workflow execution and waits for a human to review and decide. The reviewer sees the context you provide, makes a decision, and the workflow resumes with their response in context.


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

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/:stepIndex Engine->>Engine: Run status → "running" Engine->>Workflow: Resume with approval context

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 http://localhost:3009/approvals/{runId}/0 \
  -H "X-Org-Id: acme-corp" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": true,
    "comments": "Reviewed and approved — receipt verified",
    "data": {
      "reviewer": "[email protected]",
      "override_amount": null,
      "notes": "All documentation present"
    }
  }'
POST/approvals/:runId/:stepIndex

Submit an approval decision for a paused workflow.

3. Workflow resumes

After submission, the run resumes from the next step. The approval response is available in context.


Approval Response Format

Field Type Required Description
approved boolean Yes Whether the reviewer approved
comments string No Reviewer's comments
data object No Additional structured data from the reviewer

Context After Approval

After a PbotApproval step completes, the following keys are added to context:

Context Key Value
@__approved Boolean — true if approved, false if rejected
@__approval_data The data object from the reviewer's response

Use these in subsequent steps to branch on the approval result:

json
{
  "type": "process_expense",
  "filter": {
    "condition": { "equal": ["@__approved", true] }
  },
  "properties": {
    "expense_id": "@input.id",
    "approved_by": "@__approval_data.reviewer"
  },
  "onFalse": {
    "type": "notify_employee",
    "properties": {
      "message": "Your expense was rejected. Reason: {{__approval_data.notes}}"
    }
  }
}

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 runId, stepIndex, comment, and request_payload so your notification system can provide full context.

→ Next: Form (PbotForm)