Example
The following result asked for the ai check only, so its ai section is filled and the other sections are null:
{
"domain": "wikipedia.org",
"checks": [
"ai"
],
"scanId": "0b5a7a6e-1f7e-4d7c-9a4e-2f0d8b1c6a11",
"scannedAt": "2026-11-10T09:30:06.000Z",
"complete": true,
"pending": [],
"limited": null,
"finalUrl": "https://www.wikipedia.org/",
"resultUrl": "https://checkanysite.com/site/wikipedia.org?focus=ai",
"versions": {
"signatures": "0.6.1",
"score": "1.1"
},
"ai": {
"level": "none",
"builders": [],
"patterns": []
},
"readiness": null,
"popularity": null,
"tech": null,
"dns": null,
"trust": null,
"score": null,
"summary": null,
"history": null,
"notes": []
}Fields
Every result has the following fields. A section is null when the request didn’t ask for its check. The fields of each section follow.
domainstringThe site’s domain, as we read it ("example.com").
checksarray of one of: ai, readiness, popularity, tech, dns, trust, summary, historyThe checks this result holds: those asked that the scan answered.
scanIdstringThe scan that made this result.
scannedAtdate-timeWhen the scan read the site.
completebooleanFalse while slow sources (
pending) are still being read.pendingarray of stringThe slow sources still being read, if any.
limitedobject or nullSet when the page itself couldn’t be read; the result then comes from outside records.
finalUrlstringThe address the scan ended at, after redirects.
resultUrlstringThe result on our site, with every section and its evidence.
versionsobjectThe signature list and score formula the result was made with (/changelog).
aiobject or nullAI website builder traces (check
ai).readinessobject or nullHow ready it is for AI tools, out of 100 (check
readiness). A result made before we checked AI access takes it from a newer check when there is one (itscheckedAtsays when), and is null otherwise.popularityobject or nullPopularity from public ranked lists (check
popularity).techobject or nullThe technology it runs on (check
tech).dnsobject or nullIts DNS records (check
dns).trustobject or nullTrust signals (check
trust).scoreobject or nullHow established it looks, out of 100 (check
trust, with the signals).summaryobject or nullWhat it is and who is behind it (check
summary).historyobject or nullIts domain’s history (check
history).notesarray of stringLimits of this scan, in plain words.
limited
reasonone of: blocked, robots, privateblocked(bot protection turned us away),robots(robots.txt keeps us out) orprivate(the site asks visitors to sign in).messagestringWhat that means, in plain words.
versions
signaturesstringThe signature list’s version.
scorestringThe score formula’s version.
ai
levelone of: high, medium, nonehigh: an AI builder’s own trace;medium: a combination of its weaker traces only;none: no traces found.buildersarray of objectEach builder whose traces we found; empty when none.
builders[].idstringOur id for the builder ("lovable").
builders[].namestringThe builder’s name ("Lovable").
builders[].kindone of: ai, generalaifor AI builders,generalfor other site builders.builders[].urlstringThe builder’s own site.
builders[].strengthone of: signature, combinationsignature: one trace of its own;combination: weaker traces that count only together.builders[].combinationstring or nullFor a combination, what its traces mean together.
builders[].evidencearray of objectWhere each trace was seen, with the exact line.
builders[].evidence[].wherestringWhere we saw it: "index.html, line 14", "response header", "address".
builders[].evidence[].snippetstringThe element, header or excerpt as it appears.
builders[].evidence[].matchstringThe part of the snippet that matched.
builders[].evidence[].maskedbooleanTrue when email addresses and phone numbers in the snippet are masked.
patternsarray of objectDesign patterns common on AI-built pages; they never set the level on their own.
patterns[].idstringOur id for the pattern.
patterns[].namestringThe pattern’s name.
patterns[].notestringWhy it is weak evidence on its own.
patterns[].evidencearray of objectWhere it was seen.
patterns[].evidence[].wherestringWhere we saw it: "index.html, line 14", "response header", "address".
patterns[].evidence[].snippetstringThe element, header or excerpt as it appears.
patterns[].evidence[].matchstringThe part of the snippet that matched.
patterns[].evidence[].maskedbooleanTrue when email addresses and phone numbers in the snippet are masked.
readiness
answerstringThe answer in a sentence ("Ready for AI: it scores 82 of 100.").
notestringWhat it lets AI crawlers do, in a sentence: the site’s choice, never scored.
scoreinteger or nullOut of 100; null when too little could be checked to say.
versionstringThe readiness formula’s version (/changelog).
checkedAtdate-timeWhen AI access was checked: the scan’s own date, or for a result made before we checked AI access, the newer check that answers in its place.
levelobject or nullThe highest level it reaches; null when it reaches none.
level.idstringThe level’s id ("readable").
level.namestringIts name ("Readable").
level.meaningstringWhat reaching it means, in a sentence.
levelsarray of objectEvery level, lowest first; one counts once its checks and every level before it are met.
levels[].idstringfindable,readable,ai-friendlyoragent-ready; new levels may appear.levels[].namestringThe level’s name.
levels[].reachedbooleanTrue when the site reaches it.
nextobject or nullThe first level not reached and what it needs; null once every level is.
next.idstringThe level’s id.
next.namestringIts name.
next.needsarray of stringThe keys of the checks it still needs, as
checkslists them.comparisonstring or nullWhere the score stands among the most visited sites we read, in a sentence; null without a score.
partialbooleanTrue when some checks couldn’t be made or are still checking; the rest is scaled to 100.
checksarray of objectEach check that counts, as the score reads it.
checks[].keystringA stable key:
text,listing,facts,structured,sitemap,robots,agents(every file for AI agents at once: one found is enough),llms,linksormarkdown; new keys may appear.checks[].groupone of: find, read, agentsfind(can AI find its pages?),read(can AI read it?) oragents(can agents use it?).checks[].labelstringThe check’s name ("Structured data").
checks[].stateone of: found, partial, none, info, unknownfound,partial,none,infoorunknown(we couldn’t check it).checks[].valuestringWhat we found, in words.
checks[].evidencearray of objectWhere it was seen, with the exact line.
checks[].evidence[].wherestringWhere we saw it: "index.html, line 14", "response header", "address".
checks[].evidence[].snippetstringThe element, header or excerpt as it appears.
checks[].evidence[].matchstringThe part of the snippet that matched.
checks[].evidence[].maskedbooleanTrue when email addresses and phone numbers in the snippet are masked.
checks[].pointsintegerThe points it earns.
checks[].maxintegerThe most it can earn.
checks[].metbooleanTrue when it earns its full points.
checks[].uncheckedbooleanTrue when we couldn’t check it, or it is still checking: it is left out of the score.
checks[].optionalbooleanTrue for what few sites have yet; it is worth few points.
checks[].fixobject or nullWhat to do about it; null when it is met or couldn’t be checked.
checks[].fix.gainintegerThe points fixing it would add to the score.
checks[].fix.whystringWhy it matters.
checks[].fix.todostringWhat to do, in a line.
checks[].fix.promptstringA prompt for an AI coding assistant to fix it, with the site’s address and what we found.
fixPromptstring or nullThe fixes that aren’t optional, most points first, as one prompt for an AI coding assistant that ends with where to check again; the optional ones once only they are left. Null when there is nothing to fix.
crawlersarray of objectEvery AI crawler we know, as the site’s robots.txt treats it; never scored.
crawlers[].namestringThe crawler, as its maker writes it ("GPTBot").
crawlers[].companystring or nullThe AI company it belongs to, for those we follow.
crawlers[].roleone of: training, answersWhat it fetches pages for:
trainingmodels, oranswers(AI assistants and AI search).crawlers[].accessone of: out, some, inoutof the whole site, kept fromsomepaths, or letin.crawlers[].lineinteger or nullThe robots.txt line of the group that decides it; null when no group names it.
popularity
bandstringThe best band any list gives the site ("Top 100K"), or "Outside top 1M".
bestRankinteger or nullThe best rank behind the band; null when no list ranks the site.
ranksarray of objectEach list we read, with the site’s rank on it.
ranks[].liststringThe list’s name ("Chrome UX Report").
ranks[].rankinteger or nullThe rank, or null when the list doesn’t rank the site.
ranks[].isBucketbooleanTrue when the rank is the edge of a bucket, not an exact position.
ranks[].rankedAsstring or nullThe parent name the list ranks, when not the site itself.
ranks[].asOfstringWhen the list was produced, as it states it.
ranks[].measuresstringWhat the list counts.
ranks[].urlstringWhere the list is published.
ranks[].licenseobject or nullThe list’s license, when its terms ask for attribution: keep it when you republish.
ranks[].license.namestringThe license’s name ("CC BY 3.0").
ranks[].license.urlstringThe license’s text.
tech
technologiesarray of objectEach technology the site shows, with its evidence.
technologies[].idstringOur id for the technology.
technologies[].namestringIts name ("Next.js").
technologies[].categorystringSuch as "framework", "cms", "analytics", "hosting".
technologies[].evidencearray of objectWhere it was seen, with the exact line.
technologies[].evidence[].wherestringWhere we saw it: "index.html, line 14", "response header", "address".
technologies[].evidence[].snippetstringThe element, header or excerpt as it appears.
technologies[].evidence[].matchstringThe part of the snippet that matched.
technologies[].evidence[].maskedbooleanTrue when email addresses and phone numbers in the snippet are masked.
networkobject or nullA network, never a place: many networks answer from everywhere.
network.asnintegerThe autonomous system number, such as 13335.
network.namestringThe organisation announcing the address ("Cloudflare, Inc.").
network.prefixstring or nullThe routed block holding the address ("104.16.16.0/20").
network.sourcestringWho answered.
network.checkedAtdate-timeWhen we asked.
dns
readbooleanFalse when the lookup failed: then there are no records to give.
recordsarray of objectEach record we read.
records[].namestringThe name asked about: the domain, its www host, or a policy entry such as
_dmarc.records[].typeone of: A, AAAA, CNAME, MX, TXT, NS, CAA, SVCB, HTTPSThe record type. SVCB and HTTPS come only from
_agents, where a site names its AI agents.records[].valuestringThe record’s value, as the resolver gave it.
dnssecboolean or nullWhether the resolver validated the answer with DNSSEC; null when that didn’t answer.
incompletearray of stringThe questions ("example.com TXT") that didn’t answer whole: a record missing from one of them may still exist.
sourcestring or nullThe resolver that answered.
checkedAtdate-time or nullWhen we asked.
networkobject or nullThe network announcing the site’s address, never a place.
network.asnintegerThe autonomous system number, such as 13335.
network.namestringThe organisation announcing the address ("Cloudflare, Inc.").
network.prefixstring or nullThe routed block holding the address ("104.16.16.0/20").
network.sourcestringWho answered.
network.checkedAtdate-timeWhen we asked.
trust
checksarray of objectEach signal we looked for, found or not.
checks[].keystringA stable key such as
privacyPolicyordomainAge; new keys may appear.checks[].labelstringThe signal’s name ("Privacy policy").
checks[].stateone of: found, partial, none, info, unknownfound,partial,none(not found; absence is never an accusation),info(a fact) orunknown(couldn’t check).checks[].valuestringWhat we found, in words.
checks[].kindone of: measured, sourced, interpretedmeasuredby us,sourcedfrom a named source, orinterpretedfrom what we read.checks[].sourcestringWhere it came from: our scan or a named source.
checks[].evidencearray of objectWhere it was seen, when the page or a record shows it.
checks[].evidence[].wherestringWhere we saw it: "index.html, line 14", "response header", "address".
checks[].evidence[].snippetstringThe element, header or excerpt as it appears.
checks[].evidence[].matchstringThe part of the snippet that matched.
checks[].evidence[].maskedbooleanTrue when email addresses and phone numbers in the snippet are masked.
checks[].pendingbooleanTrue while a slow source is still being read.
score
totalinteger or nullOut of 100; null when too little could be read to score fairly.
bandstringThe band the total falls in.
withheldbooleanTrue when too little could be read;
totalis null then.versionstringThe score formula’s version (/changelog).
partsarray of objectThe parts the total is made of, each with its points.
parts[].keystringThe part, such as
transparency,trackRecord,popularity,securityorconsistency.parts[].labelstringThe part’s name.
parts[].pointsnumberThe points it earned.
parts[].maxnumberThe most it could earn from what we could check.
parts[].reasonsarray of stringWhy points were given or withheld, one short phrase each.
parts[].checkedbooleanFalse when none of its inputs could be checked.
missingarray of stringInputs we couldn’t check; the rest is scaled to 100.
summary
titlestring or nullThe page’s own title.
descriptionstring or nullThe page’s own description.
siteNamestring or nullThe name the site gives itself.
languagestring or nullThe page’s language code ("en").
kindobject or nullThe kind of site we read it as (a shop, a blog, an app…); null when unclear.
kind.idstringOur id for the kind ("shop").
kind.labelstringIts name.
kind.confidenceone of: high, mediumHow sure the reading is.
summaryobject or nullAn automatic summary whose quotes we checked against the page; null when there is none.
summary.textstringTwo or three sentences: what the site is and offers, as the page presents it.
summary.categorystringWhat kind of site the model read it as.
summary.offeringsarray of stringWhat it offers, in short phrases.
summary.audiencestring or nullWho it is for, when the page says.
summary.modelstringThe model that wrote it.
summary.writtenAtdate-timeWhen it was written.
identityobject or nullWho is behind the site, by independent sources.
identity.namesarray of objectEach name a source gives for who is behind the site.
identity.names[].namestringThe name as the source gives it.
identity.names[].sourcestringWhere it comes from:
structured data,copyright line,Wikidataorcertificate.identity.agreeingarray of stringThe sources whose names agree, when at least two do.
wikidataarray of objectThe Wikidata items that name the domain as their official website.
wikidata[].idstringThe item’s id ("Q52").
wikidata[].labelstringIts label.
wikidata[].descriptionstring or nullIts short description.
wikidata[].typesarray of stringWhat it is an instance of, in English ("search engine").
wikidata[].inceptionYearinteger or nullThe year it was founded or launched.
wikidata[].urlstringIts page on Wikidata.
socialarray of objectThe profiles the home page links.
social[].networkstringThe network ("github", "linkedin").
social[].handlestringThe account as its address names it ("acme", "company/acme").
social[].urlstringThe profile’s address.
aiPolicyobject or nullWhat the site says about AI crawlers using its content.
aiPolicy.trainingBlockedarray of stringAI training crawlers robots.txt keeps out of the whole site.
aiPolicy.trainingPartlyarray of stringTraining crawlers it gives rules for some paths only.
aiPolicy.assistantsBlockedarray of stringAI assistants (fetching pages for a person) it keeps out of the whole site.
aiPolicy.everyoneBlockedbooleanTrue when every crawler is kept out, AI ones included.
aiPolicy.contentSignalstring or nullIts Content Signals line, as written ("search=yes, ai-train=no").
aiPolicy.noaibooleanTrue when a
noairobots tag or header is set.llmsTxtobject or nullThe site’s llms.txt (llmstxt.org), when it has one.
llmsTxt.urlstringWhere it is.
llmsTxt.titlestringIts title.
llmsTxt.summarystring or nullThe summary it writes for AI assistants.
iconUrlstring or nullOur copy of the site’s icon.
history
registrationobject or nullThe domain registry’s record; null when it couldn’t be read.
registration.registeredAtdate-time or nullWhen the domain was registered; null when the registry doesn’t say.
registration.lastChangedAtdate-time or nullWhen the record last changed.
registration.registrarstring or nullThe registrar, as the registry names it.
registration.recordForstring or nullThe registered name, when the record is for a parent name.
registration.sourcestringThe registry server that answered (RDAP or WHOIS).
registration.checkedAtdate-timeWhen we asked.
firstCertificateobject or nullCertificate Transparency: when a certificate for the domain was first issued.
firstCertificate.firstSeendate-time or nullThe earliest certificate’s start date; null when there were too many to read.
firstCertificate.countinteger or nullHow many certificates the logs list, when read in full.
firstCertificate.sourcestringThe log search that answered.
firstCertificate.checkedAtdate-timeWhen we asked.
archiveobject or nullThe Internet Archive’s record of the site.
archive.firstCapturedate-time or nullThe web archive’s first capture of the site.
archive.firstCaptureUrlstring or nullA link to that capture, to look at.
archive.captureYearsarray of integerThe years with at least one capture, oldest first.
archive.sourcestringThe archive that answered.
archive.checkedAtdate-timeWhen we asked.