Agent integration guide
cron402 is a pure x402 resource server. Every paid endpoint follows the same dance:
request → 402 Payment Required → sign USDC payment (EIP-3009) → retry with
payment header. Use any x402 client — @x402/fetch is the drop-in option.
1. Create a cron job
npm install @x402/fetch @coinbase/cdp-sdkimport { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { CdpClient } from "@coinbase/cdp-sdk";
import { applySpendControls, fromCdpEvmAccount } from "@coinbase/cdp-sdk/x402";
// Coinbase Agentic Wallet (no private key handling in your code)
const cdp = new CdpClient();
const account = await cdp.evm.getOrCreateAccount({ name: "my-agent" });
const client = new x402Client().register(
"eip155:8453", // Base mainnet
// "eip155:8453", // base mainnet
new ExactEvmScheme(fromCdpEvmAccount(account)),
);
applySpendControls(client, { maxAmountPerPayment: { atomic: 100_000n } }); // $0.10 cap
const fetchWithPayment = wrapFetchWithPayment(globalThis.fetch, client);
const res = await fetchWithPayment(`https://cron402-api.user-defaults.workers.dev/v1/crons`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
schedule: "*/5 * * * *",
target: {
url: "https://your-agent.example/tick",
method: "POST",
body: JSON.stringify({ hello: "world" })
}
}),
});
const { id } = await res.json();2. Check status & execution log
const status = await fetch(`https://cron402-api.user-defaults.workers.dev/v1/crons/${id}`).then(r => r.json());
// { credits: 9, status: "active", nextRunAt: 1755000000000,
// executions: [{ runAt, ok, statusCode, durationMs }, ...] }3. Top up run credits ($0.008 / run)
await fetchWithPayment(`https://cron402-api.user-defaults.workers.dev/v1/crons/topup/10`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ jobId: id }),
});4. Pause / resume / delete (wallet-signed)
Management actions require an EIP-712 signature over ManageJob { action } from the payer's key.
const message = {
action: "pause", // "pause" | "resume" | "delete"
jobId: id,
timestamp: Date.now(), // valid for ±5 minutes
};
const signature = await account.signTypedData({
domain: { name: "cron402", version: "1" },
types: { ManageJob: [
{ name: "action", type: "string" },
{ name: "jobId", type: "string" },
{ name: "timestamp", type: "uint256" },
]},
primaryType: "ManageJob",
message,
});
await fetch(`https://cron402-api.user-defaults.workers.dev/v1/crons/${id}/pause`, {
method: "POST",
headers: {
"x-cron402-timestamp": String(message.timestamp),
"x-cron402-signature": signature,
},
});API reference
| Endpoint | Auth | Description |
|---|---|---|
POST /v1/crons | x402 · $0.008 | Create job (includes 1 credit) |
POST /v1/crons/topup/1|10|100 | x402 · $0.008/$0.08/$0.80 | Add run credits |
GET /v1/crons/:id | free | Status + last executions |
GET /v1/openapi.json | free | OpenAPI 3.1 machine-readable spec |
POST /v1/crons/:id/pause | wallet-signed | Pause job |
POST /v1/crons/:id/resume | wallet-signed | Resume job (needs credits) |
DELETE /v1/crons/:id | wallet-signed | Delete job |
Limits & policies
- Min interval 1 minute · max 1,000 active jobs per wallet
- Failed dispatches retry 3× with backoff, then the job auto-pauses
- Jobs with zero credits pause automatically; top up to reactivate
- Execution logs kept: last 100 runs or 30 days per job
- Live on **Base mainnet** (
eip155:8453). Testnet waseip155:84532.