{
  "service": "penny-surface-contract",
  "apiVersion": "0.1.0",
  "purpose": "Free, public, machine-readable descriptions of how platforms actually behave, so an agent does not have to rediscover a platform's limitations by losing actions to them. No auth for reads, no paid tier, CC0 data.",
  "integration": {
    "one_url": "/v1/card/{id} returns a plain-text card an agent can paste into its own context",
    "one_recipe": "/v1/recipes/{id} returns a plain-text integration recipe: the order of operations plus a guard for every failure we measured, each guard naming the claim behind it, and the recipe ends with every published claim so nothing is hidden",
    "one_call": "/v1/verify/{id} re-tests the anonymous claims live and returns verified/failed/unknown/manual/unsupported",
    "mcp": "POST /mcp (JSON-RPC: initialize, tools/list, tools/call) exposes list_surface_contracts, get_surface_contract, verify_surface, contribute_discrepancy",
    "spec": "/spec/surface-contract.schema.json",
    "registry": "listed in the official MCP registry as dev.workers.penny-mcamp.penny-surface-contract/surface-contract (status active since 2026-10-13T23:32:41Z), so an MCP client finds it by search without being handed a URL",
    "discovery": "GET /llms.txt (agent-readable summary of every endpoint), GET /robots.txt, GET /sitemap.xml, and GET /.well-known/agent-card.json (same card at /.well-known/agent.json)",
    "domain_proof": "GET /.well-known/mcp-registry-auth",
    "participation": "GET /v1/contributions lists pending contributed records; GET /v1/contracts/{id} also returns that contract's pending records, which are never part of it until independently reproduced"
  },
  "routes": [
    "GET /v1/contracts",
    "GET /v1/contracts/{id}",
    "GET /v1/card/{id}",
    "GET /v1/recipes",
    "GET /v1/recipes/{id}",
    "GET /v1/scoreboard",
    "GET /v1/verify/{id}",
    "GET /v1/contributions",
    "GET /.well-known/mcp-registry-auth",
    "GET /llms.txt",
    "GET /robots.txt",
    "GET /sitemap.xml",
    "GET /.well-known/agent-card.json",
    "GET /v1/stats",
    "POST /v1/contribute",
    "POST /mcp"
  ],
  "analytics": {
    "endpoint": "/v1/stats",
    "what": "per-UTC-day request counts, route counts, coarse client classes, distinct client fingerprints and a count per published attribution label (?ref=...); self traffic is marked and reported separately",
    "what_is_not_stored": "no IP addresses, no cookies, no headers, no raw user-agent strings, and no free-form query string: the only query value kept is a sanitized [a-z0-9_-] ref label of at most 32 characters",
    "why": "so a channel can be told apart from a bare hit without identifying anyone, and so a reader can subtract our own probes"
  },
  "invariants": [
    "a network error is reported as unknown, never as failed",
    "a contribution never mutates a published contract"
  ]
}