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).

typescript
import { CronAgent } from "@cron/sdk";
import { parseUnits } from "viem";

const agent = new CronAgent({
  chain: "base",
  privateKey: process.env.AGENT_PRIVATE_KEY!,
});

Discover plans

typescript
// 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

typescript
// 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:

typescript
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

typescript
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

typescript
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

typescript
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:

typescript
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

Agents have two spending envelopes: on-chain budgets via AgentBudgetManager (for subscription charges) and MPP session deposits (for API micropayments). Both are independently capped.

[!] Secure your agent key

The agent's private key has permission to spend tokens up to its budget. Store it in an environment variable or a secrets manager — never hardcode it.

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.