Pay Anthropic Credits from an AI Agent
Scenario: Your LangChain agent monitors its Anthropic API credit balance. When it drops below $10, the agent autonomously tops up by $50 — using a PQSafe spend envelope to authorize the payment through Airwallex ACH, no human intervention required.
Prerequisites
@pqsafe/agent-payinstalled and configured- An Anthropic account with billing API access
- Airwallex account with ACH enabled (
AIRWALLEX_CLIENT_ID,AIRWALLEX_API_KEYin.env) - A PQSafe issuer key (
PQSAFE_ISSUER_KEYin.env) - LangChain:
npm install langchain @langchain/anthropic
Install
npm install @pqsafe/agent-pay langchain @langchain/anthropic-
Create a spend envelope scoped to Anthropic
The envelope hard-caps spending at $200/day and restricts the recipient to Anthropic’s payment address.
import {generateKeyPair,createSpendEnvelope,createSignedEnvelope,} from '@pqsafe/agent-pay'const { publicKey, secretKey } = await generateKeyPair()const envelope = createSpendEnvelope({agentId: 'anthropic-credit-topup-agent',maxAmount: 200, // Hard cap: $200 max per envelopecurrency: 'USD',allowedRails: ['airwallex'],allowedRecipients: ['anthropic.com'],validUntil: new Date(Date.now() + 86_400_000), // 24h validityrequireApproval: false, // Fully autonomous below $200memo: 'Anthropic API credits — autonomous top-up',})const signedEnvelope = createSignedEnvelope(envelope, secretKey) -
Build the LangChain tool
The tool checks the Anthropic balance and executes a top-up if credits are low.
import { DynamicTool } from 'langchain/tools'import { executeAgentPayment, buildLedgerRecord, submitToLedger } from '@pqsafe/agent-pay'const TOP_UP_THRESHOLD = 10 // Top up when balance drops below $10const TOP_UP_AMOUNT = 50 // Add $50 each timeasync function getAnthropicBalance(): Promise<number> {const res = await fetch('https://api.anthropic.com/v1/account/usage', {headers: { 'x-api-key': process.env.ANTHROPIC_API_KEY! },})const data = await res.json()return data.credits_remaining_usd ?? 0}const anthropicTopUpTool = new DynamicTool({name: 'top_up_anthropic_credits',description: `Checks Anthropic API credit balance and tops up by $${TOP_UP_AMOUNT} if below $${TOP_UP_THRESHOLD}. Returns payment status.`,func: async (_input: string) => {const balance = await getAnthropicBalance()if (balance >= TOP_UP_THRESHOLD) {return `Balance is $${balance.toFixed(2)} — no top-up needed.`}// Execute payment via PQSafeconst result = await executeAgentPayment(signedEnvelope, {recipient: 'anthropic.com/billing',amount: TOP_UP_AMOUNT,memo: `Credit top-up — balance was $${balance.toFixed(2)}`,})// Log to immutable ledgerawait submitToLedger(buildLedgerRecord(signedEnvelope, result))return `Top-up complete. Status: ${result.status}. TX: ${result.txId}. New balance expected: ~$${(balance + TOP_UP_AMOUNT).toFixed(2)}.`},}) -
Wire the spending alert webhook
Get notified when the envelope is 80% consumed (before it runs out).
import express from 'express'import { setAgentPayConfig } from '@pqsafe/agent-pay'setAgentPayConfig({webhooks: {envelopeConsumed: {threshold: 0.8, // Fire at 80% of maxAmounturl: 'https://your-server.com/webhooks/pqsafe',},},})// Webhook handlerconst app = express()app.use(express.json())app.post('/webhooks/pqsafe', (req, res) => {const { event, envelopeId, consumed, maxAmount } = req.bodyif (event === 'envelope.threshold_reached') {console.warn(`⚠️ Envelope ${envelopeId} is ${(consumed / maxAmount * 100).toFixed(0)}% consumed.`)// Trigger issuance of a new envelope here}res.sendStatus(200)}) -
Build the LangChain agent
import { ChatAnthropic } from '@langchain/anthropic'import { AgentExecutor, createOpenAIFunctionsAgent } from 'langchain/agents'import { ChatPromptTemplate } from '@langchain/core/prompts'const llm = new ChatAnthropic({model: 'claude-opus-4-5',apiKey: process.env.ANTHROPIC_API_KEY,})const prompt = ChatPromptTemplate.fromMessages([['system', 'You are an autonomous ops agent. Monitor API credit balances and top them up as needed.'],['human', '{input}'],['placeholder', '{agent_scratchpad}'],])const agent = await createOpenAIFunctionsAgent({llm,tools: [anthropicTopUpTool],prompt,})const executor = new AgentExecutor({ agent, tools: [anthropicTopUpTool] }) -
Run the agent
const result = await executor.invoke({input: 'Check Anthropic credit balance and top up if needed.',})console.log(result.output)
Complete runnable example
import { generateKeyPair, createSpendEnvelope, createSignedEnvelope, executeAgentPayment, buildLedgerRecord, submitToLedger,} from '@pqsafe/agent-pay'import { DynamicTool } from 'langchain/tools'import { ChatAnthropic } from '@langchain/anthropic'import { AgentExecutor, createOpenAIFunctionsAgent } from 'langchain/agents'import { ChatPromptTemplate } from '@langchain/core/prompts'
const { secretKey } = await generateKeyPair()
const signedEnvelope = createSignedEnvelope( createSpendEnvelope({ agentId: 'anthropic-topup', maxAmount: 200, currency: 'USD', allowedRails: ['airwallex'], allowedRecipients: ['anthropic.com'], validUntil: new Date(Date.now() + 86_400_000), }), secretKey)
const topUpTool = new DynamicTool({ name: 'top_up_anthropic_credits', description: 'Check Anthropic balance; top up $50 if below $10.', func: async () => { const result = await executeAgentPayment(signedEnvelope, { recipient: 'anthropic.com/billing', amount: 50, memo: 'Autonomous credit top-up', }) await submitToLedger(buildLedgerRecord(signedEnvelope, result)) return `Payment ${result.status}. TX: ${result.txId}` },})
const agent = await createOpenAIFunctionsAgent({ llm: new ChatAnthropic({ model: 'claude-opus-4-5' }), tools: [topUpTool], prompt: ChatPromptTemplate.fromMessages([ ['system', 'You are an ops agent. Top up Anthropic credits when needed.'], ['human', '{input}'], ['placeholder', '{agent_scratchpad}'], ]),})
const result = await new AgentExecutor({ agent, tools: [topUpTool] }).invoke({ input: 'Check and top up Anthropic credits if needed.',})console.log(result.output)Expected output
> Entering new AgentExecutor chain...> Invoking tool: top_up_anthropic_creditsPayment settled. TX: txn_airwallex_abc123Balance after top-up: ~$57.34> Finished chain.Top-up complete. Added $50 to Anthropic account. New expected balance: ~$57.34.Troubleshooting
| Problem | Solution |
|---|---|
ENVELOPE_EXPIRED | Envelope’s validUntil passed — create a new one |
RECIPIENT_NOT_ALLOWED | Check allowedRecipients includes 'anthropic.com' |
RAIL_TIMEOUT | Airwallex API is slow — retry with exponential backoff |
INSUFFICIENT_BALANCE | Airwallex account needs funds — top up via Airwallex dashboard |
| Balance API returns 401 | Check ANTHROPIC_API_KEY is set and valid |
Next steps
- Add a Telegram Approval Gate — require human approval for top-ups above $100
- Pay Cloudflare Invoice — same pattern for DevOps bills
- Ledger concept — understand how payments are logged