# AGENTS.md — grokzilla.shop / x402-micro-pay.com

Instructions for autonomous agents consuming this marketplace.

## Identity

- **Name:** Grokzilla x402 micro pay
- **Base URL:** https://grokzilla.shop (alias https://x402-micro-pay.com)
- **Protocol:** x402 v2 (USDC) + Stripe (humans)
- **Network:** eip155:8453 (Base mainnet)
- **USDC:** 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
- **Billing:** paid only (`free_beta: false`)

## Discovery (do this first)

```http
- Catalog (JSON): https://grokzilla.shop/api/catalog
- Agents JSON: https://grokzilla.shop/agents.json
- OpenAPI: https://grokzilla.shop/openapi.json
GET https://grokzilla.shop/contracts/humanless.json
GET https://grokzilla.shop/health
```

## MCP

- Streamable HTTP: `POST https://grokzilla.shop/mcp` (stateless JSON, no session).
- Quickstart: https://grokzilla.shop/agents and https://grokzilla.shop/agents.md
- Server card: https://grokzilla.shop/.well-known/mcp/server-card.json
- Discovery tools `list_skills` and `get_skill` are free. Other tools are pay-per-call over x402. Clients that cannot pay receive a PaymentRequired result and should stop.

## Payment flow

1. Call a skill endpoint without payment → expect **HTTP 402** with `PAYMENT-REQUIRED` header **and** JSON body (`accepts[]`).
2. Decode accepts[]: scheme=exact, network=eip155:8453, asset=USDC mainnet, amount, payTo.
3. Sign and attach payment proof; retry same request with `PAYMENT-SIGNATURE`.
4. On success, response includes resource JSON (+ optional PAYMENT-RESPONSE).

Humans: `POST /api/stripe/checkout` with `{ "skill_id", "payload" }`.

## Spend limits

Respect `max_spend_per_call` and `max_spend_per_session` in `/contracts/humanless.json`.

## Cheap deterministic utils ($0.003, POST, JSON body)

- `/api/skills/pii-redact` `{ "text" }` → `{ ok, redacted, counts_by_type }` (emails, phones, SSN-shaped, Luhn-valid cards, IPv4 → `[EMAIL]`, `[PHONE]`, `[SSN]`, `[CARD]`, `[IPV4]`)
- `/api/skills/csv-normalize` `{ "csv", "delimiter"? }` → `{ ok, headers, rows, row_count }` (snake_case headers; 400 on ragged rows / unparseable CSV)
- `/api/skills/base64` `{ "mode": "encode"|"decode", "text", "url_safe"? }` → `{ ok, output }` (400 on invalid base64)

Bad param types or values → 422 `invalid_params`; content errors → 400. Neither is charged. Free preflight: header `X-X402-Validate-Only: 1`.

## Epoch, web reading, token risk (POST, JSON body)

- `/api/skills/epoch-convert` ($0.003) `{ "value", "tz"? }` → `{ epoch_s, epoch_ms, iso_utc, iso_tz }` (seconds vs ms by magnitude, or ISO-8601; IANA tz, 400 `unknown_tz`; deterministic, no network)
- `/api/skills/url-to-markdown` ($0.003) `{ "url" }` → `{ ok, url, final_url, title, markdown, bytes, truncated }` (one public page; honors robots.txt for `grokzilla-url-to-markdown`; SSRF-guarded; HTML only; 1 MB / 5 s; no JavaScript rendering; own domains refused before payment)
- `/api/skills/token-risk` ($0.005) `{ "token", "chain": "base" }` → `{ ok, token, chain, risk_level: low|medium|high|unknown, checks: { contract_code, erc20_metadata, proxy, ownership, privileged_functions, liquidity_pool, sell_simulation, buy_simulation, transfer_tax }, disclaimer }` (read-only public Base RPC; each check has `result` pass/warn/fail/unknown and `evidence`; informational, not financial advice)

## JSON repair and cron schedules (POST, JSON body)

- `/api/skills/json-repair` ($0.0041) `{ "text" }` → `{ ok, json, repaired, fixes[], changed }` (fences, comments, trailing commas, single quotes, unquoted keys, True/False/None, missing commas, truncated strings/brackets; 400 `unrepairable_json`; deterministic, no network)
- `/api/skills/cron-next` ($0.0031) `{ "expr", "tz"?, "count"? (1-20, default 5), "from"? }` → `{ ok, normalized, tz, next[], next_utc[], next_epoch_s[] }` (5-field cron with lists, ranges, steps, names and @daily-style macros; DST-aware IANA tz; 400 `bad_cron` / `unknown_tz` / `no_match`)

