{"openapi":"3.2.1","info":{"title":"Good for Bots Public Read API","version":"1.0.0","description":"Anonymous, read-only access to published listings, reports and methodology. No API key or account is required. Reads never start scans. Listing entitlements still control report detail and historical access. Response objects may gain fields; clients should ignore unknown fields. Catalogue reads may reuse data for up to one minute, with removal invalidation. Use bounded pagination and back off on failures."},"servers":[{"url":"https://goodforbots.com"}],"security":[],"externalDocs":{"description":"Public API guide","url":"https://goodforbots.com/api"},"paths":{"/api/sites":{"get":{"operationId":"listSites","summary":"Search published listings","description":"Returns published directory entries. Removed, deleted, blocked, opted-out and redirected listings are excluded. Filters combine with AND; repeated category, tag, platform and band values use OR, while capabilities use AND. Unknown well-formed slugs return no matches. Results may change between pages when a scan is published; an out-of-range page returns an empty data array with the real total.","parameters":[{"name":"q","in":"query","description":"Case-insensitive literal substring of host, name or tagline. Whitespace is trimmed.","schema":{"type":"string","minLength":1,"maxLength":120}},{"name":"category","in":"query","description":"Active category slug from /api/categories. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"tag","in":"query","description":"Active tag slug from /api/tags. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"platform","in":"query","description":"Platform slug from /api/sites/facets. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"capability","in":"query","description":"Passed check ID from /api/sites/facets. Repeat for AND: every specified check must pass.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"band","in":"query","description":"Band ID from /api/standards data.rubric.bands. Repeat for OR.","schema":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":4},"style":"form","explode":true},{"name":"status","in":"query","description":"Listing ownership status.","schema":{"type":"string","enum":["unclaimed","claimed"]}},{"name":"minScore","in":"query","description":"Minimum score, inclusive. Must not exceed maxScore.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"maxScore","in":"query","description":"Maximum score, inclusive.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"sort","in":"query","description":"Result order; paid plans never change ranking.","schema":{"type":"string","enum":["score","score-asc","host","recent"],"default":"score"}},{"name":"page","in":"query","description":"Page number.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"limit","in":"query","description":"Entries per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":24}}],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SiteSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"400":{"description":"Invalid parameters. Unknown query names and repeated scalar values are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sites/suggestions":{"get":{"operationId":"suggestSites","summary":"Find existing reports by name or domain","description":"Returns up to five published catalogue identities: host, name and logoUrl. Matches literal host or name text, ignoring case. Exact host matches come first, then exact names, prefixes and substrings; ties use host order. Scores and payments do not affect ranking. The same visibility rules as the directory apply. Reading suggestions never starts a scan.","parameters":[{"name":"q","in":"query","description":"Name or canonical domain fragment. Whitespace is trimmed; wildcard characters are literal.","schema":{"type":"string","minLength":2,"maxLength":120},"required":true}],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"host":{"type":"string"},"name":{"type":["string","null"]},"logoUrl":{"type":["string","null"]}},"required":["host","name","logoUrl"]},"maxItems":5}},"required":["data"]}}}},"400":{"description":"Invalid parameters. Unknown query names and repeated scalar values are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sites/facets":{"get":{"operationId":"getSiteFacets","summary":"Discover filters and counts","description":"Accepts listing filters, but no sort, page or limit. Category counts ignore the selected category; platform counts ignore the selected platform. Signal counts keep every current filter and add the candidate signal. Counts describe listings, not the whole web.","parameters":[{"name":"q","in":"query","description":"Case-insensitive literal substring of host, name or tagline. Whitespace is trimmed.","schema":{"type":"string","minLength":1,"maxLength":120}},{"name":"category","in":"query","description":"Active category slug from /api/categories. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"tag","in":"query","description":"Active tag slug from /api/tags. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"platform","in":"query","description":"Platform slug from /api/sites/facets. Repeat for OR.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"capability","in":"query","description":"Passed check ID from /api/sites/facets. Repeat for AND: every specified check must pass.","schema":{"type":"array","items":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"minItems":1,"maxItems":10},"style":"form","explode":true},{"name":"band","in":"query","description":"Band ID from /api/standards data.rubric.bands. Repeat for OR.","schema":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":4},"style":"form","explode":true},{"name":"status","in":"query","description":"Listing ownership status.","schema":{"type":"string","enum":["unclaimed","claimed"]}},{"name":"minScore","in":"query","description":"Minimum score, inclusive. Must not exceed maxScore.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"maxScore","in":"query","description":"Maximum score, inclusive.","schema":{"type":"integer","minimum":0,"maximum":100}}],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Facets"}},"required":["data"]}}}},"400":{"description":"Invalid parameters. Unknown query names and repeated scalar values are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sites/{host}/report":{"get":{"operationId":"getSiteReport","summary":"Read a published report","description":"Reads an existing report without starting a scan. Use a canonical host from /api/sites: lowercase ASCII/punycode, without scheme, path, port, leading www or trailing dot. Blocked, opted-out and redirected reports can be read by host and have no score. Prompt visibility and historical access follow the listing's plan, independent of the caller. Missing, removed, deleted and never-published listings return 404.","parameters":[{"name":"host","in":"path","required":true,"description":"Canonical hostname, for example example.com.","schema":{"type":"string","maxLength":253}},{"name":"scan","in":"query","description":"Published scan ID belonging to this site. Omit for the latest report. A historical scan requires the listing's history entitlement.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9_-]+$"}}],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Report"}},"required":["data"]}}}},"400":{"description":"Invalid parameters. Unknown query names and repeated scalar values are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The listing's plan does not permit historical reports.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The report or selected scan was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sites/{host}/enrichment":{"get":{"operationId":"getReportEnrichment","summary":"Check report generation status","description":"Reads the current published scan's description and file-generation states without starting work. Poll only while queued, generating or delayed; pause when hidden or offline and back off on errors. An opaque revision changes when content or its status changes. Delayed work has an earliest retry time, not a completion estimate. Files are null without entitlement; the entire result is null for unscored reports. No model, error details, costs or internal job identifiers are exposed. Unknown queries are rejected.","parameters":[{"name":"host","in":"path","required":true,"description":"Canonical hostname.","schema":{"type":"string","maxLength":253}}],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"anyOf":[{"$ref":"#/components/schemas/Enrichment"},{"type":"null"}]}},"required":["data"]}}}},"400":{"description":"Invalid parameters. Unknown query names and repeated scalar values are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The report was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/standards":{"get":{"operationId":"getStandards","summary":"Read the current scoring methodology","description":"Current rubric, score bands, public check descriptions and the AI crawler registry. Historical reports retain their own scoring version. Read band IDs and labels here instead of hardcoding them. Capabilities and experimental checks do not add points.","parameters":[],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Standards"}},"required":["data"]}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/categories":{"get":{"operationId":"listCategories","summary":"List active categories","description":"Active categories, including empty ones, ordered by order then slug. Use slug as the category filter.","parameters":[],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TaxonomyEntry"}}},"required":["data"]}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tags":{"get":{"operationId":"listTags","summary":"List active industry tags","description":"Active tags, including unused ones, ordered by order then slug. Use slug as the tag filter.","parameters":[],"responses":{"200":{"description":"Successful read. JSON responses are not cached by the public proxy.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TaxonomyEntry"}}},"required":["data"]}}}},"502":{"description":"The backend returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The API is temporarily unavailable. Retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"]}}},"required":["error"]},"Pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1},"limit":{"type":"integer","minimum":1,"maximum":100},"total":{"type":"integer","minimum":0},"totalPages":{"type":"integer","minimum":0}},"required":["page","limit","total","totalPages"]},"TaxonomyEntry":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"group":{"type":"string"},"order":{"type":"integer"}},"required":["slug","name","group","order"]},"SiteSummary":{"type":"object","properties":{"host":{"type":"string"},"url":{"type":"string","format":"uri"},"name":{"type":["string","null"]},"tagline":{"type":["string","null"]},"status":{"type":"string"},"latestScore":{"anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"latestBand":{"type":["string","null"]},"latestScoreVersion":{"type":["string","null"]},"latestScannedAt":{"type":["string","null"],"format":"date-time"},"platforms":{"type":"array","items":{"type":"string"}},"hosting":{"type":["string","null"]},"linkRel":{"type":"string"},"category":{"anyOf":[{"$ref":"#/components/schemas/TaxonomyEntry"},{"type":"null"}]},"tags":{"type":"array","items":{"$ref":"#/components/schemas/TaxonomyEntry"}},"capabilities":{"type":"array","items":{"type":"string"},"description":"IDs of passed achievements and capabilities from the published scan."},"logoUrl":{"type":["string","null"]},"ogImageUrl":{"type":["string","null"]},"highlighted":{"type":"boolean"}},"required":["host","url","name","tagline","status","latestScore","latestBand","latestScoreVersion","latestScannedAt","platforms","hosting","linkRel","category","tags","capabilities","logoUrl","ogImageUrl","highlighted"]},"Facets":{"type":"object","properties":{"total":{"type":"integer","minimum":0},"categories":{"type":"object","properties":{"total":{"type":"integer","minimum":0},"items":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/TaxonomyEntry"},{"type":"object","properties":{"count":{"type":"integer","minimum":0}},"required":["count"]}]}}},"required":["total","items"]},"signals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"kind":{"enum":["achievement","capability"]},"count":{"type":"integer","minimum":0}},"required":["id","label","description","kind","count"]}},"platforms":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["slug","name","count"]}}},"required":["total","categories","signals","platforms"]},"Check":{"type":"object","properties":{"checkId":{"type":"string"},"checkVersion":{"type":"integer","minimum":1},"title":{"type":"string"},"label":{"type":"string"},"kind":{"enum":["achievement","penalty","capability"]},"block":{"anyOf":[{"type":"integer","minimum":1,"maximum":2},{"type":"null"}]},"status":{"enum":["pass","warn","fail","na"]},"points":{"type":"number"},"maxPoints":{"type":"number"},"lifecycle":{"enum":["active","experimental","deprecated",null]},"summary":{"type":["string","null"]},"details":{"type":"object","additionalProperties":true,"description":"Check-specific observations; keys vary by check and version."}},"required":["checkId","checkVersion","title","label","kind","block","status","points","maxPoints","lifecycle","summary","details"]},"Fix":{"type":"object","properties":{"checkId":{"type":"string"},"title":{"type":"string"},"kind":{"type":"string"},"status":{"type":"string"},"summary":{"type":["string","null"]},"recoverablePoints":{"type":"number"},"scoreAfter":{"anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"prompt":{"type":["string","null"]},"promptStatus":{"enum":["archived","unavailable"]}},"required":["checkId","title","kind","status","summary","recoverablePoints","scoreAfter","prompt","promptStatus"]},"EnrichmentState":{"type":"object","properties":{"state":{"enum":["queued","generating","delayed","ready","unavailable"]},"nextRetryAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["state","nextRetryAt"]},"Enrichment":{"type":"object","properties":{"scanId":{"type":"string"},"revision":{"type":"string"},"copy":{"$ref":"#/components/schemas/EnrichmentState"},"starterFiles":{"anyOf":[{"$ref":"#/components/schemas/EnrichmentState"},{"type":"null"}]}},"required":["scanId","revision","copy","starterFiles"]},"Report":{"type":"object","properties":{"enrichment":{"anyOf":[{"$ref":"#/components/schemas/Enrichment"},{"type":"null"}]},"accessPolicy":{"anyOf":[{"$ref":"#/components/schemas/AccessPolicy"},{"type":"null"}]},"prerender":{"anyOf":[{"$ref":"#/components/schemas/Prerender","description":"Set when the homepage is a client-rendered app whose host renders full HTML only for crawlers it verifies; the score grades what every other reader receives. Null otherwise and for scans archived before the diagnostic."},{"type":"null"}]},"site":{"type":"object","properties":{"host":{"type":"string"},"url":{"type":"string"},"name":{"type":["string","null"]},"description":{"type":["string","null"]},"status":{"type":"string"},"claimed":{"type":"boolean"}},"required":["host","url","name","description","status","claimed"]},"scan":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"finishedAt":{"type":"string","format":"date-time"},"historical":{"type":"boolean"},"score":{"anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"band":{"type":["string","null"]},"scoreVersion":{"type":["string","null"]},"block1":{"anyOf":[{"type":"number"},{"type":"null"}]},"block2":{"anyOf":[{"type":"number"},{"type":"null"}]},"penalties":{"anyOf":[{"type":"number"},{"type":"null"}]},"cappedAt":{"anyOf":[{"type":"integer","minimum":0,"description":"The score's ceiling when the homepage gave a crawler without a browser nothing to read; the blocks minus penalties then add up to more than the score. Null otherwise."},{"type":"null"}]},"robotsVerdict":{"type":["string","null"]},"summary":{"type":["string","null"]},"redirect":{"anyOf":[{"type":"object","properties":{"host":{"type":["string","null"]},"status":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]}},"required":["host","status"],"description":"Set when status is `moved`: the homepage redirects to another domain, so the scan has no score. The destination's host and the redirect's HTTP status, null for a scripted navigation."},{"type":"null"}]},"stats":{"type":"object","properties":{"pagesScanned":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"requestCount":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"bytesFetched":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"durationMs":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["pagesScanned","requestCount","bytesFetched","durationMs"]}},"required":["id","status","finishedAt","historical","score","band","scoreVersion","block1","block2","penalties","cappedAt","robotsVerdict","summary","redirect","stats"]},"profile":{"anyOf":[{"type":"object","additionalProperties":true,"description":"Observed login, API and commerce features and their evidence."},{"type":"null"}]},"checks":{"type":"array","items":{"$ref":"#/components/schemas/Check"}},"observations":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"url":{"type":"string"},"finalUrl":{"type":["string","null"]},"status":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"contentType":{"type":["string","null"]},"durationMs":{"type":"number"},"rung":{"type":"string"},"redirects":{"type":"integer","minimum":0},"byteLength":{"type":"integer","minimum":0}},"required":["key","url","finalUrl","status","contentType","durationMs","rung","redirects","byteLength"]}},"pages":{"anyOf":[{"type":"object","properties":{"version":{"type":"integer","minimum":1},"completeness":{"enum":["full","partial","empty"]},"stopped":{"type":["string","null"]},"pages":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"kind":{"type":"string"},"sources":{"type":"array","items":{"enum":["previous","sitemap","homepage"]}},"reasons":{"type":"array","items":{"type":"string"}},"outcome":{"type":"string"},"status":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"finalUrl":{"type":["string","null"]}},"required":["url","kind","sources","reasons","outcome","status","finalUrl"]}}},"required":["version","completeness","stopped","pages"],"description":"Content pages sampled besides the homepage and what each answered; null for scans archived before sampling."},{"type":"null"}]},"fixes":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Fix"}},"total":{"type":"integer","minimum":0},"limit":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"hidden":{"type":"integer","minimum":0}},"required":["data","total","limit","hidden"]},"access":{"type":"object","properties":{"history":{"type":"boolean"},"highlight":{"type":"boolean"},"starterFiles":{"type":"boolean"}},"required":["history","highlight","starterFiles"]},"starterFiles":{"anyOf":[{"type":"object","additionalProperties":true,"description":"Plan-dependent generated file drafts and their readiness state."},{"type":"null"}]},"starterFilesOffer":{"type":"boolean"},"links":{"type":"object","properties":{"canonical":{"type":"string"},"markdown":{"type":"string"}},"required":["canonical","markdown"]},"seo":{"type":"object","properties":{"indexable":{"type":"boolean"}},"required":["indexable"]}},"required":["enrichment","accessPolicy","prerender","site","scan","profile","checks","observations","pages","fixes","access","starterFiles","starterFilesOffer","links","seo"]},"AccessPolicy":{"type":"object","properties":{"version":{"const":1},"url":{"type":"string"},"summary":{"type":"string"},"notes":{"type":"array","items":{"type":"string"}},"identities":{"type":"array","items":{"type":"object","properties":{"token":{"type":"string"},"operator":{"type":"string"},"purpose":{"type":"string"}},"required":["token","operator","purpose"]}},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"findings":{"type":"array","items":{"type":"object","properties":{"subjects":{"type":"array","items":{"type":"string"}},"state":{"enum":["allowed","disallowed","observed","not-observed","unknown","unstated","unresolved","mixed"]},"explanation":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"scope":{"type":"string"},"raw":{"type":"array","items":{"type":"string"}},"checkIds":{"type":"array","items":{"type":"string"}}},"required":["subjects","state","explanation","source","url","scope","raw","checkIds"]}}},"required":["id","title","summary","findings"]}}},"required":["version","url","summary","notes","identities","rows"]},"Prerender":{"type":"object","properties":{"version":{"const":1},"platform":{"enum":["lovable"]},"markdownOnRequest":{"type":"boolean"},"title":{"type":"string"},"paragraphs":{"type":"array","items":{"type":"string"}},"sources":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}},"required":["label","url"]}}},"required":["version","platform","markdownOnRequest","title","paragraphs","sources"]},"Band":{"type":"object","properties":{"band":{"type":"string"},"label":{"type":"string"},"min":{"type":"integer","minimum":0,"maximum":100},"max":{"type":"integer","minimum":0,"maximum":100}},"required":["band","label","min","max"]},"Standards":{"type":"object","properties":{"rubric":{"type":"object","properties":{"version":{"type":"string"},"block1Points":{"type":"number"},"block2Points":{"type":"number"},"bands":{"type":"array","items":{"$ref":"#/components/schemas/Band"}}},"required":["version","block1Points","block2Points","bands"]},"badgeExamples":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Band"},{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"capabilities":{"type":"integer","minimum":0}},"required":["score","capabilities"]}]}},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"title":{"type":"string"},"version":{"type":"integer","minimum":1},"reviewedVersion":{"type":"integer","minimum":1},"reviewedOn":{"type":"string"},"specificationStatus":{"type":"string"},"overview":{"type":"string"},"whyItMatters":{"type":"string"},"whatWeCheck":{"type":"string"},"results":{"type":"string"},"limitations":{"type":"string"},"sources":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}},"required":["label","url"]}},"sourceNote":{"type":["string","null"]},"related":{"type":"array","items":{"type":"string"}},"kind":{"enum":["achievement","penalty","capability"]},"checkClass":{"enum":["universal","conditional","capability"]},"lifecycle":{"enum":["active","experimental","deprecated"]},"block":{"anyOf":[{"type":"integer","minimum":1,"maximum":2},{"type":"null"}]},"weight":{"type":"number"},"maxPoints":{"type":"number"}},"required":["id","name","title","version","reviewedVersion","reviewedOn","specificationStatus","overview","whyItMatters","whatWeCheck","results","limitations","sources","sourceNote","related","kind","checkClass","lifecycle","block","weight","maxPoints"]}},"aiCrawlers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"operator":{"type":"string"},"purpose":{"enum":["training","search","user-fetch","agent","extraction"]}},"required":["name","operator","purpose"]},"description":"Compatibility projection of approved scanner identities. Purpose is an engagement scoring group; use crawlerCatalogue for factual uses, aliases and research."},"crawlerCatalogue":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"operator":{"type":"string"},"group":{"type":"string"},"kind":{"type":"string"},"robotsToken":{"type":["string","null"]},"aliases":{"type":"array","items":{"type":"string"}},"httpIdentity":{"type":"string"},"purposes":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"verification":{"type":"string"},"reviewed":{"type":"string"},"sources":{"type":"array","items":{"type":"string"}},"summary":{"type":"string"},"notes":{"type":["string","null"]},"scanner":{"type":"object","properties":{"recognized":{"type":"boolean"},"visibilityPenalty":{"type":"boolean"},"trainingOptOut":{"type":"boolean"}},"required":["recognized","visibilityPenalty","trainingOptOut"]}},"required":["id","name","operator","group","kind","robotsToken","aliases","httpIdentity","purposes","status","verification","reviewed","sources","summary","notes","scanner"]}}},"required":["rubric","badgeExamples","checks","aiCrawlers","crawlerCatalogue"]}}}}