{
  "openapi": "3.1.0",
  "info": {
    "title": "402registry",
    "version": "1",
    "description": "Pay-per-check discoverability audit: does an AI crawler actually see your site? Signed HTTP audit over the x402 protocol (USDC on Base) — no account, no card, no human.",
    "contact": {
      "name": "abuse",
      "email": "abuse@402registry.com"
    }
  },
  "servers": [
    {
      "url": "https://402registry.com"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "summary": "Landing page",
        "description": "Human-readable landing page: what the service does, current pricing, and machine endpoints.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/html": {}
            }
          }
        }
      }
    },
    "/registry": {
      "get": {
        "summary": "Public registry",
        "description": "Sites that paid for a check and came back \"listed\", newest first. Free, cached, no payment.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/html": {}
            }
          }
        }
      }
    },
    "/docs": {
      "get": {
        "summary": "API guide (JSON)",
        "description": "This document, as machine-readable JSON: quickstart, verdict meanings, current pricing, and the same route list as /openapi.json.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "OpenAPI specification",
        "description": "This OpenAPI 3.1 document.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "summary": "Sitemap",
        "description": "Real HTML pages only: the landing page, and /registry once it has at least one listed site.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/xml": {}
            }
          }
        }
      }
    },
    "/og.png": {
      "get": {
        "summary": "Social preview image",
        "description": "1200x630 PNG used as og:image / twitter:image when a link to this site is shared.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "image/png": {}
            }
          }
        }
      }
    },
    "/.well-known/402registry.json": {
      "get": {
        "summary": "Machine manifest",
        "description": "Service identity, x402 payment protocol details, current packs, and whether the till is open right now.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Liveness probe",
        "description": "Cheap health check for uptime monitors: kill switch state and how long ago the maintenance sweep last ran.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/buy/{pack}": {
      "get": {
        "summary": "Buy a check (x402)",
        "description": "Without a payment header this is a browse request: it answers 402 with the x402 payment requirements for `pack` (and, if `site` is given and accepted, the maximum number of checks that domain can buy). With a valid `PAYMENT-SIGNATURE` (x402 v2) or `X-PAYMENT` (x402 v1) header it is a real purchase: the payment is verified and settled, the site is fetched and checked, and the response carries the verdict and a link to the report.",
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "Which pack to buy.",
            "schema": {
              "type": "string",
              "enum": [
                "one",
                "two",
                "four"
              ]
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "The https URL to check. Required to actually pay; omitted, the response is just the price list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "monitor",
            "in": "query",
            "required": false,
            "description": "Opt in to scheduled re-checks at this cadence. Omit it for a one-off check — nothing is ever re-checked unless you ask. Each scheduled check spends one credit, and monitoring stops when the balance reaches zero. It only starts when the verdict is `listed`; an unknown value is refused before any payment is taken.",
            "schema": {
              "type": "string",
              "enum": [
                "daily",
                "weekly",
                "monthly"
              ]
            }
          }
        ],
        "responses": {
          "402": {
            "description": "x402 payment requirements (browse) or a settled purchase result (paid).",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/r/{id}": {
      "get": {
        "summary": "Check report",
        "description": "The report for a paid check: findings, each with evidence quoted verbatim, and a fix for the detected stack. HTML by default (for the human behind the agent); `?format=json` or `Accept: application/json` returns the same data as JSON. Never indexed by search engines.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "32 lowercase hex characters.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "`json` forces the JSON body regardless of Accept.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/html": {}
            }
          }
        }
      }
    },
    "/api/check": {
      "get": {
        "summary": "Free badge lookup",
        "description": "Looks up a host in the registry by URL. Free, cached, no payment. Unknown host is a normal 200 with `known:false`, not an error.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Any URL on the site to look up; only the host is used.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/badge/{host}": {
      "get": {
        "summary": "Status badge (SVG)",
        "description": "An embeddable status badge. The path segment is the host plus a literal \".svg\" suffix, e.g. \"/badge/example.com.svg\". Free, cached, no payment.",
        "parameters": [
          {
            "name": "host",
            "in": "path",
            "required": true,
            "description": "The host to show, with a literal \".svg\" suffix appended (e.g. \"example.com.svg\").",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "image/svg+xml": {}
            }
          }
        }
      }
    }
  }
}