Escrow for AI Agents
in 5 Minutes
AI agents can transact autonomously. They schedule calls, submit deliverables, process invoices. But every one of those transactions has a trust gap: who guarantees the other side follows through? This post walks through why escrow is the missing layer — and gets you live on testnet in five minutes.
// 01The Problem
Agent-to-agent payments are real. Protocol bridges like x402 and AP2 let agents send USDC across HTTP headers, on-chain, in milliseconds. That's a solved problem.
What isn't solved: conditional payment. When Agent A pays Agent B for a task, the payment is unconditional. It settles the moment it's sent. If Agent B never delivers — the work isn't done, the deadline passes, the output fails validation — Agent A has no recourse.
In the current state of the ecosystem:
- x402 handles payment authorization over HTTP, but funds transfer immediately on settlement. There's no hold, no release condition, no refund path.
- AP2 handles agent-to-agent transfer flows, but likewise settles unconditionally.
- Most agent frameworks handle payment as a side-effect of task execution — "pay, then work." That order-of-operations creates an obvious attack surface.
What you actually want is: lock funds → define a condition → release only when it's met, refund if it isn't. That's escrow. And for agents operating at scale, it's the only trust model that works without a human in the loop.
// 02What Escrow Solves
Escrow converts a payment into a conditional promise. The mechanics are simple:
- Lock funds on-chain. The payer deposits USDC into a smart contract. The funds are out of their account — but they haven't moved to the payee yet.
- Define a condition. The contract holds the funds until a specific condition is satisfied: a task completion signal, an external oracle, a deadline, an explicit approval.
- Condition met → release. When the condition is verified, the contract releases funds to the payee. Automatic, trustless, no intermediary.
- Condition not met → refund. If the deadline passes without the condition being satisfied, the funds auto-refund to the payer.
For AI agents, this matters enormously. Agents can't call lawyers. They can't dispute a charge with their bank. They need programmable, auditable guarantees baked into the payment layer itself — not layered on top after the fact.
The value isn't just protecting payers. It's that both sides can operate with higher autonomy. The payee agent doesn't need a reputation system or manual review — the smart contract enforces the outcome. The payer agent doesn't need to babysit — the refund path is already wired in.
// 03ClearPact in 5 Minutes
ClearPact wraps Base Sepolia escrow contracts behind a REST API. No wallet management, no ABI calls, no gas configuration. Four API calls and you have a complete escrow lifecycle.
Step 1 — Get an API key
Generate a free testnet key at /docs. No credit card, no wallet required. The key scopes your escrows and tracks settlement state.
// POST /api/keys — generate a testnet API key const res = await fetch('https://clearpact.polsia.app/api/keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ label: 'my-agent' }) }); const { api_key } = await res.json(); // → "cpk_test_abc123..."
Step 2 — Create an escrow
Post a single JSON payload with the amount, condition type, and payee address. The API creates the on-chain escrow and returns a stable escrow_id you'll reference for the rest of the lifecycle.
// POST /api/escrow — lock funds with a condition const escrow = await fetch('https://clearpact.polsia.app/api/escrow', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': api_key }, body: JSON.stringify({ amount_usdc: 10.00, payee_address: '0xRecipientAgentAddress', condition_type: 'api_callback', // release on HTTP callback expires_in_seconds: 3600, // auto-refund after 1h metadata: { task_id: 'task_xyz', description: 'Generate product images' } }) }).then(r => r.json()); console.log(escrow.escrow_id); // "esc_8f3a..." console.log(escrow.status); // "funded" console.log(escrow.tx_hash); // on-chain transaction hash
Step 3 — Poll status
The payee agent (or your orchestrator) polls the escrow until it settles or expires. The response includes the current on-chain state.
// GET /api/escrow/:id — poll until settled or expired const status = await fetch( `https://clearpact.polsia.app/api/escrow/${escrow.escrow_id}`, { headers: { 'x-api-key': api_key } } ).then(r => r.json()); // Possible statuses: "funded" | "released" | "refunded" | "expired" if (status.status === 'released') { console.log('✅ Payee received funds', status.settled_at); } else if (status.status === 'refunded') { console.log('↩️ Funds returned to payer'); }
Step 4 — Settle
When the task is complete, trigger settlement. For api_callback condition type, this is a simple POST with an optional proof payload. The smart contract verifies and releases.
// POST /api/escrow/:id/settle — trigger release to payee const result = await fetch( `https://clearpact.polsia.app/api/escrow/${escrow.escrow_id}/settle`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': api_key }, body: JSON.stringify({ proof: { task_id: 'task_xyz', completed_at: new Date().toISOString(), output_hash: 'sha256:...' // optional — binds proof to output } }) } ).then(r => r.json()); console.log(result.status); // "released" console.log(result.tx_hash); // settlement transaction on Base Sepolia
// 04Under the Hood
A few things worth knowing before you build on top of this.
Base Sepolia smart contract. Every escrow is a real on-chain transaction. Testnet funds are free — use the Base Sepolia faucet on Alchemy to get test USDC. Mainnet is available for production workloads at the same API endpoints.
ERC-8004 auto-settlement. ClearPact implements ERC-8004, the emerging standard for autonomous agent payment settlement. For supported condition types, settlement is fully automatic — no explicit settle call required. The adapter polls validation state and triggers the contract when conditions are met.
Six condition types. The API supports six condition categories, from simple time-based locks to oracle-verified outcomes:
| Condition type | Releases when |
|---|---|
| api_callback | Your server POSTs a completion signal with optional proof payload |
| deadline | A specific timestamp is reached — funds release automatically |
| manual_approval | Explicit approval from a designated address or API call |
| erc8004_validation | On-chain validation record is written matching the escrow's task hash |
| oracle | External data oracle resolves the condition (price, delivery, outcome) |
| multi_sig | M-of-N approvals from a defined set of addresses |
// 05Try It Now
The testnet playground in the docs lets you create and settle escrows directly in the browser — no API key required for the first test. Full TypeScript SDK available if you'd rather wire it into your agent directly.
Try it on testnet — free, no wallet needed
Create your first escrow in the interactive playground. Mainnet-ready when you are.
Open the Playground → Or get an API key and integrate directly.