Capping what your agent spends
Checked against the live server on Oct 17, 2026, including real paid calls at 11:55–11:57 AM CT.
Every paid call on grokzilla.shop is one small, exact USDC payment on Base. Nothing is billed afterwards and there's no account to top up. You only pay for calls you sign. These rules keep that safe.
1. Check every challenge before you sign
Pay only if all of these match:
Field in accepts[0] |
Must be |
|---|---|
scheme |
exact |
network |
eip155:8453 (Base mainnet) |
asset |
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (USDC) |
payTo |
0xc22f9CAEBAc37fE72D5142f35f21f6696Ea9Ef69 |
amount |
the catalog price × 1,000,000, nothing higher |
The same payTo is published at https://grokzilla.shop/.well-known/x402 (pay_to). If a challenge names any other address, don't pay, and tell us.
Prices are in https://grokzilla.shop/api/catalog (price_usd) and at the end of each MCP tool description. As of Oct 17 the per-call MCP tools run from $0.002 (token_price) to $0.012 (seo). Over plain HTTP, a few site-audit skills cost more, up to $0.1993 per call. Always read the live catalog rather than this page.
Our published limits are in https://grokzilla.shop/contracts/humanless.json (constraints): at most $0.25 per call and $0.50 per session. Every per-call skill fits under that cap. Items listed in one_time_purchases (such as the $1 credit pack and downloadable kits) are explicit purchases outside that cap, so buy them only on purpose.
2. Set a per-call cap
@x402/mcp already refuses any single payment over $1 by default (spendControls.maxAmountPerPayment). That's far above anything here, so tighten it. A policy that only accepts our exact terms and caps each call at 2 cents:
const PAY_TO = "0xc22f9CAEBAc37fE72D5142f35f21f6696Ea9Ef69".toLowerCase();
const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913".toLowerCase();
const MAX_PER_CALL = 20_000n; // $0.02 in USDC atomic units
const onlyGrokzilla = (_v: number, reqs: any[]) =>
reqs.filter(r =>
r.scheme === "exact" &&
r.network === "eip155:8453" &&
String(r.asset).toLowerCase() === USDC_BASE &&
String(r.payTo).toLowerCase() === PAY_TO &&
BigInt(r.amount) <= MAX_PER_CALL);
Pass it as policies: [onlyGrokzilla] to createx402MCPClient. If nothing passes the filter, the client doesn't pay.
3. Set a daily budget
The client has no built-in daily total, so keep one yourself in onPaymentRequested. Return false to refuse:
let spentToday = 0n; // reset at midnight in your own scheduler
const DAILY_BUDGET = 500_000n; // $0.50, the same as max_spend_per_session_usd
onPaymentRequested: async ({ toolName, paymentRequired }) => {
const amount = BigInt(paymentRequired.accepts[0].amount);
if (spentToday + amount > DAILY_BUDGET) return false;
spentToday += amount; // counts approvals, so it may over-count failed calls
return true;
}
Count conservatively. Note that @x402/mcp returns paymentMade: true whenever it signed and retried, even if the server rejected the payment and nothing settled (seen live Oct 17, both with an unfunded key and with a paid call that had bad arguments). If you want an exact ledger, record the transaction from _meta["x402/payment-response"] and only count calls that carry one.
Simplest hard limit of all: fund the paying wallet with only what you're willing to spend.
4. When you're not charged
- Bad input, before payment. Over HTTP, add
X-X402-Validate-Only: 1to any skill request. Wrong input gets 422 with field errors and no challenge; good input gets the 402. Checked live on json-repair, sha256, slugify, json-flatten, token-count and url-to-markdown. Some skills (seo, url-to-markdown with a private URL, and the six data skills) refuse bad input with 400 and"charged": falseeven without that header, over HTTP and MCP. - Bad input, after you paid. Most tools (json_repair, sha256 and the other simple utilities) return the challenge even when the arguments are wrong. If you sign anyway, the payment is not settled. Tested Oct 17 with real signed payments on json_repair
{}: over HTTP it returned 422invalid_params; over MCP,isError: truewith "Invalid arguments: ...". No USDC moved either time. Validate againstinputSchemafirst to save the round trip. - Payment can't be verified. Over MCP you get
isError: trueand_meta{"x402/error":{"code":"payment_verification_failed",...},"charged":false}. Nothing settles. - Nothing chargeable, after payment. If a skill runs but has nothing real to give you (seo with no score, for example), the server answers 422 or another 4xx/5xx with
"charged": falseand doesn't settle. This follows our server rules; the Oct 17 paid test didn't cover it.
5. Retries and double charges
- A payment is one signed USDC authorization with its own nonce. It can settle once at most, so resending the same signed payment can't charge you twice.
- On a timeout or a network error after you sent a payment, check the wallet's USDC history for a transfer to the payTo before signing a new one. If it went through, don't pay again for the same call.
- An unsettled authorization expires after
maxTimeoutSeconds(300 seconds here). After that it can't be used. isError: truewith nox402/payment-responsein_metameans nothing settled. Fix the issue and pay fresh.- There's no
Idempotency-Keysupport for x402 calls on this server, so don't rely on one.
6. Keep the key away from the server
The server never asks for a key and never holds one. Your client signs locally. Never paste a private key into a tool argument.