# Human-in-the-Loop AI Purchases: Approval Workflows That Actually Work

URL: https://firestarter.network/blog/human-in-the-loop-ai-purchases
Published: 2026-06-11
Author: Victor Young

Learn how to design human-in-the-loop approval workflows for AI agent purchases—propose, review, approve, execute—so agents act fast without overspending.

AI agents that buy things autonomously without any human checkpoint are a liability, not an asset. For most organizations, fully autonomous spending introduces too much financial and operational risk to be practical. The right model is human-in-the-loop: the agent does the research, surfaces options, and waits for a human to confirm before money moves. This post walks through the design patterns that make approval workflows fast enough to be useful and rigorous enough to be trustworthy.

## Why Fully Autonomous Spending Is a Non-Starter

The appeal of a fully autonomous purchasing agent is obvious—no friction, no waiting. But the risks compound quickly. An agent optimizing for speed might pick the cheapest option without accounting for supplier reliability. One optimizing for quality might exceed a budget. Without a human checkpoint, there is no moment to catch a misunderstood intent before money leaves the account.

There is also an organizational reality: most companies have procurement policies, approval chains, and audit requirements that exist for legal and financial reasons. An agent that bypasses them does not eliminate those requirements—it just creates a compliance gap. For a deeper look at why agent accountability matters, see [what a commerce execution API actually does](/what-is-commerce-execution-api) and the [Firestarter vs. Zip comparison](/compare/firestarter-vs-zip) on approval controls.

The practical middle ground is an agent that handles everything except the final authorization. It parses intent, searches suppliers, compares options, calculates total landed cost, and presents a clear summary—then stops and waits.

## The Four-Stage Lifecycle

A well-designed approval workflow follows a consistent pattern:

**1. Propose** — The agent receives a request and translates it into a structured execution. It searches available suppliers, applies budget constraints, and ranks options by a combination of price, shipping time, and supplier score.

**2. Review** — The agent surfaces its top recommendations with enough information for a human to make a real decision. This is the gate. The execution sits in `pending_approval` status until someone acts.

**3. Approve** — A human reviewer confirms (or rejects) via an API call or a UI action backed by that call. Approval can be delegated—a manager approves large orders, a team lead approves small ones—based on amount thresholds configured at the API level.

**4. Execute** — Payment is authorized, a shipping label is generated, and tracking begins. From this point the agent monitors the order and handles exceptions (delays, damage, cancellations) without further human input.

This maps directly to Firestarter's lifecycle. When you POST to `/v1/executions`, the execution advances automatically through parse, search, and compare, then holds at `pending_approval`. From there, a human—or an automated policy engine—calls `/v1/executions/:id/approve`.

## What a Human Needs at the Gate

An approval step is only useful if the reviewer has enough information to make a real decision quickly. The worst approval UIs show a request summary and ask "approve or reject?" without context. Reviewers either rubber-stamp or slow everything down asking clarifying questions.

A useful approval payload includes:

- **The original request** — what the agent was asked to find
- **Top-ranked options** — at minimum the recommended option plus one or two alternatives, with supplier name, unit price, and lead time
- **Total landed cost** — item cost plus shipping plus tax, not just unit price
- **Estimated delivery date** — specific, not "3–5 business days"
- **Budget status** — whether the order fits within the configured spend limit and what headroom remains

Here is what a Firestarter execution looks like when it reaches the approval gate:

```json
{
  "id": "exec_01HXYZ123",
  "status": "pending_approval",
  "request": "noise cancelling headphones under $80",
  "budget": { "max_total": 80 },
  "options": [
    {
      "rank": 1,
      "supplier": "AudioSupplyCo",
      "product": "SoundShield Pro 40",
      "unit_price": 67.99,
      "shipping": 5.99,
      "tax": 3.40,
      "total_landed": 77.38,
      "estimated_delivery": "2026-06-14",
      "in_budget": true
    },
    {
      "rank": 2,
      "supplier": "TechDirect",
      "product": "QuietMate 200",
      "unit_price": 71.50,
      "shipping": 0,
      "tax": 3.58,
      "total_landed": 75.08,
      "estimated_delivery": "2026-06-16",
      "in_budget": true
    }
  ],
  "approve_url": "https://api.firestarter.network/v1/executions/exec_01HXYZ123/approve"
}
```

The reviewer sees real numbers for both options and can approve the recommendation or switch to an alternative in the same call.

## Async Approval: Polling vs. Webhooks

Approval does not have to be synchronous. In most real deployments, the agent kicks off an execution, the request goes into a queue or notification channel, and a human reviews it when they next check their inbox or task list. Two patterns handle this well.

