Docs · SDKs
Budget policy SDK
Local, synchronous budget control for agent payments. Declare the caps once; evaluate every intent before it spends.
About this page
How to use this page
- Copy the TypeScript sample to add local budget control to your agent.
- Or POST to /v1/budget/check over raw HTTP for the cumulative (collector-backed) check.
- Read the Principles section — local-first, synchronous, cumulative-via-collector.
What you'll find here
- A TS/JS sample, a raw-HTTP sample, and the SDK principles.
TypeScript / JavaScript
npm install @harpd/agent-budget-policy@^0.1.0
import { defineBudget, evaluate, validatePolicyRules }
from '@harpd/agent-budget-policy'
// 1. Declare the policy (per-call / per-agent / per-endpoint / per-tool).
const policy = defineBudget({
perCall: { usdMax: 0.05 }, // catches the wrong-decimals bug
perAgent: { 'weather-agent': { usd: 1, window: '1d' } },
perEndpoint: { '*': { usd: 1, window: '1d' } }, // '*' = default for any endpoint
allowedTokens: ['eip155:8453/erc20:0xUSDC'],
})
// 2. Validate at app boot — fail fast on a bad policy, not mid-payment.
const v = validatePolicyRules({
perCall: { usdMax: 0.05 },
perEndpoint: { '*': { usd: 1 } },
})
if (!v.ok) throw new Error('bad policy: ' + v.error)
// 3. Evaluate synchronously — never blocks on the network.
const ok = evaluate(policy, {
agentId: 'weather-agent',
endpoint: 'https://paid-weather.example.com/v1',
amountUsd: 0.01,
})
if (!ok.allowed) {
// reason: 'perCall' | 'token_not_allowed' | 'invalid_intent' | 'no_policy_loaded'
// windowed denials set ok.retryAfter (ISO); perCall denials don't.
console.log('deny:', ok.reason)
} else {
// ok.scopes = the resolved cap rows for this intent
await payAndFetch(intent)
}
Raw HTTP (collector-backed)
The local SDK enforces the per-call cap instantly. For cumulative checks (have we already spent the daily endpoint cap?), the collector holds the ledger and answers /v1/budget/check. Wire budgetControl: true into harpdPlugin from @harpd/observe to route there.
curl -X POST https://api.harpd.com/v1/budget/check \
-H "X-Harpd-Key: $HARPD_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "weather-agent",
"endpoint": "https://paid-weather.example.com/v1",
"amount": 10000,
"token": "eip155:8453/erc20:0xUSDC",
"chain": "eip155:8453"
}'
Principles
- Local-first. The per-call cap is enforced synchronously, with no network round-trip — a denial never blocks on the collector.
- Synchronous.
evaluate()is pure and returns immediately; an agent loop never awaits the budget check. - Cumulative via collector. Windowed caps (per-agent / per-endpoint / per-tool) need history; that lives in
@harpd/observe's queue + the Harpd collector. - Sane defaults.
perCall.usdMaxdefaults to0.05— set against the most common agent-payment bug we've seen.
When to add Harpd
The open-source SDK gives you local decisions and the append-only event schema. The hosted Harpd product adds the dashboard, multi-team policy editor, cross-tenant marketplace scores, email alerts, and the CFO-ready compliance export. Both share the same event shape — upgrading never rewrites your agent code.