这个端点做什么?
它像爬虫一样抓取一个域名,读取 robots.txt、llms.txt 和 sitemap.xml(如果存在), 然后按站点在 /zh/methodology/ 上说明的同一套公开规则给页面打分。调用者拿到的是分数、12 个维度的结果和问题列表,而不是它们的截图。
GET https://llmention-geo.com/api/scan?domain=example.com
扫描在请求过程中完成,所以对一个冷域名的第一次调用,耗时等于抓取该域名本身的耗时。同一个分析器也支撑着报告页(英文)和已发布的研究,这就是为什么从这里拿到的分数与从界面拿到的分数是同一个数。
它接受哪些参数?
| 参数 | 必填 | 作用 |
|---|---|---|
domain | 是 | 只接受主机名。粘贴进来的 https:// 前缀、路径或查询串会被去掉;www. 前缀也会被移除。 |
brief=1 | 否 | 只返回头部数字——约 300 字节,而不是约 8 KB——不含维度或问题列表。调用者要收集大量域名时,靠它避免为每个域名拉一份完整报告。 |
scope=site | 否 | 增加一个 site 块:首页加上 sitemap 中列出的页面,每一页都由同一个分析器打分,并给出站点平均分和跨页面重复出现的问题。 |
pages=N | 否 | 站点扫描的预算:首页之外的页面数,默认 5,最大 10。提供它会隐含 scope=site。 |
brief=1 与 scope=site 同时发送时,brief=1 优先。这是有意的:精简形式的存在是为了让批量收集便宜,而 site 块是相反的取舍。
响应里包含什么?
完整扫描返回 reachable、status、scheme、browserStatus、scoreBasis、truncated、score、grade、gradeLabel、dimensions、checksRun、checksPassed、pageType、checksNotApplicable、issues 和 metrics。
scoreBasis说明这个分数描述的是什么。页面返回 200 时它是"homepage", 页面没有返回 200 时它是"403 error response"之类——错误响应不是页面, 这个字段的存在就是为了让调用者不会把两者搞混。dimensions承载全部 12 个加权结果,每个都带有已得点数、可得分点数,以及公开的评分理由。issues列出未通过和部分通过的检查,连同产生该结论的证据,以及规则页公布的修复方法。truncated在抓取因大小上限而中止时为 true,此时分数描述的是读到的那部分,而不是整份文档。checksNotApplicable是因页面类型或前提而被排除的规则数量。一个有 1 项被排除的 39/39,不等于 39/40;见方法论。
精简响应长什么样?
这是 example.com 的一个真实响应,采集于 2026-10-23。它不是示意图:运行同一个请求,你应该得到同样的结构。
{
"domain": "example.com",
"status": 200,
"browserStatus": null,
"scoreBasis": "homepage",
"truncated": false,
"score": 16,
"grade": "F",
"checksRun": 40,
"checksPassed": 5,
"aiCrawlersBlocked": false,
"hasJsonLdEntity": false,
"hasSameAs": false,
"hasRobotsTxt": false,
"topIssue": "robots-present",
"pageType": "homepage",
"checksNotApplicable": 1
}速率限制是多少?
一个尽力而为的 isolate 内令牌桶:每个客户端地址每分钟 20 个请求。用尽时端点返回 429, 并带上 Retry-After 响应头。它不是全局限流——Cloudflare 会运行许多 isolate,每个都有自己的计数器—— 所以打算做批量工作的调用者应该自己控制节奏,而不是依赖这个数字。之所以写明这一点,是因为一句准确的警告比一个架构兑现不了的承诺更有用。
它会返回哪些状态码?
| 状态码 | 含义 |
|---|---|
200 | 一个结果。拒绝爬虫的站点仍然返回 200,带 reachable: true 和 status: 403—— 拒绝本身就是结论。 |
400 | 域名不是有效主机名,或拒绝解析到公网地址。响应体带一个 error 字符串。 |
429 | 被限流。按 Retry-After 的值重试。 |
如果两个 scheme 都完全不应答,响应是 200,带 reachable: false、score: 0 和空的问题列表。 无法访问的域名是关于可达性的结果,而不是调用者造成的服务器错误。
这个端点不做什么?
- 它看不见防火墙。这个扫描器发出的请求来自它自己的地址,所以一条针对 bot 的 CDN 规则可以拒绝它,同时照常服务浏览器。 这会被报告为访问类检查的部分结果,而不是通过。
- 它不执行 JavaScript。客户端渲染的页面,按爬虫收到的那样打分。
- 它不向任何 AI 引擎询问任何东西。分数描述的是页面是否可以被引用,而不是它当前是否已经被引用;对比页解释了其中的区别。
- 它不存储扫描内容。没有历史,也没有会丢的密钥。
- 它不是一份有版本的契约。字段可能增加,路由也可能随站点变化;稳定的是公开的方法,而不是 JSON 信封。 如果你要基于它构建,请固定在你读取的字段上,并在每次发布后重新核对。
如何在脚本里调用它?
# Headline result for one domain
curl -s "https://llmention-geo.com/api/scan?brief=1&domain=example.com"
# Full report, including every dimension and issue
curl -s "https://llmention-geo.com/api/scan?domain=example.com" | jq '{score, grade, issues: [.issues[].id]}'
# Homepage plus up to five sitemap pages
curl -s "https://llmention-geo.com/api/scan?domain=example.com&scope=site" | jq '.site.siteScore'参数和响应的实现在 app/api/scan/route.ts,站点扫描的预算在 lib/geo/scan.ts。两者都可读,因为一份无法核对的 API 文档只是一个声明。
可以商用吗?
这个端点免费且无需认证,源码以 MIT 许可发布。没有服务等级协议:这是一个小型独立项目,不是平台; 在循环里调用它,正是速率限制和「没有密钥」所要劝阻的事。批量或代理机构的工作,付费测量报告是受支持的路径——如果你的工作形态不在其中,请发邮件(英文)。
为什么这个端点不在首页上?
因为这个站点面向的是想弄清自己的页面能否被引用的人,而他们中的大多数并不想要一个 JSON 信封。 API 是给那些确实想要的读者——开发者、代理机构,以及任何需要以界面无法服务的规模收集数据的人——提供的同一种测量。 它从工具索引、导航和 /llms.txt 都有链接,所以它不是秘密。
关于扫描 API 的问题
我需要 API 密钥吗?
不需要。端点公开且无需认证,扫描器也不保存扫描历史。速率限制是唯一的门槛,而且它是尽力而为的。
为什么速率限制不精确?
因为它在 Worker isolate 内部执行,而 Cloudflare 会运行许多 isolate。计数器只能阻止单个调用者猛打单个 isolate;它不是全局配额。诚实的限制是公布出来的那个,而不是架构交付不了的数字。
我可以拿到一个站点的每一页吗?
不是每一页。scope=site 读取首页,加上最多十个由 sitemap 列出的页面,逐节挑选;默认是五个。这是一份预算,而不是抽样,响应里会说明考虑了多少页、在哪里截断。
分数和报告页显示的一样吗?
一样。两者都调用同一个分析器、读取同一批支持的资源文件,这也是已发布的研究通过这个端点采集的原因。不同的只是呈现方式,而不是测量。