Designed for agents

Built for the code that asks before it acts.

Most approval tools were designed for humans filling in forms. FinalApproval was designed for agents — long-running processes that need to pause, wait for a decision, and resume with the right branch running.

The problem

An agent is trusted up to the point it isn't.

The agents you build are powerful up to a line — the line where a mistake costs real money, breaks a customer relationship, or can't be undone. Send the email to every subscriber. Issue the refund. Push to production. Delete the row.

The conventional answer is a confirmation prompt in the terminal, or worse, a Slack message and prayer. Neither is a real gate — terminals time out, Slack messages get lost, and both rely on whoever happens to be watching.

FinalApproval is the gate — a queue a human reviews, a decision that fires back, and a branch of your own code that runs on the right answer.

What makes it agent-native

Three things generic approval tools miss.

01

Skill-first setup

The agent itself runs the install. You describe what needs approval in plain English; the skill provisions the review UI, the signed webhook, and the continuation handler directly in your codebase.

The alternative

Most tools ask you to click through a form wizard and paste configuration into your code yourself.

02

Continuation-native

The decision doesn't come back as an email or a row in a database — it comes back as a function call in your agent's own runtime. Approve → executeBranch(). Deny → cancelBranch(). No polling, no state reconstruction.

The alternative

Most tools hand you a row in a database and expect you to figure out how to resume the agent that was waiting on it.

03

Built for many calls, not many configs

Your agent might ask for 500 refund approvals this week. Each one is a single API call with a unique HTML body; the channel, webhook, and API key are configured once and never touched.

The alternative

Most tools scale badly past one-off workflows — every new approval type is a new board, a new form, a new config.

Integration patterns

Three ways your agent waits.

Agents live with different runtime assumptions. FinalApproval supports all three waiting patterns with the same API surface — pick the one that fits your orchestrator.

Block

Stay in the function until the decision arrives.

Simplest pattern. Your code calls POST /api/v1/approvals and awaits a short-poll helper that returns when resolution lands. Fine for agents with long-lived runtimes and short approval SLAs.

const decision = await fa.awaitDecision({
  title: 'Refund $1,248 to Acme, Inc.',
  body: '<p>Invoice #INV-9831…</p>',
  data: { invoice_id: 'INV-9831' },
  timeoutMs: 120_000,
});
if (decision.status === 'approved') await issueRefund();
Park

Yield. The webhook resumes the workflow.

Right pattern for agents that check-point to disk or to a durable queue. Submit the approval, save the agent's state keyed by the returned request id, and let the webhook handler rehydrate and resume.

const { id } = await fa.submit({ title, body, data });
await queue.parkState({ runId, waitingOn: id });
// — later, in /hooks/refunds —
const run = await queue.resume({ waitingOn: decision.id });
run.continue({ decision: decision.status });
Stream

Keep producing — resolve this branch asynchronously.

For agents that fan out work. Submit the approval, keep doing other things, and let the webhook fire a single branch resolver that doesn't block the parent trace.

agent.branch('refund', async () => {
  const { id } = await fa.submit({ title, body, data });
  return fa.resolveOn(id); // resolves when webhook arrives
});
// agent continues other branches in parallel

Runtime-agnostic

Works with every agent framework.

FinalApproval is a plain HTTP API. If your agent can make a network request, it can ask for approval. The skills library adds idiomatic bindings for the frameworks you're most likely to reach for.

Claude Agent SDK

Skill

Tool call that waits for a human

LangChain / LangGraph

Skill

Checkpoint node with decision routing

CrewAI

Skill

HumanGate tool + resolver callback

Vercel AI SDK

Skill

generateText tool definition

OpenAI Agents SDK

Skill

FunctionTool with parked state

Anything else

HTTP

Plain HTTP. Any language. Any runtime.

Let your agent ask before it acts.

Install the skill, describe what you want approved, and ship.