**Status polling** — The agent (or a calling system) periodically calls `GET /v1/executions/:id` and checks the `status` field. Once it transitions from `pending_approval` to `approved` or `rejected`, the agent either continues or surfaces the rejection for follow-up. Polling is simple to implement but wastes requests if the review cycle is long.

**Webhooks** — Firestarter posts a status-change event to a configured endpoint when an execution transitions state. Your system receives the event, routes it to the right handler (continue the agent workflow, notify the requester, log the outcome), and responds. Webhooks are more efficient for high-volume deployments and work well when approval is integrated into a Slack bot, email workflow, or internal dashboard.

See the [full webhook and polling reference in the developer docs](/developers) and the [OpenAPI spec](/openapi) for the complete status transition model.

## Calling the Approve Endpoint

Once a reviewer has seen the options and is ready to proceed, approval is a single POST:

```bash
curl -X POST https://api.firestarter.network/v1/executions/exec_01HXYZ123/approve \
  -H "Authorization: Bearer fs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "selected_option_rank": 1,
    "approved_by": "user@example.com",
    "note": "Approved for Q2 equipment budget"
  }'
```

The `approved_by` field becomes part of the [audit trail](/use-cases/agent-approval-audit-api)—recorded against the execution so there is always a human name attached to the authorization. The `note` field is optional but useful for procurement records.

After approval, the execution advances to `payment_processing`, then `shipping`, then `in_transit`. All transitions are queryable via `GET /v1/executions/:id` and appear in the step-by-step log.

## Configuring Approval Thresholds

Not every purchase needs senior review. A good approval system is tiered: small purchases might auto-approve or require a quick confirmation, while large orders escalate. Firestarter supports per-execution spend limits and approval checkpoints configured when you create an execution:

```json
{
  "request": "office supplies for Q3",
  "budget": {
    "max_total": 500
  },
  "approval": {
    "required": true,
    "notify": ["ops@example.com"]
  }
}
```

For orgs building agent workflows at scale, the [MCP integration](/mcp) lets you expose `firestarter_approve` as a tool that an orchestrating agent can trigger after receiving confirmation from an authorized human in a conversation thread—useful for Slack-native or assistant-native approval flows.

## What Happens on Rejection

Rejection should not be a dead end. When an approval call returns `rejected`, the agent has context about why—too expensive, wrong supplier, needs different specs—and can restart the search with refined parameters. The `/v1/executions/:id/message` endpoint lets a human send a correction mid-lifecycle:

```bash
curl -X POST https://api.firestarter.network/v1/executions/exec_01HXYZ123/message \
  -H "Authorization: Bearer fs_live_YOUR_KEY" \
  -d '{"message": "Prefer a supplier with 2-day delivery even if slightly more expensive"}'
```

The execution re-enters the search and comparison stages with updated preferences, then returns to `pending_approval` with a revised set of options. The full history of both rounds is preserved in the audit log.

For more on the end-to-end flow, see [AI procurement automation](/blog/what-is-agentic-commerce) and the [kraft mailer scenario](/scenarios/kraft-mailer-boxes-austin) for a concrete B2B example.

---

## FAQ

### Can I turn off the approval checkpoint entirely?

Yes. Set `"approval": {"required": false}` in the execution request. Firestarter will advance automatically from `options_ready` to `payment_processing` without waiting for human input. This is appropriate for low-value, high-frequency purchases with tight budget constraints already enforced at the API level—but understand that you are shifting all review responsibility to the pre-purchase configuration.

### How long does an execution stay in `pending_approval` before it expires?

Executions in `pending_approval` do not expire by default. Supplier quotes and inventory availability may change over time, so the execution surfaces a warning if a significant delay has elapsed since options were generated. You can also call `/v1/executions/:id/cancel` at any point to close the execution without proceeding.

### Can different users have different approval authority levels?

Approval authority is enforced at the application layer—your system decides which users can call `/approve` for which executions. Firestarter records the `approved_by` identifier you supply; it does not maintain an internal user-role hierarchy. See the [developer docs](/developers) for patterns on building role-gated approval into your integration.

### Does Firestarter support multi-step approval chains (e.g., manager + finance)?

The current model supports a single approval gate per execution. Multi-step chains—where the execution must be approved by two or more parties in sequence—are implemented by holding the execution in `pending_approval` until your application has collected all required sign-offs, then calling `/approve` once all conditions are satisfied. See [/use-cases/agent-approval-audit-api](/use-cases/agent-approval-audit-api) for integration patterns.

### What does it cost to run approval workflows through Firestarter?

Each execution consumes one token. [Free tier: 100 tokens to start plus a 14-day Pro trial, no credit card required.](/pricing) Pro is $99/month with 10,000 tokens. Buyers pay no transaction fees.
