{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/checkwebsitenow-com/json-schema/checkwebsitenow-com-agent-check-result-schema.json",
  "title": "AgentCheckResult",
  "x-generated": "2026-11-03",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/checkwebsitenow-com-openapi.yml#/components/schemas/AgentCheckResult",
  "type": "object",
  "required": [
    "schema_version",
    "score_name",
    "score_model",
    "official",
    "method_url",
    "target",
    "checked_at",
    "final_url",
    "final_origin",
    "final_url_truncated",
    "duration_ms",
    "requests_used",
    "measurement_region",
    "cached",
    "status",
    "score",
    "score_available",
    "score_unavailable_reason",
    "band",
    "headline",
    "coverage",
    "scaled",
    "caps_applied",
    "groups",
    "checks",
    "deductions",
    "mcp",
    "webmcp",
    "training_policy",
    "disclaimer",
    "summary",
    "findings",
    "limitations"
  ],
  "properties": {
    "schema_version": {
      "const": "2.0"
    },
    "score_name": {
      "const": "CheckWebsiteNow Agent Readability Score"
    },
    "score_model": {
      "type": "string"
    },
    "official": {
      "const": false
    },
    "method_url": {
      "type": "string"
    },
    "target": {
      "type": "string"
    },
    "checked_at": {
      "type": "string",
      "format": "date-time"
    },
    "final_url": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 255
    },
    "final_origin": {
      "type": [
        "string",
        "null"
      ]
    },
    "final_url_truncated": {
      "type": "boolean"
    },
    "duration_ms": {
      "type": "integer",
      "minimum": 0
    },
    "requests_used": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9
    },
    "measurement_region": {
      "type": "string"
    },
    "cached": {
      "type": "boolean"
    },
    "cached_age_seconds": {
      "type": "integer",
      "minimum": 0,
      "description": "Only on cached results: age of the reused result. Normally below 60; up to 300 when a limit refused a fresh check and a recent result was served instead."
    },
    "status": {
      "type": "string",
      "enum": [
        "complete",
        "partial",
        "unavailable"
      ]
    },
    "score": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0,
      "maximum": 100
    },
    "score_available": {
      "type": "boolean"
    },
    "score_unavailable_reason": {
      "type": [
        "string",
        "null"
      ]
    },
    "band": {
      "type": "object",
      "required": [
        "id",
        "label",
        "symbol",
        "min",
        "max"
      ],
      "properties": {
        "id": {
          "type": "string",
          "enum": [
            "hard",
            "partly",
            "good",
            "excellent",
            "not_available"
          ]
        },
        "label": {
          "type": "string"
        },
        "symbol": {
          "type": "string"
        },
        "min": {
          "type": [
            "integer",
            "null"
          ]
        },
        "max": {
          "type": [
            "integer",
            "null"
          ]
        }
      }
    },
    "headline": {
      "type": "object",
      "description": "Plain answer built from the checks, not from the band: can agents read the text (A1, B1), may AI search and assistants read it (A2), and which optional helpers are missing. A low score with text_readable yes means few helpers, not unreadable content.",
      "required": [
        "text_readable",
        "bots_allowed",
        "helpers_present",
        "helpers_missing",
        "text"
      ],
      "properties": {
        "text_readable": {
          "type": "string",
          "enum": [
            "yes",
            "partly",
            "no",
            "unknown"
          ]
        },
        "bots_allowed": {
          "type": "string",
          "enum": [
            "yes",
            "some_blocked",
            "blocked",
            "unknown"
          ]
        },
        "helpers_present": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "helpers_missing": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "text": {
          "type": "string"
        }
      }
    },
    "coverage": {
      "type": "object",
      "required": [
        "measured_points",
        "total_points",
        "percent"
      ],
      "properties": {
        "measured_points": {
          "type": "integer"
        },
        "total_points": {
          "const": 100
        },
        "percent": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        }
      }
    },
    "scaled": {
      "type": "boolean",
      "description": "True when the score is scaled to fewer than 100 measured points."
    },
    "caps_applied": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "search_bots_blocked",
          "javascript_shell"
        ]
      }
    },
    "groups": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "label",
          "weight",
          "measured_points",
          "points",
          "score"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "weight": {
            "type": "integer"
          },
          "measured_points": {
            "type": "integer"
          },
          "unmeasured_points": {
            "type": "integer",
            "description": "weight minus measured_points: points of this group we could not measure (shown as not measured, never as passed)."
          },
          "points": {
            "type": "number"
          },
          "score": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      }
    },
    "checks": {
      "type": "array",
      "minItems": 14,
      "maxItems": 14,
      "items": {
        "$ref": "#/$defs/AgentReadabilityCheck"
      }
    },
    "deductions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "label",
          "lost_points",
          "fix_title"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "lost_points": {
            "type": "number"
          },
          "fix_title": {
            "type": "string"
          }
        }
      }
    },
    "mcp": {
      "type": "object",
      "description": "MCP and API discovery: advertised, not tested. null means not checked.",
      "properties": {
        "api_catalog_found": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "ard_found": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "/.well-known/ard.json (Agentic Resource Discovery v0.91, a proposal) with at least one entry that has identifier, type and exactly one of url/data."
        },
        "ai_catalog_found": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Older /.well-known/ai-catalog.json, read last with leftover request budget."
        },
        "server_card_found": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "openapi_link_found": {
          "type": "boolean"
        },
        "api_catalog_link_found": {
          "type": "boolean"
        },
        "ard_link_found": {
          "type": "boolean",
          "description": "Same-origin rel=\"ard\" link in the homepage HTML or Link header."
        },
        "llms_mentions_api_or_mcp": {
          "type": "boolean"
        },
        "paths_checked": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "endpoints_called": {
          "const": false
        },
        "note": {
          "type": "string"
        }
      }
    },
    "badge": {
      "type": "object",
      "description": "Only when a score exists and badges are configured: a signed 'Agent-ready' badge for this result. The address carries host, score and check date with a server signature; serving it never starts a check and nothing is stored. The link starts a fresh check (utm_source=badge).",
      "properties": {
        "svg": {
          "type": "string",
          "format": "uri"
        },
        "link": {
          "type": "string",
          "format": "uri"
        },
        "html": {
          "type": "string"
        },
        "markdown": {
          "type": "string"
        },
        "checked_on": {
          "type": "string",
          "format": "date"
        },
        "score": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        }
      }
    },
    "homepage_links": {
      "type": "array",
      "description": "Up to 8 main pages suggested from links on the final homepage that are not hidden by markup (CSS-class hiding is not detected): same host, navigation first, no login, cart, legal or file links, paths percent-encoded. Titles are the site's own link text, shortened. Read from the homepage the check already fetched: no extra request.",
      "maxItems": 8,
      "items": {
        "type": "object",
        "required": [
          "title",
          "path"
        ],
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 60
          },
          "path": {
            "type": "string",
            "maxLength": 200
          }
        }
      }
    },
    "lighthouse_rules": {
      "type": "object",
      "description": "Rules from the Lighthouse 13.5.0 audits llms-txt, webmcp-schema-validity, webmcp-form-coverage and ard-schema (ard-schema as a minimal check), re-applied statically to the files this check read. Not a Lighthouse run; never changes the score.",
      "required": [
        "version",
        "lighthouse_run",
        "audits",
        "note"
      ],
      "properties": {
        "version": {
          "type": "string"
        },
        "lighthouse_run": {
          "const": false
        },
        "note": {
          "type": "string"
        },
        "audits": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "id",
              "title",
              "status",
              "score",
              "issues",
              "rule",
              "source_url"
            ],
            "properties": {
              "id": {
                "enum": [
                  "llms-txt",
                  "webmcp-schema-validity",
                  "webmcp-form-coverage",
                  "ard-schema"
                ]
              },
              "title": {
                "type": "string"
              },
              "status": {
                "enum": [
                  "pass",
                  "warning",
                  "fail",
                  "informative",
                  "not_applicable",
                  "unknown"
                ]
              },
              "score": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "rule": {
                "type": "string"
              },
              "source_url": {
                "type": "string",
                "format": "uri"
              },
              "forms": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "uncovered_forms": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        }
      }
    },
    "webmcp": {
      "type": "object",
      "description": "Static WebMCP declarations: declared, not verified in a browser.",
      "properties": {
        "declarative_forms": {
          "type": [
            "integer",
            "null"
          ]
        },
        "complete_declarative_forms": {
          "type": [
            "integer",
            "null"
          ]
        },
        "inline_script_hint": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "runtime_verified": {
          "const": false
        },
        "note": {
          "type": "string"
        }
      }
    },
    "training_policy": {
      "type": "object",
      "description": "Training opt-outs never lower the score.",
      "properties": {
        "training_blocked": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          }
        },
        "tokens_checked": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "note": {
          "type": "string"
        }
      }
    },
    "disclaimer": {
      "type": "string"
    },
    "summary": {
      "type": "object",
      "deprecated": true,
      "description": "Schema 1.0 counts of findings."
    },
    "findings": {
      "type": "array",
      "deprecated": true,
      "minItems": 6,
      "maxItems": 6,
      "items": {
        "type": "object"
      },
      "description": "Schema 1.0 observations (document, structure, robots, llms, metadata, webmcp)."
    },
    "limitations": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "homepage_truncated": {
      "type": "boolean",
      "description": "True when the homepage was larger than 1 MiB and only its first 1 MiB was analysed."
    },
    "homepage_note": {
      "type": [
        "string",
        "null"
      ],
      "description": "Plain-language note when homepage_truncated is true, otherwise null."
    },
    "block_page_signals": {
      "type": "array",
      "description": "Country-block and bot-challenge wording found in the homepage body (input for the geoblock assessment).",
      "items": {
        "type": "object",
        "required": [
          "id",
          "label",
          "confidence",
          "evidence"
        ],
        "properties": {
          "id": {
            "type": "string",
            "enum": [
              "cloudflare_1009",
              "cloudfront_geo",
              "sucuri_country",
              "region_text",
              "cloudflare_challenge",
              "akamai_access_denied"
            ]
          },
          "label": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low",
              "none"
            ]
          },
          "evidence": {
            "type": "string",
            "maxLength": 200
          }
        }
      }
    },
    "homepage_http_status": {
      "type": [
        "integer",
        "null"
      ],
      "description": "HTTP status our GET received for the final homepage (null when it was not read). Compare it with http_status of POST /api/v1/check: when one request was refused (401/403/429) and the other allowed, bot protection treated the two requests differently."
    }
  },
  "$defs": {
    "AgentReadabilityCheck": {
      "type": "object",
      "required": [
        "id",
        "group",
        "label",
        "status",
        "weight",
        "points",
        "evidence",
        "fix"
      ],
      "properties": {
        "id": {
          "type": "string",
          "enum": [
            "A1",
            "A2",
            "A3",
            "B1",
            "B2",
            "B3",
            "B4",
            "C1",
            "C2",
            "C3",
            "C4",
            "D1",
            "D2",
            "D3"
          ]
        },
        "group": {
          "type": "string",
          "enum": [
            "A",
            "B",
            "C",
            "D"
          ]
        },
        "label": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "pass",
            "partial",
            "fail",
            "unknown",
            "not_applicable"
          ]
        },
        "weight": {
          "type": "integer",
          "minimum": 1
        },
        "points": {
          "type": [
            "number",
            "null"
          ],
          "description": "Earned points; null when unknown or not applicable."
        },
        "evidence": {
          "type": "string",
          "maxLength": 256,
          "description": "Counts and our own wording only; never page text."
        },
        "fix": {
          "type": "object",
          "required": [
            "title",
            "detail"
          ],
          "properties": {
            "title": {
              "type": "string"
            },
            "detail": {
              "type": "string"
            },
            "snippet": {
              "type": "string",
              "description": "Copy-ready example for the checked host."
            }
          }
        }
      }
    }
  }
}