THE HUMAN-IN-THE-LOOP API FOR AI AGENTS

Agents act.
Humans approve.

One API call pauses any agent before it refunds money, sends the email, or touches production. A human clicks approve, reject, or edit — and a signed webhook resumes the run.

free tier · 100 approvals/mo · no card required

the rogue refund — caught
$ node support-agent.js
agent intent: refund customer #4821
agent amount: $10,000.00 (expected ~$10)
confirm POST /v1/requests → req_8fk2 · PENDING
confirm agent paused · approval sent to finance@acme.com
 
human Sarah Chen edited payload: amount 10000 → 10.00
human APPROVED · webhook signed + delivered in 87ms
agent resumed → refunded $10.00 · audit log written ✓

A pause button, as an API.

REQUEST

The agent yields

Before the sensitive action, your code calls POST /v1/requests with a summary and the exact payload. The agent stops there.

DECIDE

A human rules on it

The approver gets a magic link — no account, no app. They see the payload, then approve it, reject it, or edit it first. Every decision records who, when, and from where.

RESUME

The webhook lands

We POST the verdict to your endpoint, HMAC-signed. Execute effectivePayload — the human-corrected version wins over the original.

Enterprises don't fear agents.
They fear unsupervised ones.

The same four-line integration covers every team's nightmare scenario. Pick one:

BRAND SAFETY

The hallucinated detail, fixed before it ships

A sales agent drafts 50 personalized emails from scraped data. One invents a funding round that never happened. The SDR edits the payload in the approval view — the corrected version is what your webhook receives.

  • Approver sees the exact JSON the agent wants to send
  • Edit Payload rewrites it inline; the edit is versioned next to the original
  • Your code executes effectivePayload — human corrections always win
the hallucinated email — corrected
$ node sdr-agent.js --batch=q3-outbound
agent drafted 50 personalized emails from CRM + web research
agent → cfo@northwind.com: “congrats on the Series C…”
confirm POST /v1/requests → req_2hd8 · PENDING
confirm batch paused · approval sent to sdr-lead@acme.com
 
human flagged: Northwind never raised a Series C
human edited payload · body rewritten · APPROVED
agent sent 50/50 · 0 hallucinations shipped ✓

INTEGRATION

One POST request.
Any stack.

No SDK required — it's plain HTTPS with a bearer key. Works from LangChain tools, Vercel AI SDK, CrewAI, cron jobs, or a bash script. Resume on the signed webhook, or poll if you'd rather keep it simple.

Full API reference →
// 1. Pause the agent before the sensitive action
const res = await fetch("https://confirm.dev/api/v1/requests", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONFIRM_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    summary: "Refund $10,000 to customer #4821",
    payload: { action: "refund", amount: 10000 },
    notify: "finance@company.com",
    agentName: "SupportBot",
  }),
});

const { id, status } = await res.json(); // status: "PENDING"
// 2. The agent yields here. Resume on the webhook, or poll:
//    GET /api/v1/requests/{id}  until status !== "PENDING"

SECURITY

Built like the infrastructure it protects.

HASHED CREDENTIALS

API keys and magic-link tokens are stored as SHA-256 hashes. A database leak can't mint requests or approve them.

SIGNED WEBHOOKS

Every delivery carries an HMAC-SHA256 signature over a timestamped payload — verifiable, replay-resistant, per-endpoint secrets.

256-BIT MAGIC LINKS

Approval tokens are 256 bits of entropy, single-purpose, and expire on your TTL. Possession is the credential; nothing to phish a password from.

APPEND-ONLY AUDIT

Requests, decisions, and every webhook delivery attempt are immutable rows. SOC2 evidence is a query, not an archaeology project.

IDENTITY ON EVERY DECISION

Approvals record the approver, timestamp, IP address, user agent, and their note — the full who / what / when / from where.

FAIL SAFE, NOT OPEN

Unanswered requests expire to a terminal EXPIRED state and notify your system. Silence never becomes consent.

The full model is documented, not marketed: read the security page.

Pricing

Per approval, not per seat. Approvers are always free.

HOBBY

$0forever

  • 100 approvals / month
  • Email notifications
  • 1 webhook endpoint
  • 7-day audit log

PRO

$29per month

  • 1,000 approvals / month
  • $0.05 per extra approval
  • Email + SMS notifications
  • Unlimited webhook endpoints
  • 90-day audit log

ENTERPRISE

Customannual

  • Slack & Teams approvals
  • SSO / SAML
  • Custom domains
  • Indefinite audit retention

Exact limits per plan are in the docs.

Questions, answered.

What happens if nobody approves in time?+

Every request has a TTL (default 24 hours, up to 7 days). When it elapses, the request moves to a terminal EXPIRED state and a request.expired webhook fires — so your agent fails safe instead of hanging forever or acting anyway.

Do approvers need a Confirm account?+

No. Approvers get a single-purpose magic link by email. The 256-bit token in the link is the credential — nothing to sign up for, install, or remember. Only developers who build with the API have accounts.

Can the approver change what the agent does?+

Yes — that's the point of Edit Payload. The approver fixes the JSON in the review screen and approves; the webhook's effectivePayload carries their version. The original stays stored alongside it for the audit trail.

How do I know a webhook really came from you?+

Every delivery is signed: HMAC-SHA256 over timestamp.body with your endpoint's secret, sent in X-Confirm-Signature. Verification is ~6 lines of code, shown in the integration samples above and in the docs.

Does it work with LangChain / Vercel AI SDK / CrewAI?+

Yes — Confirm is framework-agnostic by design. Anywhere you can make an HTTPS request, you can gate an action: wrap it in a LangChain tool, a Vercel AI SDK tool call, a CrewAI task, or a plain function.

What exactly is in the audit log?+

Every request (summary, original payload, metadata), every decision (approver identity, timestamp, IP, user agent, note, and any payload edits), and every webhook delivery attempt with its HTTP status. Rows are append-only.

Ship the agent. Keep the veto.

Your first hundred approvals are free. Integration is one POST request.