Approval Flow

When Yebo returns REQUIRE_APPROVAL, execution pauses. Nothing runs until a human explicitly approves.

This page shows the complete loop: how approval requests are created, how to approve them, and how execution resumes.


When does this trigger?

REQUIRE_APPROVAL is returned when the amount falls between your policy's auto_approve_below and deny_above thresholds:

{
  "auto_approve_below": 500,
  "deny_above": 10000
}

Any payment between $500 and $10,000 triggers an approval request. Amounts below $500 are auto-authorized. Amounts above $10,000 are blocked outright.


Step 1 — Agent calls protectPayment()

import { protectPayment } from "yebo-protect";

const result = await protectPayment({
  type: "payment",
  amount: 5000,
  vendor: "Big Vendor",
  currency: "USD",
});

// result.decision   → "REQUIRE_APPROVAL"
// result.reason     → "Amount $5,000 requires human authorization ($500–$10,000)"
// result.policy_rule → "require_approval_range"
// result.pending_id  → "pnd_abc123..."
// result.next_step   → "Approval required — run: yebo approve pnd_abc123..."

The payment is not sent to Stripe. A pending approval record is written locally.


Step 2 — Human reviews pending approvals

List all pending approvals:

yebo list

Output:

Pending Approvals
─────────────────────────────────────────────────────────────────
ID              Amount      Vendor        Policy Rule        Created
pnd_abc123...   $5,000      Big Vendor    require_approval   2 minutes ago
─────────────────────────────────────────────────────────────────
  run: yebo approve <id>   to approve
  run: yebo reject <id>    to deny

Step 3 — Human approves

yebo approve pnd_abc123...

Output:

  Mandate pnd_abc123... approved.
  Run: yebo exec pnd_abc123... to execute the payment.

This marks the mandate as approved. It does not execute Stripe yet — that is your explicit decision.


Step 4 — Execute the approved mandate

yebo exec pnd_abc123...

Output:

  Executing approved mandate pnd_abc123...
  ✓ Payment authorized by Yebo policy
  ✓ Stripe PaymentIntent created: pi_3abc...
  ✓ Status: succeeded

  Amount:  $5,000
  Vendor:  Big Vendor
  Executed at: 2026-03-04T14:32:00Z

Stripe only runs after this explicit exec command.


Alternative — Auto-resume in code

If you want the agent to automatically resume execution once approved, use wait_for_approval: true:

const result = await protectPayment(
  {
    type: "payment",
    amount: 5000,
    vendor: "Big Vendor",
    currency: "USD",
  },
  {
    wait_for_approval: true,       // polls every 2 seconds (max 5 minutes)
    poll_interval_ms: 2000,
    approval_timeout_ms: 300_000,
  }
);

// result.decision → "ALLOW" once human approves (Stripe has executed)
// result.decision → "DENY" if human rejects
// result.timed_out → true if no response within 5 minutes

With wait_for_approval: true, the function blocks until a human runs yebo approve <id>. When they do, executeApproved() is called automatically and the payment executes.


Reject a mandate

To block a pending payment:

yebo reject pnd_abc123...

Output:

  Mandate pnd_abc123... rejected.
  No payment will be executed.

The complete loop

protectPayment()
  → decision: REQUIRE_APPROVAL
  → pending_id: pnd_abc123...
  
yebo list
  → shows pending mandates

yebo approve pnd_abc123...
  → marks approved

yebo exec pnd_abc123...
  → Stripe executes
  → receipt returned

# OR — with wait_for_approval: true:
protectPayment({ wait_for_approval: true })
  → blocks until human approves
  → auto-executes on approval
  → resolves with final result

Approval link (web)

Every pending mandate also has a web approval link:

https://yebo.dev/approve/pnd_abc123...

This can be sent to a human approver via Slack, email, or any notification system. The approver clicks the link, reviews the mandate, and approves or rejects — no CLI required.


What happens if nobody approves?

Pending mandates expire after 24 hours by default. An expired mandate cannot be approved or executed. Call protectPayment() again to create a new one.


Get Started

npx create-yebo    # see REQUIRE_APPROVAL in the sandbox demo

Run node yebo-demo/large-payment.js to see the full approval flow output locally.

Quickstart →  |  Start a pilot →