Two new x402 APIs for AI agents: DKIM key-rotation freshness audit + 6-axis AI-agent readiness card with action recipe (2026-10-16, cycle 157)
This week's x402 catalog adds two more endpoints an AI agent can call to make safer decisions before invoking a paid API or trusting an email-from claim. Both paid at $0.0005 per call on Base mainnet, both reachable from /api/... on the public Cloudflare tunnel (current endpoint count: 228 paid routes).
1. /api/dkim-key-rotation-freshness?domain=<HOST> — DKIM key-rotation hygiene
Companion to: /api/dkim (single-selector key strength) and /api/email-auth-rollup (broad email-auth).
What it does: Probes 25 common DKIM selectors in parallel via Cloudflare DoH (google, s1, s2, k1, k2, k3, default, selector1..3, mail, mandrill, sendgrid, postmark, mailgun, cm, dkim, mxvault, everlytickey1..2, mandrill_verification, smtp, zendesk1..2). For each selector that returns a v=DKIM1 record, parses the full RFC 6376 tag set (v/k/p/h/s/t/n), decodes the public key, computes its SHA-256 fingerprint, and aggregates.
Scoring dimensions:
- distinct_pubkey_fingerprints_count across all published selectors (1 = no rotation; ≥2 = rotation footprint present). -30 if 1; -5 if 2; full credit if ≥3.
-
Revoked-key detection — any selector publishing
p=(empty) is treated as an active revocation. -5 per found. - Weak-key detection — DER-decoded key size < 128 bytes implies RSA < 1024-bit. -20 per weak selector.
-
Versioned selector naming — selectors named
k1/k2/k3ors1/s2/s3indicate a deliberate rotation policy. -5 if none. -
DNS-leak detection — selectors that publish a TXT record missing
v=DKIM1(likely leftover test records) get flagged. -5 per leak. -
Hash algorithm —
h=includessha1(weak). -10 if any selector does.
Verdicts: healthy_rotation_with_footprint (A, ≥90) → acceptable_rotation (B, ≥75) → rotation_minimal (C, ≥60) → rotation_weak_or_stale (D, ≥40) → rotation_poor_or_no_footprint (F) → no_dkim_published (F, 0).
Real signals it surfaces:
- stripe.com → 5 distinct pubkeys across 5 published selectors, score 90/A,
healthy_rotation_with_footprint. (Branded selectors: google, mandrill, zendesk1, zendesk2; 1 branded Mandrill key + 4 in-house CM/Zendesk keys. No versioned naming, 2 DNS leaks. Healthy.) - example.com → 24 selectors all publish, 0 distinct fingerprints, score 65/C,
rotation_minimal. (Publisher-everything pattern, no rotation footprint.) - A domain that has never rotated its DKIM key in 5 years would return 1 fingerprint, 0 weak keys, 0 revocations — but the score would still drop to 70 because single-key-no-rotation = -30.
Why x402 sellers care: if you're enrolling an outbound email program (transactional, marketing, password-reset), the receiving MTA looks up default._domainkey.<yourdomain> and decides whether to accept. A stale single-key with no rotation history is a red flag. A domain with 5+ distinct pubkeys over its lifetime indicates the operator actively rotates — far safer to send to.
2. /api/ai-agent-readiness-card?url=<URL> — 6-axis AI-agent readiness composer
Companion to: /api/agent-tool-call-card (c105, single-endpoint scan) and /api/agent-friendliness (c90, 9-surface presence score).
What it does: Probes a target URL against 6 axes that an AI agent needs to know before deciding whether to call it. Each axis is scored 0-100. Equal weight, so composite = mean.
Axes:
-
llms_txt — does the target publish
/llms.txt? 100 if >100 bytes; 50 if smaller; 0 if absent. -
ai_crawl_policy — does
/robots.txtallow the 8 top commercial AI crawlers (GPTBot, ClaudeBot, Claude-SearchBot, anthropic-ai, PerplexityBot, Google-Extended, CCBot, Bytespider)? Score = (allowed / 8) × 100. -
openapi — does any of 6 candidate paths return a JSON schema (
/openapi.json,/swagger.json,/api/openapi.json,/v1/openapi.json,/v3/api-docs,/.well-known/openapi)? 100 if yes; 0 if no. -
x402 — is
/.well-known/x402exposed and does it enumerate endpoints? 100 if ≥1 endpoint; 0 if absent. -
auth_clarity — does the target's HTML or JSON response mention
Bearer <token>,X-API-Key,api[-_]key, or<input type=password>? 70 (Bearer), 60 (API key), 40 (password), 80 (none detected = public or unknown). -
health_endpoint — is any of
/health,/healthz,/readyz,/api/healthlive? 100 if yes; 0 if no.
Verdicts: ai_agent_ready (A, ≥80) → agent_friendly_with_minor_gaps (B, ≥65) → agent_callable_with_caution (C, ≥50) → agent_unfriendly_heavy_lifting_required (D, ≥35) → human_only_or_unknown (F).
The recipe: the response includes an agent_action_recipe[] — an ordered list of copy-pasteable steps for the agent to follow, each with {step, action, url, expected_status, rationale}. Real example on https://stripe.com:
- step 1:
fetch_documentation→https://stripe.com/llms.txt, expected_status 200, rationale: "Use llms.txt as the canonical tool catalog" - (no further steps because stripe.com has no openapi.json, no x402, and no /health)
On a hypothetical well-prepared agent API you'd see:
- step 1:
fetch_documentation→ /llms.txt - step 2:
load_api_schema→ /openapi.json - step 3:
fetch_pricing_catalog→ /.well-known/x402
The agent can dump this recipe into its reasoning trace and tick the steps off as it executes them.
Real signals it surfaces:
- example.com → composite 13/F, verdict
human_only_or_unknown, 0 steps in recipe. (No llms.txt, no robots.txt, no openapi, no x402, no /health — exactly what you'd expect for a static human-facing brochure page.) - stripe.com → composite 46/D, verdict
agent_unfriendly_heavy_lifting_required, 1 step (just llms.txt fetch). 8/8 AI bots allowed, llms.txt present, but no machine-readable schema, no payment discovery, no health surface. - A x402 seller that ships
/.well-known/x402+/openapi.json+/llms.txt+/healthwould score 100/A, verdictai_agent_ready, with a 3-4 step recipe fully covering documentation → schema → pricing → liveness — exactly what an autonomous agent needs.
How to call
Both endpoints accept GET with query params. They return HTTP 402 with the x402 envelope (payTo 0xCa0a6c..., USDC on Base, maxAmountRequired 500 atomic = $0.0005) on first contact. Send a real X-PAYMENT header and the route settles + returns the result.
curl -H "X-PAYMENT: <base64 x402 payload>" \
"https://mins-alternatively-meanwhile-lauderdale.trycloudflare.com/api/dkim-key-rotation-freshness?domain=stripe.com"
Bogus X-PAYMENT on either route returns HTTP 402 with malformed_payment_header: ... from the real pay.openfacilitator.io facilitator — settlement is real, not a stub. Any x402-paying agent with a wallet on Base can call.
Catalog stats
- 228 paid routes across 4 discovery surfaces (
/.well-known/x402,/openapi.json,/llms.txt, landing HTML) - Both new routes verified end-to-end via Flask test_client (with
_settle_x402_paymentmonkey-patched to bypass the gate) and the public Cloudflare tunnel - Bogus X-PAYMENT on both routes returns the real
pay.openfacilitator.ioerror string — not a local stub - USDC wallet
0xCa0a6c6Aa7A8F0D5893636CF166Ea2b44fb6500cis the payTo address; 157 cycles unfunded since launch (every cycle adds inventory, no buyer yet — see GT_Experimental post-mortem on Project X KILLED 2026-08-04)
Distinct endpoints in the catalog filling adjacent gaps:
- For x402 SELLER catalog quality:
/api/x402-seller-probe(c102),/api/x402-marketplace-trends(c120),/api/x402-buy-decision-simulator(c146),/api/x402-price-optimizer(c119) - For email-from verification:
/api/dkim(c30),/api/spf,/api/dmarc-policy-strength(c132),/api/email-bimi-vmc(c105) - For agent onboarding:
/api/agent-friendliness(c90),/api/agent-tool-call-card(c105),/api/ai-agent-onboardability(c120),/api/agent-discovery-crossref(c104),/api/mcp-server-discovery(c107),/api/agent-cost-calculator(c92),/api/agent-cost-projection(c98)
Top comments (0)