Quickstart

From zero to first signed receipt in 60 seconds.

Install the SDK, wrap your provider client, set a daily cap. The next time your agent tries to spend over your cap, AgentGuard throws before the provider is called. The provider never sees the request. You never get the bill.

Step 1

Install

Pick your runtime. The SDK has zero hard dependencies on any specific provider — you bring your own OpenAI / Anthropic / Bedrock client.

npm install @agentguard-run/spend
pip install agentguard-spend
Step 2

Wrap your provider client

One call. Pass in your existing client, declare a cap, get back a guarded client you use the same way.

// Anthropic, OpenAI, Bedrock — same pattern.
import Anthropic from '@anthropic-ai/sdk';
import { withSpendGuard } from '@agentguard-run/spend';

const guarded = withSpendGuard(new Anthropic(), {
  policy: {
    caps: [
      { amountCents: 2000, window: 'per_day', action: 'block' }
    ]
  },
  scope: { tenantId: 'acme', agentId: 'my-agent' }
});

await guarded.messages.create({
  model: 'claude-opus-4-7',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'hello' }]
});
# One line. Drop-in.
from agentguard_spend import easy_install
from anthropic import Anthropic

client = easy_install(Anthropic(), daily_cap_dollars=20)

client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "hello"}]
)
What just happened

Every call now flows through the spend guard. Cost is projected from your prompt + max_tokens. If your day's spend would cross $20, the call is blocked and an AgentGuardBlockedError is thrown — before the provider is ever called. Your API key never sees the request.

Step 3

Watch it block

Drop the cap to a few cents and trigger a real call. You'll see the block fire instantly.

try {
  await guarded.messages.create({ /* ... */ });
} catch (err) {
  if (err.name === 'AgentGuardBlockedError') {
    console.log(err.toString());  // human-readable trace
    console.log(err.decision); // the signed decision
  }
}
from agentguard_spend import AgentGuardBlockedError

try:
    client.messages.create(...)
except AgentGuardBlockedError as err:
    print(err)                    # color-coded trace
    print(err.decision.action)    # "block"
    print(err.decision.cap_hit)   # which cap fired
Step 4

Verify a receipt

Every decision is Ed25519-signed and hash-chained. Anyone with your public key can verify the chain — useful for audit, dispute, and M&A diligence.

$ agentguard verify --trace latest

action       block
agent        my-agent
amount       $1,122.41 / cap $500.00
timestamp    2026-05-24T19:42:31.004Z

signature    ed25519:a3f2b1c9d4e5...
chain        sha256:9e4d8fa2b3c1...

✓ Signature valid
✓ Spend cap not exceeded
✓ DAG chain integrity verified
✓ Receipt tamper-evident
from agentguard_spend import verify_entry, load_public_key

pub = load_public_key("~/.agentguard/acme/public.key")
entry = json.load(open("receipt.json"))

ok = await verify_entry(entry, pub)
print("valid" if ok else "tampered")

Next steps

Local in-memory storage is fine for a single process. Production wants Redis or Postgres so caps survive restarts and span workers. Real keys want KMS or Vault so the signing key never sits on disk.

Capabilities matrix → All integrations → Redis adapter → KMS & Vault →