{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://api.klarava.app/v1/schema",
  "title": "klarava API Response v1",
  "$comment": "Leading source is docs/openapi.yaml (OpenAPI 3.1 = JSON Schema 2020-12). This file should be generated from it, not maintained in parallel (concept §10).",
  "description": "Response schema of the klarava GEO/AEO API. The 'ai' block is only present on /v1/analyze and /v1/full; /v1/audit does not return it.",
  "type": "object",
  "required": [
    "schema_version",
    "score_version",
    "generated_at",
    "url",
    "final_url",
    "requested_lang",
    "output_lang",
    "pages_checked",
    "status",
    "coverage",
    "confidence",
    "redirected",
    "geo_score",
    "brand_clarity",
    "signals",
    "findings"
  ],
  "additionalProperties": false,
  "properties": {
    "schema_version": {
      "type": "string",
      "const": "1.9",
      "description": "1.9 exposes whether Brand Clarity used only deterministic facts or citation-validated semantic interpretation. The endpoint path stays /v1."
    },
    "score_version": {
      "type": "string",
      "const": "3.34.0",
      "description": "Version of score checks, applicability semantics, and weights. Compare scores only within the same version."
    },
    "generated_at": {
      "type": "string",
      "format": "date-time"
    },
    "url": {
      "type": "string",
      "format": "uri",
      "description": "The requested URL."
    },
    "final_url": {
      "type": "string",
      "format": "uri",
      "description": "URL after redirects."
    },
    "requested_lang": {
      "type": "string",
      "enum": [
        "de",
        "en",
        "auto"
      ],
      "description": "Output language requested by the call (echo)."
    },
    "output_lang": {
      "type": "string",
      "enum": [
        "de",
        "en"
      ],
      "description": "Actual language of the text in this response (for 'auto', resolved from detected_language)."
    },
    "detected_language": {
      "type": "string",
      "description": "Language detected from the website (ISO-639-1, e.g. 'en')."
    },
    "pages_checked": {
      "type": "integer",
      "minimum": 0
    },
    "status": {
      "type": "string",
      "enum": [
        "ok",
        "partial"
      ],
      "description": "Crawl outcome: 'ok' = content sample analyzable, 'partial' = planned pages were unreachable, repeated page shells limited the content assessment, or the homepage main content was empty."
    },
    "coverage": {
      "type": "object",
      "description": "How much of the site was covered.",
      "required": [
        "checked",
        "sitemap_total",
        "sample",
        "clusters"
      ],
      "additionalProperties": false,
      "properties": {
        "checked": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of pages actually crawled."
        },
        "sitemap_total": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of URLs found in the sitemap (0 if none)."
        },
        "sample": {
          "type": "string",
          "enum": [
            "full",
            "sample",
            "unknown"
          ],
          "description": "Sampling state of the page-level checks. 'full' when the sitemap lists no more pages than were checked, 'sample' when it lists more, 'unknown' without a sitemap. Independent of 'confidence', which only reports content readability."
        },
        "clusters": {
          "type": "array",
          "description": "Coverage per content area. URLs from sitemap and internal links are grouped by path template; each row reports how many URLs the area holds and how many were checked. The last row may aggregate the remaining areas.",
          "items": {
            "type": "object",
            "required": [
              "template",
              "total",
              "checked"
            ],
            "additionalProperties": false,
            "properties": {
              "template": {
                "type": "string",
                "description": "Path template of the area, e.g. '/blog/*'."
              },
              "total": {
                "type": "integer",
                "minimum": 0,
                "description": "URLs discovered in this area."
              },
              "checked": {
                "type": "integer",
                "minimum": 0,
                "description": "URLs actually crawled from this area."
              }
            }
          }
        }
      }
    },
    "confidence": {
      "type": "string",
      "enum": [
        "ok",
        "low"
      ],
      "description": "'low' when content was barely readable (JS/SPA) and the assessment may be too strict."
    },
    "redirected": {
      "type": [
        "object",
        "null"
      ],
      "description": "Set when the entered host differs from the final host after redirects, ignoring a leading www. (e.g. example.com -> example.org), else null. A pure apex-to-www or scheme upgrade is not reported.",
      "required": [
        "from",
        "to"
      ],
      "additionalProperties": false,
      "properties": {
        "from": {
          "type": "string",
          "description": "Entered host."
        },
        "to": {
          "type": "string",
          "description": "Final host after redirects."
        }
      }
    },
    "cached": {
      "type": "boolean",
      "description": "true if the response came from cache."
    },
    "geo_score": {
      "$ref": "#/$defs/geoScore"
    },
    "brand_clarity": {
      "$ref": "#/$defs/brandClarity"
    },
    "signals": {
      "$ref": "#/$defs/signals"
    },
    "findings": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/finding"
      }
    },
    "fixes": {
      "type": "array",
      "description": "Deterministic fix drafts for safely identified gaps. Review approval_required and required_inputs before deployment.",
      "items": {
        "type": "object",
        "required": [
          "id",
          "title",
          "code",
          "approval_required",
          "required_inputs"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "description": "Fix kind: robots | noindex | ssr | canonical | sitemap | entity | org | person | faq."
          },
          "title": {
            "type": "string",
            "description": "Localized short title (output_lang)."
          },
          "code": {
            "type": "string",
            "description": "Implementation draft (config, noindex/rendering decision, JSON-LD, or entity alternatives). Apply only after required review."
          },
          "approval_required": {
            "type": "boolean"
          },
          "required_inputs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "ai": {
      "$ref": "#/$defs/ai"
    }
  },
  "$defs": {
    "capabilityAssessment": {
      "type": "object",
      "required": ["status", "confidence", "evidence"],
      "additionalProperties": false,
      "properties": {
        "status": { "type": "string", "enum": ["yes", "no", "unknown"] },
        "confidence": { "type": "string", "enum": ["high", "medium", "low"] },
        "evidence": { "type": "array", "items": { "type": "string" } }
      }
    },
    "severity": {
      "type": "string",
      "enum": [
        "high",
        "medium",
        "low"
      ]
    },
    "tier": {
      "type": "string",
      "enum": [
        "high",
        "mid",
        "low"
      ]
    },
    "coverage": {
      "type": "string",
      "enum": [
        "yes",
        "partial",
        "no"
      ]
    },
    "score": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100
    },
    "geoScore": {
      "type": "object",
      "required": [
        "value",
        "method",
        "max",
        "weighted_earned",
        "weighted_max",
        "weighted_possible"
      ],
      "additionalProperties": false,
      "properties": {
        "value": {
          "$ref": "#/$defs/score"
        },
        "method": {
          "type": "string",
          "enum": [
            "deterministic",
            "llm"
          ]
        },
        "max": {
          "type": "integer",
          "const": 100
        },
        "weighted_earned": {
          "type": "integer",
          "minimum": 0,
          "description": "Weight earned across assessed checks."
        },
        "weighted_max": {
          "type": "integer",
          "minimum": 0,
          "description": "Maximum weight of checks that were assessable for this crawl."
        },
        "weighted_possible": {
          "type": "integer",
          "const": 131,
          "description": "Maximum weight of the complete score definition before applicability exclusions."
        }
      }
    },
    "brandClarity": {
      "type": "object",
      "description": "Second score layer: deterministic on /audit and optionally hybrid on LLM endpoints. It is not assessed without reliable main content.",
      "required": [
        "method",
        "assessed",
        "assessment_reason",
        "value",
        "dimensions",
        "weight_base",
        "weight_possible",
        "findings"
      ],
      "additionalProperties": false,
      "properties": {
        "method": {
          "type": "string",
          "enum": ["deterministic", "hybrid"],
          "description": "deterministic on /audit; hybrid when /analyze or /full applied citation-validated identity interpretation."
        },
        "assessed": {
          "type": "boolean",
          "description": "false when content, sample coverage, or applicability is insufficient; value is then null and findings is empty."
        },
        "assessment_reason": {
          "type": ["string", "null"],
          "enum": ["no_content", "thin_sample", "insufficient_applicability", null],
          "description": "Why the brand score was not assessed; null when assessed is true."
        },
        "value": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "dimensions": {
          "type": "object",
          "required": [
            "facts",
            "sources",
            "people",
            "proof",
            "freshness"
          ],
          "additionalProperties": false,
          "properties": {
            "facts": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 100
            },
            "sources": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 100
            },
            "people": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 100
            },
            "proof": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 100
            },
            "freshness": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 100
            }
          }
        },
        "findings": {
          "type": "array",
          "description": "Per weak dimension: what is structurally missing + a concrete fix.",
          "items": {
            "type": "object",
            "required": [
              "dimension",
              "score",
              "severity",
              "missing",
              "label",
              "fix"
            ],
            "additionalProperties": false,
            "properties": {
              "dimension": {
                "type": "string",
                "enum": [
                  "facts",
                  "sources",
                  "people",
                  "proof",
                  "freshness"
                ]
              },
              "score": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "maximum": 100,
                "description": "null when the dimension could not be assessed."
              },
              "severity": {
                "$ref": "#/$defs/severity"
              },
              "missing": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "label": {
                "type": "string"
              },
              "fix": {
                "type": "string"
              }
            }
          }
        },
        "weight_base": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "Sum of the weights of the assessable dimensions. Below weight_possible when a dimension could not be measured."
        },
        "weight_possible": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "Weight sum with every dimension assessable (1)."
        }
      }
    },
    "signals": {
      "type": "object",
      "description": "Raw, deterministic crawl facts (no AI).",
      "additionalProperties": false,
      "properties": {
        "ai_access": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "blocked": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "All checked AI crawler tokens fully blocked in robots.txt."
            },
            "allowed": {
              "type": "boolean",
              "description": "Backward-compatible aggregate: true only when no checked crawler token is blocked."
            },
            "visibility_allowed": {
              "type": "boolean",
              "description": "True when no supported AI search/retrieval crawler is fully blocked."
            },
            "search_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "user_fetch_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "indirect_search_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "training_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "dataset_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "other_blocked": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "indexable": {
          "type": "object",
          "description": "Raw noindex coverage plus score-relevant content pages and neutral utility pages.",
          "additionalProperties": false,
          "properties": {
            "noindex": {
              "type": "integer",
              "minimum": 0
            },
            "total": {
              "type": "integer",
              "minimum": 0
            },
            "noindex_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            },
            "score_relevant_noindex": {
              "type": "integer",
              "minimum": 0
            },
            "score_relevant_noindex_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            },
            "neutral_utility_noindex": {
              "type": "integer",
              "minimum": 0
            },
            "neutral_utility_noindex_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        },
        "schema_types": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "schema_depth": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "organization": {
              "type": "boolean"
            },
            "logo": {
              "type": "boolean"
            },
            "address": {
              "type": "boolean"
            },
            "contact_point": {
              "type": "boolean"
            },
            "breadcrumb": {
              "type": "boolean"
            },
            "website_search": {
              "type": "boolean"
            },
            "article_date": {
              "type": "boolean"
            },
            "aggregate_rating": {
              "type": [
                "object",
                "null"
              ],
              "description": "Recognized AggregateRating values from schema, or null if absent.",
              "additionalProperties": false,
              "properties": {
                "rating_value": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "review_count": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            }
          }
        },
        "headings": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "one_h1": {
              "type": "boolean"
            },
            "hierarchy_ok": {
              "type": "boolean"
            }
          }
        },
        "head": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "canonical": {
              "type": "boolean"
            },
            "open_graph": {
              "type": "boolean"
            },
            "twitter_card": {
              "type": "boolean"
            }
          }
        },
        "authority": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Linked external authority/entity profiles (sameAs, etc.)."
        },
        "semantics": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "landmarks": {
              "type": "boolean"
            },
            "imgs": {
              "type": "integer",
              "minimum": 0
            },
            "with_alt": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "content": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "thin_pages": {
              "type": "integer",
              "minimum": 0
            },
            "thin_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            },
            "total": {
              "type": "integer",
              "minimum": 0
            },
            "min_words": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "sitemap_xml": {
          "type": "boolean"
        },
        "sitemap_details": {
          "type": "object",
          "description": "Structured evidence for sitemap discovery and validation. Child sitemap checks are capped and report their coverage explicitly.",
          "required": [
            "present",
            "declared",
            "valid_urls",
            "checks",
            "child_sitemaps_discovered",
            "child_sitemaps_checked",
            "child_sitemap_limit"
          ],
          "additionalProperties": false,
          "properties": {
            "present": {
              "type": "boolean"
            },
            "declared": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "valid_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            },
            "checks": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "url",
                  "reachable",
                  "valid",
                  "status"
                ],
                "additionalProperties": false,
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "reachable": {
                    "type": "boolean"
                  },
                  "valid": {
                    "type": "boolean"
                  },
                  "status": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 100,
                    "maximum": 599
                  }
                }
              }
            },
            "child_sitemaps_discovered": {
              "type": "integer",
              "minimum": 0
            },
            "child_sitemaps_checked": {
              "type": "integer",
              "minimum": 0
            },
            "child_sitemap_limit": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "robots_txt": {
          "type": "boolean"
        },
        "llms_txt": {
          "type": "boolean"
        },
        "contact": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "email": {
              "type": "boolean"
            },
            "phone": {
              "type": "boolean"
            },
            "address": {
              "type": "boolean"
            }
          }
        },
        "meta_coverage": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "with_title": {
              "type": "integer",
              "minimum": 0
            },
            "with_meta": {
              "type": "integer",
              "minimum": 0
            },
            "total": {
              "type": "integer",
              "minimum": 0
            },
            "missing_meta_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        },
        "ai_directives": {
          "type": "object",
          "description": "May an AI use/cite the content? (meta robots + X-Robots-Tag + TDMRep)",
          "additionalProperties": false,
          "properties": {
            "noai": {
              "type": "boolean"
            },
            "noimageai": {
              "type": "boolean"
            },
            "nosnippet": {
              "type": "boolean"
            },
            "max_snippet": {
              "type": [
                "integer",
                "null"
              ]
            },
            "tdm_reservation": {
              "type": "boolean"
            },
            "restricted": {
              "type": "boolean"
            }
          }
        },
        "freshness": {
          "type": "object",
          "description": "Recency/date signals (AI prefers fresh, verifiable sources).",
          "additionalProperties": false,
          "properties": {
            "date_published": {
              "type": [
                "string",
                "null"
              ]
            },
            "date_modified": {
              "type": [
                "string",
                "null"
              ]
            },
            "sitemap_lastmod": {
              "type": [
                "string",
                "null"
              ]
            },
            "freshness_days": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0
            },
            "has_visible_updated_date": {
              "type": "boolean"
            },
            "source": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "page",
                "sitemap",
                null
              ],
              "description": "Where the newest date signal came from."
            },
            "source_url": {
              "type": [
                "string",
                "null"
              ],
              "description": "URL of the page that produced the newest date signal; null when it came from the sitemap."
            },
            "dated_pages": {
              "type": "integer",
              "minimum": 0,
              "description": "Checked pages carrying a usable date."
            },
            "archive_pages_excluded": {
              "type": "integer",
              "minimum": 0,
              "description": "Checked pages excluded as archive documents (historic year in the path)."
            },
            "assessable": {
              "type": "boolean",
              "description": "true when a sitemap lastmod or at least two dated pages support a domain-level statement."
            }
          }
        },
        "answer_structure": {
          "type": "object",
          "description": "Is the content usable as an AI answer? (AEO)",
          "additionalProperties": false,
          "properties": {
            "question_headings": {
              "type": "integer",
              "minimum": 0
            },
            "tables_with_headers": {
              "type": "integer",
              "minimum": 0
            },
            "definition_lists": {
              "type": "integer",
              "minimum": 0
            },
            "list_items": {
              "type": "integer",
              "minimum": 0
            },
            "has_summary": {
              "type": "boolean"
            },
            "answerable": {
              "type": "boolean"
            }
          }
        },
        "language": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "html_lang": {
              "type": "string"
            },
            "hreflang_count": {
              "type": "integer",
              "minimum": 0
            },
            "has_x_default": {
              "type": "boolean"
            },
            "multilingual": {
              "type": "boolean"
            },
            "consistency": {
              "type": "boolean"
            }
          }
        },
        "rendering": {
          "type": "object",
          "description": "Is the content in the HTML (SSR) or only via JavaScript (SPA)?",
          "additionalProperties": false,
          "properties": {
            "spa_like": {
              "type": "boolean"
            },
            "home_text_length": {
              "type": "integer",
              "minimum": 0
            },
            "empty_homepage": {
              "type": "boolean"
            },
            "failed_pages": {
              "type": "integer",
              "minimum": 0
            },
            "boilerplate_dominated": {
              "type": "boolean"
            },
            "boilerplate_ratio": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "near_duplicate_pages": {
              "type": "integer",
              "minimum": 0
            },
            "skipped_language_pages": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "source_mix": {
          "type": "object",
          "description": "Source mix (Brand Clarity input): owned/social/authority/people/evidence sources.",
          "additionalProperties": false,
          "properties": {
            "owned_sources": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "social_profiles": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "authority_profiles": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "people_profiles": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "evidence_sources": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "source_diversity": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            }
          }
        },
        "site_archetype": {
          "type": "object",
          "description": "Conservative deterministic website archetype. freelancer means a personal-brand/solo site, not a legal employment status.",
          "additionalProperties": false,
          "required": [
            "type",
            "confidence",
            "evidence",
            "source"
          ],
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "agency",
                "freelancer",
                "saas",
                "software_product",
                "company",
                "unknown"
              ]
            },
            "confidence": {
              "type": "string",
              "enum": [
                "high",
                "medium",
                "low"
              ]
            },
            "evidence": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "source": {
              "type": "string",
              "const": "deterministic"
            }
          }
        },
        "site_capabilities": {
          "type": "object",
          "description": "Deterministic per-requirement applicability. unknown blocks contextual recommendations but does not prove non-applicability; only no can remove a score requirement.",
          "additionalProperties": false,
          "required": ["organization_identity", "personal_brand", "editorial_content", "service_offering", "product_offering", "project_evidence", "review_signals", "public_people", "legal_disclosure", "physical_location", "direct_contact"],
          "properties": {
            "organization_identity": { "$ref": "#/$defs/capabilityAssessment" },
            "personal_brand": { "$ref": "#/$defs/capabilityAssessment" },
            "editorial_content": { "$ref": "#/$defs/capabilityAssessment" },
            "service_offering": { "$ref": "#/$defs/capabilityAssessment" },
            "product_offering": { "$ref": "#/$defs/capabilityAssessment" },
            "project_evidence": { "$ref": "#/$defs/capabilityAssessment" },
            "review_signals": { "$ref": "#/$defs/capabilityAssessment" },
            "public_people": { "$ref": "#/$defs/capabilityAssessment" },
            "legal_disclosure": { "$ref": "#/$defs/capabilityAssessment" },
            "physical_location": { "$ref": "#/$defs/capabilityAssessment" },
            "direct_contact": { "$ref": "#/$defs/capabilityAssessment" }
          }
        },
        "assessment": {
          "type": "object",
          "description": "Applicability basis for page-level content checks. Excluded pages remain part of indexability checks.",
          "required": [
            "content_pages",
            "excluded_pages",
            "checks"
          ],
          "additionalProperties": false,
          "properties": {
            "content_pages": {
              "type": "integer",
              "minimum": 0
            },
            "excluded_pages": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "url",
                  "reasons"
                ],
                "additionalProperties": false,
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "reasons": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "noindex",
                        "utility",
                        "boilerplate_shell",
                        "empty_content"
                      ]
                    }
                  }
                }
              }
            },
            "checks": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "required": [
                  "assessed",
                  "pages"
                ],
                "additionalProperties": false,
                "properties": {
                  "assessed": {
                    "type": "boolean"
                  },
                  "pages": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          }
        },
        "entity_completeness": {
          "type": "object",
          "description": "Structural entity completeness (Brand Clarity input, facts dimension).",
          "additionalProperties": false,
          "properties": {
            "entity_type": {
              "type": "string",
              "enum": [
                "organization",
                "person",
                "unknown"
              ],
              "description": "Deterministic entity type. unknown means no safe type could be inferred."
            },
            "organization_schema": {
              "type": "boolean"
            },
            "name": {
              "type": "boolean"
            },
            "logo": {
              "type": "boolean"
            },
            "address": {
              "type": "boolean"
            },
            "contact_point": {
              "type": "boolean"
            },
            "founding_date": {
              "type": "boolean"
            },
            "management_page": {
              "type": "boolean"
            },
            "press_page": {
              "type": "boolean"
            },
            "impressum": {
              "type": "boolean"
            },
            "score": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            }
          }
        },
        "people_signals": {
          "type": "object",
          "description": "People/management anchors (Brand Clarity input, people dimension). named_people only from Person schema.",
          "additionalProperties": false,
          "properties": {
            "team_page": {
              "type": "boolean"
            },
            "named_people": {
              "type": "integer",
              "minimum": 0
            },
            "roles_visible": {
              "type": "boolean"
            },
            "linkedin_profiles": {
              "type": "integer",
              "minimum": 0
            },
            "spokesperson_contact": {
              "type": "boolean"
            },
            "score": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            }
          }
        }
      }
    },
    "finding": {
      "type": "object",
      "required": [
        "id",
        "tier",
        "severity",
        "label"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable finding ID (contract). Set defined in geoscore.mjs.",
          "enum": [
            "ai_access",
            "indirect_ai_access",
            "indexable",
            "schema_org",
            "authority",
            "sitemap",
            "canonical",
            "one_h1",
            "meta_desc",
            "hierarchy",
            "contact",
            "faq_schema",
            "content",
            "open_graph",
            "semantics",
            "img_alt",
            "llms",
            "ai_directives",
            "ssr",
            "answerable"
          ]
        },
        "tier": {
          "$ref": "#/$defs/tier"
        },
        "weight": {
          "type": "integer",
          "minimum": 0
        },
        "severity": {
          "$ref": "#/$defs/severity"
        },
        "label": {
          "type": "string",
          "description": "Display text (not stable, language-dependent)."
        }
      }
    },
    "dimension": {
      "type": "object",
      "required": [
        "score",
        "evidence",
        "assessed"
      ],
      "additionalProperties": false,
      "properties": {
        "score": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "evidence": {
          "type": "string"
        },
        "assessed": {
          "type": "boolean",
          "description": "False when no reliable evidence supports this dimension; score is then null and excluded from overall."
        }
      }
    },
    "ai": {
      "type": "object",
      "description": "LLM analysis (only /v1/analyze and /v1/full).",
      "required": [
        "overall",
        "dimensions",
        "gaps",
        "query_fanout",
        "ai_summary"
      ],
      "additionalProperties": false,
      "properties": {
        "overall": {
          "$ref": "#/$defs/score"
        },
        "dimensions": {
          "type": "object",
          "required": [
            "identity",
            "offering",
            "audience",
            "differentiation",
            "proof",
            "structure"
          ],
          "additionalProperties": false,
          "properties": {
            "identity": {
              "$ref": "#/$defs/dimension"
            },
            "offering": {
              "$ref": "#/$defs/dimension"
            },
            "audience": {
              "$ref": "#/$defs/dimension"
            },
            "differentiation": {
              "$ref": "#/$defs/dimension"
            },
            "proof": {
              "$ref": "#/$defs/dimension"
            },
            "structure": {
              "$ref": "#/$defs/dimension"
            }
          }
        },
        "gaps": {
          "type": "array",
          "maxItems": 5,
          "items": {
            "type": "object",
            "required": [
              "title",
              "why",
              "fix",
              "severity"
            ],
            "additionalProperties": false,
            "properties": {
              "title": {
                "type": "string"
              },
              "evidence": {
                "type": "string",
                "description": "Verbatim quote from this site (or precise location of what is missing) grounding the gap."
              },
              "why": {
                "type": "string"
              },
              "fix": {
                "type": "string"
              },
              "severity": {
                "$ref": "#/$defs/severity"
              }
            }
          }
        },
        "query_fanout": {
          "type": "array",
          "maxItems": 5,
          "items": {
            "type": "object",
            "required": [
              "query",
              "coverage",
              "evidence"
            ],
            "additionalProperties": false,
            "properties": {
              "query": {
                "type": "string"
              },
              "coverage": {
                "$ref": "#/$defs/coverage"
              },
              "evidence": {
                "type": "string"
              }
            }
          }
        },
        "sample_faq": {
          "type": "string"
        },
        "target_summary": {
          "type": "string"
        },
        "ai_summary": {
          "type": "string"
        }
      }
    }
  }
}
