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.usdMax defaults to 0.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.