AI Agents
Build autonomous agents that discover, subscribe to, and manage API subscriptions on-chain.
Overview
Cron Protocol has native support for AI agents. Agents can hold a wallet, discover agent-compatible plans, approve a budget, and subscribe autonomously — all without human interaction.
The AgentBudgetManager contract lets you set per-agent spending caps so an agent wallet cannot spend beyond its authorized budget.
CronAgent
CronAgent extends CronClient with agent-specific helpers. Use it when your code runs in an autonomous context (no browser, no user wallet).
import { CronAgent } from "@cron/sdk";
import { parseUnits } from "viem";
const agent = new CronAgent({
chain: "base",
privateKey: process.env.AGENT_PRIVATE_KEY!,
});Discover plans
// Find agent-compatible API plans within your budget
const plans = await agent.plans.search({
agentCompatible: true,
maxAmount: parseUnits("20", 6), // max $20/month
serviceType: "api_access",
});
// Sort by price
plans.sort((a, b) => Number(a.amount - b.amount));
console.log("Cheapest plan:", plans[0].id, formatUnits(plans[0].amount, 6));Subscribe autonomously
// Subscribe to the first matching plan
const { subscriptionId } = await agent.subscribe(plans[0].id);
console.log("Agent subscribed:", subscriptionId);Set a spending budget
Before subscribing, a controller wallet (your backend) can set a monthly spending cap on the agent's wallet using AgentBudgetManager:
import { AGENT_BUDGET_MANAGER_ABI } from "@cron/sdk";
// Called by your controller wallet, not the agent
await walletClient.writeContract({
address: chainConfig.agentBudgetManagerAddress,
abi: AGENT_BUDGET_MANAGER_ABI,
functionName: "setBudget",
args: [
agentAddress,
parseUnits("50", 6), // $50/month cap
2592000, // 30-day window
],
});Check and manage budget
const budget = await agent.budget.get(agentAddress);
console.log("Remaining budget:", formatUnits(budget.remaining, 6));
console.log("Spent this period:", formatUnits(budget.spent, 6));
console.log("Resets at:", new Date(budget.resetsAt * 1000));Listen for subscription events
const listener = agent.events.listen();
listener.on("Charged", (event) => {
if (event.subscriber === agentAddress) {
console.log("Agent charged:", formatUnits(event.amount, 6), "USDC");
}
});
listener.on("SubscriptionExpired", (event) => {
if (event.subscriber === agentAddress) {
// Resubscribe or find a new plan
agent.subscribe(event.planId);
}
});Full agent example
import { CronAgent } from "@cron/sdk";
import { parseUnits, formatUnits } from "viem";
async function main() {
const agent = new CronAgent({
chain: "base",
privateKey: process.env.AGENT_PRIVATE_KEY!,
});
// 1. Find a suitable plan
const plans = await agent.plans.search({
agentCompatible: true,
maxAmount: parseUnits("10", 6),
});
if (plans.length === 0) {
throw new Error("No suitable plans found");
}
const plan = plans[0];
// 2. Check current subscription status
const status = await agent.subscriptions.getStatus({
planId: plan.id,
subscriber: agent.address,
});
if (status === "Active") {
console.log("Already subscribed");
return;
}
// 3. Subscribe
const { subscriptionId } = await agent.subscribe(plan.id);
console.log("Subscribed to plan", plan.id, "subscription:", subscriptionId);
}
main().catch(console.error);MPP Transport for Paid APIs
Agents can access paid Cron APIs using MPP sessions — sub-100ms micropayments with no per-request blockchain transactions:
const agent = new CronAgent({
chain: "base",
privateKey: process.env.AGENT_PRIVATE_KEY!,
mpp: {
apiBaseUrl: "https://api.cronprotocol.xyz",
maxSessionDeposit: "1", // $1 max session deposit
},
});
// Paid API calls auto-negotiate MPP sessions
const plans = await agent.searchPlansViaApi();
// High-frequency queries use session vouchers (near-zero marginal cost)
const chargeable = await agent.queryChargeableViaApi([
{ subscriber: "0x...", planId: "1" },
]);
// Stream plan data via SSE
for await (const plan of agent.streamPlansViaApi()) {
console.log("Plan:", JSON.parse(plan));
}[i] Two budget layers
[!] Secure your agent key
AgentCompatible flag
Merchants mark plans as agent-compatible by setting agentCompatible: trueat plan creation. This signals that the API supports machine-to-machine access and agents can subscribe without human interaction. Non-agent-compatible plans still work technically, butplans.search() filters to agent-compatible by default.