Skip to content

Approval steps

Some steps shouldn't fire without a human glance first. Posting to a public channel. Sending an email to a customer. Spending money. An approval node pauses the workflow, asks for a yes-or-no, and continues based on the answer.

The shape

yaml
nodes:
  - id: draft-summary
    type: prompt
    prompt: |
      Summarize this morning's Slack into a single brief.

  - id: review-summary
    type: approval
    depends_on: [draft-summary]
    prompt: |
      Here's the morning brief. Approve to post it to #leadership.

      $draft-summary.output

  - id: post-to-slack
    type: prompt
    depends_on: [review-summary]
    prompt: |
      Post the approved brief to #leadership: $draft-summary.output

When the workflow hits review-summary, it stops. The prompt text shows up wherever the workflow is being watched (your terminal, the Web UI's run detail, your agent's chat surface). You reply approve or reject. The workflow resumes accordingly.

On rejection

By default, a rejected approval node fails the whole workflow. You can override with on_reject::

yaml
  - id: review-summary
    type: approval
    depends_on: [draft-summary]
    on_reject:
      action: rework
      max_retries: 2
    prompt: |
      Here's the morning brief. Approve to post it.

The rework action sends the rejection back to the upstream node with the rejection reason in $REJECTION_REASON, so the rewrite can address what was wrong.

yaml
  - id: draft-summary
    type: prompt
    prompt: |
      Summarize this morning's Slack.
      {{#REJECTION_REASON}}
      The previous draft was rejected. Reason: $REJECTION_REASON
      {{/REJECTION_REASON}}

Capturing the reply

If you want the human's reply to feed into downstream work (not just yes/no), set capture_response: true:

yaml
  - id: review-summary
    type: approval
    capture_response: true
    prompt: |
      Here's the brief. Approve to post, or reply with edits.

Whatever the reviewer typed lands in $review-summary.output.

Where the prompt shows up

The approval prompt is delivered through whatever surface is watching the run.

  • Terminal. Z.E.N. prints the prompt and waits for approve / reject.
  • Web UI. The run detail page shows the prompt with approve and reject buttons.
  • Slack / Telegram. If the workflow was dispatched from there, the prompt arrives as a message; reply approve or reject.
  • Agent dispatch. Your agent gets the prompt as part of the streaming response and can either ask you or decide on its own.

When to use approvals vs. just trust the model

Use approvals when the next step is a one-way door (sending email, posting publicly, executing a transaction). Don't use them on every step; a workflow that asks for human approval six times is a workflow you'll stop using by Friday.

A useful rule: if the model can recover from being wrong by trying again, no approval needed. If the model being wrong means a customer sees a bad message, gate it.

AI that follows a recipe, not a conversation.