Quickstart: Headless Agent
15 minutes
Enable autonomous agents to handle pay-as-you-go APIs
Overview
Autonomous Payments
Headless agents can automatically handle HTTP 402 payment challenges, allowing them to access paid APIs while respecting budget constraints.
Step 1: Create Agent Class
class PayAsYouGoAgent {
private budget: number;
private spent: number = 0;
constructor(initialBudget: number) {
this.budget = initialBudget;
}
async call(endpoint: string, data: any, maxPrice: number = 1.0) {
const idempotencyKey = crypto.randomUUID();
let response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey,
},
body: JSON.stringify(data),
});
if (response.status === 402) {
const price = parseFloat(response.headers.get('X-402-Price')!);
const nonce = response.headers.get('X-402-Nonce');
// Check constraints
if (price > maxPrice) {
throw new Error(`Price ${price} exceeds max ${maxPrice}`);
}
if (this.spent + price > this.budget) {
throw new Error('Insufficient budget');
}
// Approve payment
await this.approvePayment(nonce!, price);
// Retry with nonce
response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey,
'X-402-Nonce': nonce!,
},
body: JSON.stringify(data),
});
this.spent += price;
}
return response.json();
}
private async approvePayment(nonce: string, amount: number) {
// In production: submit Solana transaction
// In test mode: call simulate endpoint
await fetch('/api/simulate/pay', {
method: 'POST',
body: JSON.stringify({ nonce, amount }),
});
}
}Step 2: Use in Your Agent
const agent = new PayAsYouGoAgent(10.0); // $10 budget
// Execute commands with automatic payment handling
const result1 = await agent.call(
'/api/v1/bots/mybot/commands/analyze',
{ args: { q: 'BTC' }, user_id: 'agent:001' },
0.10 // max $0.10 per call
);
const result2 = await agent.call(
'/api/v1/bots/mybot/commands/chart',
{ args: { symbol: 'ETH' }, user_id: 'agent:001' },
0.10
);
console.log(`Spent: $${agent.getSpent()}`);
console.log(`Remaining: $${agent.getRemainingBudget()}`);Step 3: Add Budget Management
Budget Controls
Always implement budget limits to prevent unexpected costs in autonomous agents.
// Set budget limits
agent.setBudget(20.0);
agent.setMaxPricePerCall(0.50);
// Track spending
agent.on('payment', (amount, command) => {
console.log(`Paid ${amount} for ${command}`);
if (agent.getRemainingBudget() < 1.0) {
console.warn('Low budget warning');
}
});
// Handle budget exhaustion
try {
await agent.call(endpoint, data);
} catch (error) {
if (error.message === 'Insufficient budget') {
// Request more budget or pause agent
await requestBudgetIncrease();
}
}Step 4: Verify Receipts
Always verify receipt signatures to ensure payment integrity:
import crypto from 'crypto';
function verifyReceipt(receipt: any, signature: string, secret: string): boolean {
const { signature: _, ...payload } = receipt;
const message = JSON.stringify(payload, Object.keys(payload).sort());
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signature)
);
}
// Use after each payment
const result = await agent.call(endpoint, data);
const isValid = verifyReceipt(
result.receipt,
result.receipt.signature,
WEBHOOK_SECRET
);
if (!isValid) {
throw new Error('Invalid receipt signature');
}Best Practices
Set reasonable budget limits per agent
Implement per-call price maximums
Log all payments for auditing
Verify all receipt signatures
Handle payment failures gracefully
Monitor agent spending in real-time