AI agents that search the web need a payment method that works programmatically. USDC stablecoins enable per-query micropayments without credit cards or monthly commitments. This tutorial builds a payment wrapper around search API calls that tracks spending in USDC, sets per-agent budgets, and logs every transaction. The search itself uses Scavio at $0.005/query, and the USDC layer adds transparent cost tracking.
Prerequisites
- Python 3.9+ installed
- requests library installed
- A Scavio API key from scavio.dev
- Basic understanding of stablecoin wallets
Walkthrough
Step 1: Build the USDC budget tracker
Create a budget system that tracks agent spending in USDC. Each agent gets a budget allocation and cannot exceed it.
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Dict
@dataclass
class Transaction:
agent_id: str
amount_usdc: float
service: str
query: str
timestamp: str = field(default_factory=lambda: datetime.now().isoformat())
class USDCBudget:
def __init__(self):
self.balances: Dict[str, float] = {}
self.transactions: List[Transaction] = []
def fund_agent(self, agent_id: str, amount_usdc: float):
self.balances[agent_id] = self.balances.get(agent_id, 0) + amount_usdc
print(f'Agent {agent_id}: funded ${amount_usdc} USDC (balance: ${self.balances[agent_id]})')
def can_spend(self, agent_id: str, amount: float) -> bool:
return self.balances.get(agent_id, 0) >= amount
def spend(self, agent_id: str, amount: float, service: str, query: str) -> bool:
if not self.can_spend(agent_id, amount):
return False
self.balances[agent_id] -= amount
self.transactions.append(Transaction(agent_id, amount, service, query))
return True
def summary(self, agent_id: str) -> dict:
agent_txns = [t for t in self.transactions if t.agent_id == agent_id]
total_spent = sum(t.amount_usdc for t in agent_txns)
return {'balance': self.balances.get(agent_id, 0),
'total_spent': total_spent, 'transactions': len(agent_txns)}
budget = USDCBudget()
budget.fund_agent('research-agent', 1.00) # $1 USDC budget
budget.fund_agent('lead-gen-agent', 5.00) # $5 USDC budget
print(f'Research agent: ${budget.balances["research-agent"]} USDC')
print(f'Lead gen agent: ${budget.balances["lead-gen-agent"]} USDC')Step 2: Wrap search calls with USDC spending
Create a search function that checks the agent's USDC budget before making API calls and records each transaction.
import requests, os
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
SEARCH_COST_USDC = 0.005 # $0.005 per query
def budgeted_search(agent_id: str, query: str, budget: USDCBudget) -> dict:
if not budget.can_spend(agent_id, SEARCH_COST_USDC):
remaining = budget.balances.get(agent_id, 0)
return {'error': f'Insufficient USDC balance: ${remaining:.3f} < ${SEARCH_COST_USDC}',
'results': []}
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': 10})
results = resp.json().get('organic_results', [])
budget.spend(agent_id, SEARCH_COST_USDC, 'scavio_search', query)
return {
'results': [{'title': r['title'], 'link': r['link']}
for r in results],
'cost_usdc': SEARCH_COST_USDC,
'remaining_usdc': budget.balances[agent_id]
}
# Agent makes searches against its budget
result = budgeted_search('research-agent', 'best python frameworks 2026', budget)
print(f'Results: {len(result["results"])}')
print(f'Cost: ${result.get("cost_usdc", 0)} USDC')
print(f'Remaining: ${result.get("remaining_usdc", 0):.3f} USDC')Step 3: Add spending reports and alerts
Generate spending reports per agent and set up alerts when budgets run low.
def spending_report(budget: USDCBudget):
print('Agent Spending Report')
print('=' * 50)
for agent_id, balance in budget.balances.items():
summary = budget.summary(agent_id)
print(f'\nAgent: {agent_id}')
print(f' Balance: ${balance:.3f} USDC')
print(f' Spent: ${summary["total_spent"]:.3f} USDC')
print(f' Transactions: {summary["transactions"]}')
# Alert if low balance
if balance < 0.10:
print(f' WARNING: Low balance! Fund this agent to continue.')
# Queries remaining estimate
queries_left = int(balance / SEARCH_COST_USDC)
print(f' Queries remaining: ~{queries_left}')
# Simulate some agent activity
for i in range(5):
budgeted_search('research-agent', f'query {i}', budget)
spending_report(budget)Python Example
import requests, os
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
balances = {'agent-1': 1.0}
txns = []
def search(agent_id, query, cost=0.005):
if balances.get(agent_id, 0) < cost:
return {'error': 'Insufficient USDC'}
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': 10})
balances[agent_id] -= cost
txns.append({'agent': agent_id, 'cost': cost, 'query': query})
results = resp.json().get('organic_results', [])
print(f'${cost} USDC | Balance: ${balances[agent_id]:.3f} | Results: {len(results)}')
return results
search('agent-1', 'best CRM tools 2026')
print(f'Total spent: ${sum(t["cost"] for t in txns):.3f} USDC')JavaScript Example
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const balances = { 'agent-1': 1.0 };
async function search(agentId, query, cost = 0.005) {
if ((balances[agentId] || 0) < cost) return { error: 'Insufficient USDC' };
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: 'us', num_results: 10 })
});
balances[agentId] -= cost;
const results = (await resp.json()).organic_results || [];
console.log(`$${cost} USDC | Balance: $${balances[agentId].toFixed(3)} | Results: ${results.length}`);
return results;
}
search('agent-1', 'best CRM tools 2026');Expected Output
Agent research-agent: funded $1.00 USDC (balance: $1.0)
Agent lead-gen-agent: funded $5.00 USDC (balance: $5.0)
Results: 10
Cost: $0.005 USDC
Remaining: $0.995 USDC
Agent Spending Report
==================================================
Agent: research-agent
Balance: $0.970 USDC
Spent: $0.030 USDC
Transactions: 6
Queries remaining: ~194