Documentation
AgentPact is a spending guardrail for AI agents. The owner of an agent writes a Pact; the agent asks AgentPact before every financial action; AgentPact answers allow, deny, or approval required, commits the budget, and records the decision. The policy is enforced server-side; the MCP server and SDK are clients.
Quickstart (no signup)
Create a throwaway sandbox agent with a Research Pact and a one-hour session key:
curl -X POST https://api.agentpact.dev/api/v1/demo/sessionAsk whether the agent may pay 0.5 USDG to a research API:
curl -X POST https://api.agentpact.dev/api/v1/authorize \
-H "Authorization: Bearer pact_sk_..." \
-H "content-type: application/json" \
-d '{"action":"payment","amount":"0.5","asset":"USDG","destination":"0xResearchApi"}'{
"decisionId": "pact_dec_4a8qn2tqye",
"decision": "approval_required",
"reasons": ["new_destination"],
"checks": {
"agent_active": "pass", "action_allowed": "pass", "asset_allowed": "pass",
"destination_not_blocked": "pass", "destination_known": "ask",
"transaction_cap": "pass", "daily_budget": "skip", "session_budget": "pass", "velocity": "skip"
},
"remainingDailyBudget": "25",
"pactId": "pact_p4hiratbzfn8", "pactVersion": 1,
"approvalId": "apr_cn657y8mn4", "approvalExpiresAt": "2026-09-12T07:00:41.946Z"
}The Research Pact asks the owner the first time an agent pays a new destination. Try a swap (denied by the Pact), an amount above 1 USDG (asks), or a run of small payments (allowed until the 25 USDG day is spent). Then read GET /budget and GET /activity with the same key. Or use the live demo on the home page.
How a decision is made
Rules run in a fixed order. AI never participates; the limits are deterministic.
- Agent frozen → deny
- Action type set to deny → deny
- Asset not in
allowed_assets→ deny - Destination in
blocked_destinations→ deny - Destination unknown and
unknown_contractsis deny → deny - Action type set to ask → approval required
- Amount above
transaction_limit(or at/aboveapproval_threshold) → approval required - Destination unknown and
unknown_contractsis ask → approval required - Daily budget, session budget, or hourly velocity would be exceeded → deny
- Otherwise → allow, and the amount is committed against the budget
A destination is unknown when it is not in allowed_destinations and this agent has never been allowed to pay it before. This is computed by the server; an agent cannot claim a destination is known.
The budget step is one atomic database write: the allow row is only inserted if, at that instant, committed spend plus this amount still fits. Concurrent requests cannot overspend. The daily window is rolling 24 hours. An approved approval counts against the budget from the moment the owner approves it, and approving never lets the daily limit be exceeded; if the day is already spent, the approval is recorded as denied.
MCP
Hosted server: https://mcp.agentpact.dev/mcp (Streamable HTTP; /sse for legacy clients). The agent's session key travels with the connection, never as a tool argument, so it stays out of the model's context.
Claude Code / Claude Desktop / Codex (any client that supports headers):
{
"mcpServers": {
"agentpact": {
"type": "http",
"url": "https://mcp.agentpact.dev/mcp",
"headers": { "Authorization": "Bearer pact_sk_..." }
}
}
}Clients without header support can put the key in the URL:
https://mcp.agentpact.dev/mcp?key=pact_sk_...Tools:
| Tool | What it does |
|---|---|
| pact_status | Agent status, active Pact summary, today's budget |
| pact_budget | Daily limit, spent, remaining, per-transaction cap |
| pact_authorize | action, amount, asset, destination, memo → allow | deny | approval_required with checks |
| pact_approval_status | approvalId → pending | approved | denied | expired |
| pact_activity | Recent decisions, newest first |
| pact_pay | Authorize AND execute a payment from the agent's managed wallet; returns txHash on allow |
| pact_wallet | Managed wallet address and balances, for funding checks |
| pact_swap | Authorize a swap. Swap execution not deployed yet; authorizes only |
Suggested system prompt line for the agent: “Before any payment, swap, transfer, or contract call, call pact_authorize. Only proceed on allow. On approval_required, poll pact_approval_status. On deny, do not retry the same request.”
TypeScript SDK
npm install @agentpact-dev/sdkimport { AgentPact } from "@agentpact-dev/sdk";
// Sandbox, no signup:
const { client } = await AgentPact.sandbox();
// Real agent, key issued by the owner:
const pact = new AgentPact({ sessionKey: process.env.AGENT_SESSION_KEY! });
const result = await pact.authorize({
action: "payment", amount: "2", asset: "USDG", destination: "0x…", memo: "NVDA filings",
});
if (result.decision === "allow") {
// proceed
} else if (result.decision === "approval_required") {
const approval = await pact.waitForApproval(result.approvalId!);
if (approval.status === "approved") { /* proceed */ }
} else {
// denied: result.reasons
}
await pact.budget();
await pact.activity({ limit: 20 });Owners: agents, Pacts, session keys
Owners sign in with their wallet (no email, no password): the API returns a nonce message, the wallet signs it, and the API returns a token. The dashboard does this with any injected wallet. From the REST API:
# 1. nonce + message to sign
curl "https://api.agentpact.dev/api/v1/auth/nonce?address=0xYourWallet"
# 2. sign message with the wallet, then
curl -X POST https://api.agentpact.dev/api/v1/auth/verify \
-H "content-type: application/json" \
-d '{"message":"<message>","signature":"0x..."}'
# → { "token": "...", "owner": { ... } }Create an agent from a template (research, trading, worker) or a full Pact config, then issue a session key:
curl -X POST https://api.agentpact.dev/api/v1/agents \
-H "Authorization: Bearer <owner token>" -H "content-type: application/json" \
-d '{"name":"Research Agent","template":"research"}'
curl -X POST https://api.agentpact.dev/api/v1/agents/agt_.../session \
-H "Authorization: Bearer <owner token>" -H "content-type: application/json" \
-d '{"label":"laptop","expiresInHours":168}'
# → { "sessionKey": "pact_sk_..." } shown once, only a hash is storedGive the key to the agent. It identifies the agent on every call. An agent cannot read or change its Pact beyond what the owner set, cannot approve itself, and cannot extend its own key. Freezing an agent revokes every key at once.
Pact reference
| Field | Meaning |
|---|---|
| name | Display name |
| transaction_limit | Autonomous per-transaction cap (decimal string). Above it → approval required |
| daily_limit | Hard ceiling on spend per rolling 24h. Exceeding it → deny, never ask |
| session_limit | Optional hard ceiling on lifetime spend of one session key |
| approval_threshold | Optional: ask at/above this amount even when under transaction_limit |
| max_actions_per_hour | Optional velocity guard on allowed actions |
| allowed_assets | Asset symbols the agent may use (case-insensitive) |
| allowed_destinations | Trusted addresses / identifiers. Never treated as unknown |
| blocked_destinations | Always denied |
| actions | payment, swap, transfer, contract_call → allow | ask | deny |
| unknown_contracts | What to do with a destination that is neither trusted nor previously allowed: allow | ask | deny |
| approval_ttl_minutes | How long an approval stays open (default 60) |
All amounts are decimal strings with up to 6 decimals. Floats are rejected.
{
"name": "Research Agent Pact",
"transaction_limit": "1",
"daily_limit": "25",
"allowed_assets": ["USDG"],
"allowed_destinations": ["0xResearchApi"],
"actions": { "payment": "allow", "swap": "deny", "transfer": "deny", "contract_call": "ask" },
"unknown_contracts": "ask",
"max_actions_per_hour": 120
}REST reference
Base URL https://api.agentpact.dev/api/v1. Auth: Authorization: Bearer with an owner token (O) or an agent session key (A).
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /demo/session | none | Throwaway sandbox agent + one-hour key |
| GET | /auth/nonce?address= | none | Sign-in nonce and message |
| POST | /auth/verify | none | Signed message → owner token |
| GET | /me | O | Current owner |
| GET | /templates | none | Pact templates |
| POST | /agents | O | Create agent (+ Pact v1) |
| GET | /agents | O | List agents with budgets |
| GET | /agents/:id | O A | Agent, active Pact, budget |
| POST | /agents/:id/freeze | O | Freeze + revoke all keys |
| POST | /agents/:id/unfreeze | O | Unfreeze (keys stay revoked) |
| GET | /agents/:id/pacts | O A | Pact version history |
| POST | /agents/:id/pacts | O | New Pact version (full config) |
| GET | /pacts/:id | O A | One Pact version |
| PATCH | /pacts/:id | O | Partial edit → new version |
| POST | /agents/:id/session | O | Issue session key (shown once) |
| GET | /agents/:id/sessions | O | List keys |
| POST | /agents/:id/sessions/:keyId/revoke | O | Revoke one key |
| POST | /authorize | A | The decision (no execution) |
| POST | /pay | A | Decision + on-chain execution from the managed wallet |
| GET | /wallet | A | Own managed wallet address and balances |
| POST | /agents/:id/wallet | O | Create the agent's managed wallet |
| GET | /agents/:id/wallet | O A | Wallet address and balances |
| GET | /budget | A | Own budget |
| GET | /budget/:agentId | O A | Budget |
| GET | /activity | O A | Decisions (?agent= ?decision= ?limit= ?before=) |
| GET | /activity/:id | O A | One decision |
| GET | /approvals | O A | Approvals (?status=pending) |
| GET | /approvals/:id | O A | One approval |
| POST | /approvals/:id/approve | O | Approve once (budget-checked) |
| POST | /approvals/:id/deny | O | Deny |
What is live
| Capability | Status |
|---|---|
| Policy engine: actions, assets, destinations, per-tx cap, daily / session / velocity limits | Live |
| Atomic budget commit, rolling 24h window | Live |
| Owner wallet sign-in, agents, versioned Pacts, session keys, freeze | Live |
| Approvals: approve once, deny, expiry, budget-checked approval | Live |
| Audit trail with rule checks per decision | Live |
| Hosted MCP server, TypeScript SDK, REST API | Live |
| Dashboard (agents, Pact editor, approvals, activity, keys) | Live, injected wallet sign-in |
| Webhooks, live WebSocket feed | Planned |
| Managed agent wallets (Privy): /pay executes on Robinhood Chain, denies cannot be signed | Live |
| Swap execution; Pact Account contract (non-custodial enforcement) | Planned |
| Transaction simulation, intent-aware risk | Planned |