## Data services (POST, JSON body; same envelope: ok, service, version, summary, data, confidence, sources, generated_at, data_as_of, charged, warnings, next)

Bad input → 400 before any 402 (`charged:false`). A call that ran but found nothing chargeable → 422/503 `charged:false`, never settled.

- `/api/skills/token-price` ($0.002) `{ "token": "0x…" (Base ERC-20), "chain": "base" }` → `{ data: { price_usd, spread_pct, by_source: { defillama, onchain: { pool, block } }, disclaimer } }` (DeFiLlama cross-checked against the deepest on-chain Uniswap/Aerodrome pool; 422 `sources_disagree` over 2.5% / `insufficient_sources`; no CoinGecko; data only, not investment advice)
- `/api/skills/email-check` ($0.0032) `{ "email" }` → `{ data: { verdict: deliverable|risky|undeliverable, reasons, canonical, mx, spf, dmarc, disposable, role_account, free_provider, mailbox_checked: false } }` (DNS-over-HTTPS only; no SMTP or mailbox probing)
- `/api/skills/news-brief` ($0.0101) `{ "topic", "timespan"?: 24h|3d|7d, "max_clusters"? (1-20) }` → `{ data: { clusters: [{ headline, first_seen, outlet_count, outlets: [{ outlet, headline, url, seen_at }] }] } }` (GDELT + publisher RSS; headlines and links only, no article text; 422 `no_results`)
- `/api/skills/ip-intel` ($0.0033) `{ "query": IP or CIDR, "check"?: [ips] }` → `{ data: { network, registry: { holder, abuse_email, cidrs }, routing: { asns, as_holder }, geo: { country, attribution } } }` (RIR RDAP + RIPEstat + DB-IP Lite country, CC BY 4.0 "IP Geolocation by DB-IP"; private/reserved ranges refused before payment)
- `/api/skills/llm-cost-quote` ($0.0034) `{ "text" | "input_tokens", "output_tokens"?, "models"?, "top"? }` → `{ data: { quotes: [{ model, cost_usd, input_usd_per_mtok, output_usd_per_mtok, context_length }], price_fetched_at } }` (OpenRouter public price list, cheapest first, time-of-day pricing applied)
- `/api/skills/phone-normalize` ($0.0021) `{ "number", "region"? }` → `{ data: { valid, possible, type, region, e164, national, international } }` (full libphonenumber metadata, offline; no owner or carrier lookup)

## AI content detector ($0.01, POST, JSON body)

- `/api/skills/ai-detector` `{ "text" }` or `{ "url" }` → `{ verdict: likely_ai|likely_human|uncertain|possible_ai_influence, ai_likelihood, caveats, ... }`. Trained classifier, about 78% accurate on a held-out benchmark; not a guarantee and not sole evidence. `uncertain` results suggest a rerun on a longer section (300+ words). Tell phrases are only a secondary "possible AI influence" signal.

## SEO v2 and Agent-Ready Website Kit (POST, JSON body)

- `/api/skills/seo-v2` `{ "url", "keywords"? }` and `/api/skills/seo-compare` `{ "url", "competitor_urls": [1-3] }` -> score, checks, fixes.
- `/api/skills/agent-ready-audit` and `/api/skills/agent-ready-kit` `{ "url", "max_pages"?, "crawler_policy"?, "business"?, "override_full_disallow"?, "runs_a2a_agent"? }`.
  - `override_full_disallow` (bool, default false): a site-wide `Disallow: /` is never opened to AI bots unless true (WARNING + INSTALL.md note instead).
  - `runs_a2a_agent` (bool, default false): `.well-known/agent-card.json` is generated and scored only if true.
- `/api/skills/agent-ready-recheck` `{ "report_id" }` (from the last 30 days). Missing or invalid report_id -> 400 before payment.
- Not charged when the site blocks us or is unreachable: 422 with `score: null`, `status`, `reason`, `charged: false`; the verified payment is never settled. Settle failure after a result -> 402, no result.

## Do not

- Assume free access (beta is off).
- Ignore 402 challenges or pay on the wrong network (must be Base mainnet).
- Exceed humanless spend caps.
