ESA AI 付费爬取
验证型(Verification)服务商接入技术规范
本规范面向希望为 ESA 加速站点提供 AI 爬虫付费访问控制 的第三方验证服务商。按本规范实现一个 verify 接口并提交接入参数后,ESA 用户即可在控制台选择你作为服务商、填入接入点(endpoint)与密钥(key)直接接入, 无需 ESA 侧任何定制开发。
1概述
AI 爬虫(GPTBot、ClaudeBot、PerplexityBot 等)对内容站点的抓取量持续增长,而站长(Publisher)缺乏 「按次收费 / 免费放行 / 直接拦截」的精细控制手段。ESA(边缘安全加速)在边缘节点上提供 AI 付费爬取 能力:识别爬虫流量,并按站长配置调用第三方服务商完成 「是否放行、是否扣费」的判定。
ESA 采用 BYOK(Bring Your Own Key)中立集成:平台不绑定任何单一服务商,只定义契约。当前收敛出两大接入标准:
| 标准 | integration_mode | ESA 如何工作 | 定价与账户在谁侧 |
|---|---|---|---|
| 标准一:验证型(本文) | verification | 回源前带外调用你的 verify 接口 → 读判定 → 放行或拦截 | 服务商侧托管站长规则、爬虫账户、计费与余额 |
| 标准二:x402 型 | x402 | ESA 边缘充当 resource server,回 402 + 账单,调 facilitator 的 verify/settle 结算 | 定价在 ESA 侧按规则配置,服务商充当结算 facilitator |
你需要做的三件事
- 实现一个 verify 接口(§5–§8):接收 ESA 的带外调用,返回含
accessGranted的 JSON 判定; - 运营一个自有平台(§10):托管站长规则与定价、爬虫账户注册 / Token 签发 / 余额充值——这些都在你自己的渠道完成,ESA 不参与;
- 把两个参数交付给站长(§11):verify 接口地址(Endpoint)+ 为站长签发的网关密钥(Gateway Key),站长填入 ESA 控制台即接入完成;如需进入控制台服务商下拉列表,可再提交 Provider Profile(§12,可选)。
2角色与架构
| 角色 | 职责 |
|---|---|
| AI 爬虫 / Agent | 抓取内容的一方。在你的平台注册账户、充值余额,请求时携带你签发的爬虫 Token。 |
| ESA 边缘网关 | 收费墙的执行者:在边缘拦截爬虫请求,回源之前带外调用你的 verify 接口,按 accessGranted 放行回源或把 402/403 判定原样透传给爬虫。 |
| 验证服务商(你) | 收费墙的决策者:托管站长规则、爬虫账户、计费与余额,返回「是否放行」的判定。不接触内容本身。 |
| 站长(Publisher) | 内容所有者,同时是 ESA 用户和你的客户:在你的平台配置 URL 规则与定价,在 ESA 控制台填入你的接入点与密钥。 |
图 1 · 总架构:ESA 是执行者(拦截 / 放行 / 透传),服务商是决策者(规则 / 账户 / 计费)。爬虫的注册与充值走服务商自有渠道(虚线 ⑤),与 ESA 无关。
3端到端工作流程
3.1 付费访问(主流程)
图 2 · 付费访问时序:ESA 在回源前带外调用 verify;判定通过(含扣费)才回源取内容。
3.2 四种典型结果
| 场景 | verify 判定 | ESA 行为 | 爬虫看到 |
|---|---|---|---|
| 免费内容(allow 规则 / 未命中规则默认放行) | 200 accessGranted:true,不扣费 | 回源取内容 | 200 + 内容 |
| 付费内容,Token 有效、余额充足 | 200 accessGranted:true + charged | 回源取内容 | 200 + 内容 |
| 付费内容,无 Token / 余额不足 / 价格协商失败 | 402 accessGranted:false + 引导信息 | 把 402 JSON 原样透传 | 402 + 注册 / 充值引导 |
| 站长明确拦截(block 规则) | 403 accessGranted:false | 把 403 JSON 原样透传 | 403(付费也无法解锁) |
3.3 冷启动:陌生爬虫如何自助完成接入
一个从未接触过你平台的爬虫第一次撞上付费墙时,它唯一的信息来源就是你返回的 402 JSON。 只要 402 响应做到「自描述」(§9),爬虫(尤其是 LLM 驱动的 Agent)就能仅凭返回体自主完成 注册 → 充值 → 重试的全流程,无需任何先验知识:
图 3 · 冷启动引导:402 自描述响应 → 爬虫自助注册 / 充值 → 带 Token 重试原 URL → 放行取到内容。
4两层鉴权
verify 接口涉及两层完全独立的鉴权,各管各的事,务必区分:
| 层级 | 载体 | 证明什么 | 签发 / 持有 | 失败返回 |
|---|---|---|---|---|
| 网关层 (server-to-server) | Authorization: Bearer <gateway_key> | 「这个请求真的来自 ESA 网关、且归属哪个站长配置」 | 你签发给接入的站长用户 → 站长填入 ESA 控制台 → ESA 调用时携带 | 401 gateway_unauthorized |
| 爬虫层 (end-user identity) | X-Crawler-Token 头或 body crawlerToken | 「是哪个爬虫在访问」——计费与扣款的主体 | 你签发给注册的爬虫运营方 → 爬虫请求携带 → ESA 透传 | 402 invalid_token |
Authorization。
Authorization 是 HTTP 通用鉴权头,经过 CDN / WAF / 日志平台时容易被记录或改写,且本规范已将其保留给网关层。
爬虫 Token 走自定义头 X-Crawler-Token(头名可在 Provider Profile 中声明映射,§12)。gateway_key 的签发与轮转
- 签发:站长在你的平台开通服务后,由你签发 gateway_key(建议按站点 / 环境隔离),站长自行填入 ESA 控制台。对你而言它同时完成两件事:确认请求经由 ESA、定位站长归属。
- 校验:建议使用固定时间比较(constant-time compare)防时序攻击;失败时返回 401 且不带爬虫引导字段(这是给网关运维看的错误,不是给爬虫看的)。
- 轮转:必须支持同时接受多把有效 key(新旧并存)→ 用户在控制台换新 → 吊销旧 key,全程不中断服务。
5请求规范(ESA → 你,入参)
ESA 对你的接口发起 HTTPS POST 调用,Content-Type: application/json。完整请求示例:
POST /v1/verify HTTP/1.1 Host: verify.example-provider.com Content-Type: application/json Authorization: Bearer <gateway_key> ← 网关层鉴权(§4) X-Crawler-Token: crawler_a1b2c3... ← 爬虫 Token(ESA 从爬虫请求透传) X-Original-Crawler-Agent: Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot) X-Request-Id: req-8c85ba19abef566b ← 可选:全链路对账 ID(§14) { "publisherDomain": "example-news.com", "resourceUrl": "/premium/deep-report.html", "crawlerToken": "crawler_a1b2c3...", "crawlerAgent": "gptbot", "crawlerAutoPrice": true }
5.1 请求头
| Header | 必要性 | 说明 |
|---|---|---|
Authorization: Bearer <gateway_key> | 必需 | 网关层鉴权(§4)。 |
X-Crawler-Token | 建议 | 爬虫身份 Token,ESA 从爬虫原始请求透传。与 body crawlerToken 二选一即可,同时出现时头优先。 |
X-Original-Crawler-Agent | 建议 | 原始爬虫 UA,始终冗余传递(§5.3 双通道)。 |
X-Request-Id | 可选 | 请求关联 ID。你应在响应头原样回写;未提供时可自行生成后回写(§14.3)。 |
5.2 请求体字段
| 字段 | 类型 | 必要性 | 说明 |
|---|---|---|---|
publisherDomain | string | 必需 | 被访问站点的域名(ESA 发来的 Host)。用于定位站长及其规则配置。建议支持「子域归父域」的归属匹配。 |
resourceUrl | string | 必需 | 被访问资源路径(如 /premium/report.html)或完整 URL。用于匹配 URL 规则。 |
crawlerToken | string | 可选* | 爬虫 Token 的 body 通道。已在 X-Crawler-Token 头提供时可省略。完全无 Token 的请求不应拒收——应进入正常判定流程并在付费场景返回 402 + 引导(§9)。 |
crawlerAgent | string | 建议 | 爬虫身份的 body 通道:ESA 已识别 → 填标准化 identifier(如 "gptbot");未识别 → 填原始 UA 字符串(§5.3)。 |
crawlerAutoPrice | boolean | 三选一 | 自动扣费(推荐,一期覆盖绝大多数流量):余额足够即按资源定价直接扣款。 |
crawlerExactPrice | string | 精确价格:格式 "USD 0.10",价格与资源定价完全一致才扣费。 | |
crawlerMaxPrice | string | 预算上限:格式 "USD 0.50",资源定价 ≤ 上限才扣费。 | |
metadata | object | 可选 | 透传的附加元数据(订单号、来源标记等),建议存入访问日志。 |
三个价格字段互斥,同时出现应返回 400。都不出现 = 价格发现模式(§7)。
价格字符串格式建议:^[A-Z]{3}\s+[0-9]+\.?[0-9]*$(如 USD 0.01),不符时返回 400 INVALID_PRICE_FORMAT。
5.3 爬虫身份的双通道传递(为什么不用 User-Agent)
ESA 作为网关转发请求时,标准 User-Agent 会被改写为网关自己的 UA,原始爬虫 UA 会丢失
(与 X-Forwarded-For 保留客户端 IP 是同一个道理)。因此爬虫身份用两个自定义通道传递,互为补充:
| 通道 | 字段 | 内容 | 用途 |
|---|---|---|---|
| Body 字段 | crawlerAgent | ESA 已识别 → 标准化 identifier;未识别 → 原始 UA | 快路径:直接命中已知爬虫类型 |
| HTTP 头 | X-Original-Crawler-Agent | 始终是原始爬虫 UA 字符串 | 审计留痕 + 服务商侧兜底二次识别 |
建议的服务商侧识别顺序:① body identifier 直接命中 → ② body 原始 UA 正则匹配 → ③ header 原始 UA 正则匹配 →
④ 爬虫账户注册时登记的类型 → ⑤ 通用 bot 特征库兜底 → ⑥ unknown。识别结果通过响应的
crawlerIdentification 字段回传(§6.3),便于 ESA 侧统计与站长报表。
6响应规范(你 → ESA,出参)
6.1 核心契约:一个布尔字段
accessGranted。
true → 放行回源;false → 拦截,并把你的响应 JSON 按 statusCode 原样透传给爬虫。
其余字段都是给爬虫 / 站长 / 对账用的增值信息。任何情况下(含 4xx/5xx)都应返回该字段。三条最小合法响应:
// 放行(免费或扣费成功) { "accessGranted": true, "statusCode": 200 } // 需付费(价格发现) { "accessGranted": false, "statusCode": 402, "requiresPayment": true, "error": "price_required", "price": 0.10, "currency": "USD", "onboarding": "https://portal.example-provider.com/guide.html" } // 站长拦截 { "accessGranted": false, "statusCode": 403, "error": "access_blocked" }
6.2 字段总表
| 字段 | 类型 | 必要性 | 说明 |
|---|---|---|---|
accessGranted | boolean | 必需 | 放行 / 拦截的统一判定标志(§6.1)。 |
statusCode | number | 建议 | 回给爬虫的 HTTP 状态码(200 / 402 / 403…),同时也应作为 verify 响应本身的 HTTP 状态码。 |
message | string | 建议 | 人类(和 LLM)可读的一句话结果描述。 |
error | string | 非 200 必需 | 机器可读错误码(§8)。 |
requiresPayment | boolean | 402 建议 | 标记付费可解锁(与 403 的「付费也无法解锁」相区分)。 |
price / currency | number / string | 价格发现必需 | 资源定价与货币代码(ISO 4217,如 USD)。402 响应尽量都带,便于爬虫做预算决策。 |
charged / chargeAmount | boolean / number | 扣费时建议 | 本次是否扣费、扣了多少。ESA 可将其映射到响应头(如 X-Charged / X-Charge-Amount)供爬虫感知。 |
transaction | object | 可选 | 交易凭证 {transactionId, timestamp},审计与争议处理用。 |
crawler | object | 可选 | 爬虫账户快照,如 {balance, required, shortfall}——余额不足时告诉爬虫差多少,转化率关键字段。 |
rule | object | 可选 | 命中的规则摘要 {urlPattern, accessMode, price, billingType},帮爬虫理解计费依据。 |
crawlerIdentification | object | 建议 | 识别结果回传(§6.3)。建议每个响应(含 402/403)都带。 |
onboarding | string (URL) | 402 必需 | 注册 / 充值引导页 URL(§9)。 |
guidance | object | 强烈建议 | 机器可读引导块(§9.2)——冷启动转化率的决定性字段。 |
timestamp | string | 建议 | ISO 8601 处理时间。 |
6.3 crawlerIdentification(识别结果回传)
"crawlerIdentification": {
"recognized": true, // 是否识别出已知爬虫类型
"identifier": "gptbot", // 标准化标识;未识别固定 "unknown"(不要用 null)
"verified": true // 可选扩展:真实性验证(三态 true/false/null)
}verified 是可选的进阶字段:UA 可以伪造,服务商可结合官方公布的爬虫出口 IP 段、
或 Web Bot Auth(RFC 9421 HTTP 消息签名)等机制验真——true=确认真实,false=疑似伪造,
null=无法判断。是否据此拦截由站长策略决定,建议先只标记不拦截。
6.4 完整响应示例(扣费成功)
{
"accessGranted": true,
"statusCode": 200,
"message": "Access granted - payment processed",
"charged": true,
"chargeAmount": 0.10,
"currency": "USD",
"rule": { "urlPattern": "/premium/*", "accessMode": "pay", "price": 0.10, "billingType": "per-request" },
"crawler": { "remainingBalance": 49.90 },
"transaction": { "transactionId": "txn-9f3a-...", "timestamp": "2026-07-23T10:30:00Z" },
"crawlerIdentification": { "recognized": true, "identifier": "gptbot", "verified": true },
"timestamp": "2026-07-23T10:30:00Z"
}7价格意图(Price Intent)
爬虫通过请求体表达「愿意怎么付钱」,你据此在一次调用内完成价格协商与扣费。四种模式:
| 模式 | 请求参数 | 行为 | 典型场景 |
|---|---|---|---|
| 自动扣费 推荐 | crawlerAutoPrice: true | 余额足够即按资源定价直接扣款,一次请求完成支付 | AI Agent 自动化抓取、批量访问。一期支持此模式即可覆盖绝大多数流量 |
| 价格发现 | (不带价格参数) | 不扣费,返回 402 + error: "price_required" + price/currency | 首次探索定价、预算评估 |
| 精确价格 | crawlerExactPrice: "USD 0.10" | 价格与资源定价完全一致才扣费,否则 402 price_mismatch(响应带真实 price 供回填重试) | 两段式确认支付(先发现、再确认) |
| 预算上限 | crawlerMaxPrice: "USD 0.50" | 资源定价 ≤ 上限即扣真实价格,否则 402 price_too_high | 成本控制、防超支 |
// ① 价格发现:不带价格参数 POST /v1/verify { "publisherDomain": "example-news.com", "resourceUrl": "/premium/a.html", ... } // ← 402 { "error": "price_required", "price": 0.10, "currency": "USD", "requiresPayment": true } // ② 确认支付:回填精确价格 POST /v1/verify { ..., "crawlerExactPrice": "USD 0.10" } // ← 200 { "accessGranted": true, "charged": true, "chargeAmount": 0.10 }
INVALID_PARAMETER);
价格字符串格式非法或币种不支持返回 400 INVALID_PRICE_FORMAT。8状态码与错误码
8.1 HTTP 状态码
| 状态码 | 语义 | accessGranted | ESA 行为 |
|---|---|---|---|
| 200 | 放行(免费 / 扣费成功 / 默认放行) | true | 回源取内容 |
| 400 | 参数错误(缺字段 / 互斥冲突 / 价格格式非法) | false | 透传 |
| 401 | 网关鉴权失败(gateway_key 缺失 / 无效) | false | 提示用户检查控制台密钥配置 |
| 402 | 需要付费侧动作(细分见 error) | false | 把 402 JSON 原样透传给爬虫 |
| 403 | 站长明确拦截——付费也无法解锁 | false | 把 403 JSON 原样透传给爬虫 |
| 500 | 服务商内部错误 | false | 按超时 / 故障策略处理(§14.2) |
error: "invalid_token":对爬虫而言这不是「被拒绝」,而是「去注册 / 付费就能解决」——
保持 402 语义单一(付费可解),401 专属网关层,403 专属「付钱也没用」。三者不可混用。8.2 错误码(error 字段)
| 状态码 | error | 含义 | 爬虫的正确反应 |
|---|---|---|---|
| 402 | invalid_token | Token 缺失 / 无效 / 账户禁用 | 按 onboarding / guidance 注册获取 Token |
| 402 | insufficient_balance | 余额不足(建议带 crawler.shortfall 差额) | 充值后重试 |
| 402 | price_required | 付费资源但未携带价格意图(价格发现) | 读 price,带价格意图重试 |
| 402 | price_mismatch | exact 模式价格不一致 | 用响应中的真实 price 回填重试 |
| 402 | price_too_high | max 模式资源定价超预算 | 提升预算或放弃该资源 |
| 403 | access_blocked | 站长 block 规则命中 | 放弃该 URL,不要为它注册 / 充值 |
| 401 | gateway_unauthorized | gateway_key 缺失 / 无效 | (站长 / 运维)检查控制台密钥 |
| 400 | MISSING_REQUIRED_FIELD / INVALID_PARAMETER / INVALID_PRICE_FORMAT | 参数问题 | 修正请求 |
| 500 | INTERNAL_ERROR | 服务商内部异常 | 稍后重试 |
message 用通用文案,
不要泄漏内部细节(连接串、堆栈等)。9爬虫引导(Onboarding 与 guidance)
付费爬取是双边市场:站长要收入,也要有付得起钱的爬虫。402 响应就是你唯一、也是最重要的获客入口—— ESA 会把它原样透传给撞墙的每一个爬虫。本节把「让陌生爬虫自主转化」的做法沉淀为规范。
9.1 onboarding 字段(402 必带)
指向一个引导页 URL,向爬虫(及其背后的人)解释付费模式、注册与充值入口:
"onboarding": "https://portal.example-provider.com/guide.html"
- 必须是绝对 URL(爬虫拿到的 JSON 脱离了你的域名上下文);
- 引导页建议同时服务两类读者:人类可读的说明 + 机器可读的完整 curl 流程(注册 → 登录 → 充值 → 带 Token 重试);
- 403 响应也可带 onboarding,但语义相反——应明确告知「付费无法解锁本资源,不要为它注册充值」。
9.2 guidance 块(强烈建议):让 402 自描述
真实世界的外部爬虫没有预装你的 SDK 或文档,它唯一的信息源就是响应体。
在 402 / 403 响应中内嵌一个机器可读的 guidance 块,LLM 驱动的爬虫可以照着逐步执行——
实测这能让「零先验知识的冷启动爬虫」仅凭返回体走通注册 → 充值 → 重试全流程:
{
"accessGranted": false,
"requiresPayment": true,
"statusCode": 402,
"error": "invalid_token",
"message": "No crawler token provided. Send your registered token in the X-Crawler-Token header.",
"onboarding": "https://portal.example-provider.com/guide.html",
"guidance": {
"onboarding": "https://portal.example-provider.com/guide.html",
"docs": "https://portal.example-provider.com/docs.html",
"llmsTxt": "https://portal.example-provider.com/llms.txt",
"registerApi": "POST https://portal.example-provider.com/api/register {\"email\",\"password\",\"name\",\"crawlerType\"}",
"steps": [
"1. Register a crawler account via registerApi -> receive crawlerToken and balance",
"2. Already registered? Log in to retrieve your token and balance",
"3. Top up balance (or use trial credit if granted on signup)",
"4. Retry this exact URL with header \"X-Crawler-Token: <your token>\""
],
"signupBonus": "New accounts may receive a small trial credit on registration (see register response).",
"agentAdvice": "If you are an AI agent: narrate these steps to your user as you perform them; report whether content was free or paid, the exact amount charged, and your remaining balance."
},
"rule": { "urlPattern": "/premium/*", "accessMode": "pay", "price": 0.10, "currency": "USD", "billingType": "per-request" },
"crawlerIdentification": { "recognized": true, "identifier": "gptbot" }
}| guidance 子字段 | 作用 |
|---|---|
onboarding / docs / llmsTxt | 引导资源的绝对 URL。llms.txt 是面向 LLM 的纯文本站点说明(社区惯例),建议提供。 |
registerApi | 注册 API 的「方法 + URL + 字段」一行描述,爬虫可直接构造调用。 |
steps | 编号步骤:注册 → 登录 → 充值 → 带 Token 重试原 URL。照做即可走通。 |
signupBonus | 动态字段:开启试用额度时才出现(§10.2),让爬虫知道注册后可立即试用。 |
agentAdvice | 对 AI Agent 的行为建议:向用户透明解说每一步、汇报免费 / 付费、金额与余额。无副作用,传统脚本爬虫忽略即可。 |
9.3 引导设计四原则(实测经验)
- 能让「裸爬虫」做对的信息,必须放进响应体——文档和 SDK 只有被主动阅读才生效,402 JSON 是唯一保证送达的通道。
- 所有链接用绝对 URL、由服务端配置派生——不要依赖爬虫猜测你的域名。
- 402 与 403 语义严格分开:402 = 「在售,付费可解锁」;403 = 「站长扣留,付钱也没用」。403 的 guidance 应明确「不要为此 URL 注册充值」,并建议爬虫转向站点上真正可购买的内容(可指向价格清单),避免爬虫误判「付费功能坏了」。
- 余额不足时给出精确差额(
crawler.shortfall),并给「查余额 → 充值 → 重试」的短步骤,而不是重复完整注册流程。
10服务商平台参考架构
verify 接口只是「冰山一角」。要真正提供验证型服务,你需要一个自有平台承载账户、规则与计费。 ESA 不约束你的内部实现,本节给出一个经过生产验证的参考架构,帮助你评估建设范围:
图 4 · 平台参考架构:verify 引擎是对 ESA 的唯一必需接口;站长侧与爬虫侧能力都在你自有渠道运营。
10.1 站长侧:规则与定价系统
| 规则字段 | 说明 |
|---|---|
urlPattern | URL 匹配模式,建议支持 exact(精确)/ prefix(前缀)/ regex(正则)三种类型 |
accessMode | allow(免费放行)/ pay(付费)/ block(拦截,付费不可解锁) |
price / currency | pay 模式的定价。可扩展「按爬虫类型差异化定价」(如训练类爬虫与检索类爬虫不同价) |
billingType | 计费类型:per-request(按次,最常用)起步;时长包 / 订阅可后续扩展 |
priority | 匹配优先级。建议 first-match-wins:按优先级从高到低测试,第一条命中的规则生效 |
- 未命中任何规则的路径建议默认放行(default allow)——付费墙只罩住站长明确圈定的内容,避免误伤站点正常功能页面;也可提供站长级开关改为默认拦截。
- 建议提供批量导入 / 站点内容发现能力(读取站点的 sitemap / 价格清单文件生成候选规则),降低站长配置成本。
10.2 爬虫侧:账户、Token 与充值
| 能力 | 要点 |
|---|---|
| 注册 / 登录 API | 建议对爬虫开放纯 API 注册(邮箱 + 密码即可),并被 402 的 guidance.registerApi 引用——冷启动转化的第一环。注册响应直接返回爬虫 Token 与初始余额。 |
| 两种凭证分离 | 爬虫 Token(长期,随抓取请求走,仅用于 verify 计费)与会话凭证(短期,用于账户管理 API:改密、充值、查流水)分开签发,即使抓取链路泄漏 Token 也不危及账户。 |
| 余额查询 | 建议提供用爬虫 Token 即可调用的只读余额接口——爬虫在抓取途中随时核对余额,无需切换凭证。 |
| 在线充值 | 托管收银台(如 Stripe Checkout 类)即可:创建支付会话 → 返回支付 URL → 人类完成支付 → 余额到账。爬虫拿到 URL 后交给用户支付。 |
| 试用额度(可选) | 注册即送小额试用金(如几美分~几十美分),让爬虫先跑通完整付费闭环再充值,显著提升冷启动转化。必须配套注册限频 / 防薅机制(按 IP、邮箱域名限制),并同步写入交易流水保证对账一致。 |
10.3 verify 引擎:决策流与计费
图 5 · verify 引擎参考决策流:网关鉴权 → 识别爬虫 / 定位站长 → 规则匹配 → 按模式分流 → pay 分支完成 Token、价格意图与余额校验后原子扣费。
UPDATE balance = balance - ? WHERE id = ? AND balance >= ?,受影响行数为 0 即返回 402),
保证任何并发压力下余额不透支、不丢账。10.4 审计与对账
- 每次 verify 调用记访问日志(站长、资源、爬虫、判定结果、金额),扣费同时给爬虫与站长各记一条交易流水;
- 三类记录都存
X-Request-Id(§14.3),与 ESA 侧日志用同一 ID 关联,逐笔对账; - 站长侧提供收入报表(按爬虫类型 / 时间维度),爬虫侧提供消费明细——双边信任的基础。
11服务商接入指南:站长只填两个参数
站长在 ESA 控制台开启「AI 付费爬取」时,只需要填写两个参数——你的 verify 接口地址(Endpoint)和你为他签发的网关密钥(Gateway Key)。 填完即接入完成。之后每一次爬虫请求的拦截、调用 verify、放行回源、402/403 透传,全部由 ESA 自动执行——站长无需再做任何配置,你也无需和 ESA 做任何逐站长的对接。
11.1 站长在 ESA 控制台看到的界面(示意)
路径:ESA 控制台 → 站点 → 安全 / Bot 管理 → AI 付费爬取 → 开启 → 验证型服务商。配置界面就是下面这两个输入项:
ESA 控制台配置界面示意(静态展示,非真实表单)。站长填完这两项,收费墙即刻生效。
11.2 两个参数分别是什么
| 参数 | 是什么 | 谁提供 / 在哪拿 | 示例 |
|---|---|---|---|
| Endpoint 验证服务地址 |
你按本规范 §5–§8 实现并公网部署的 verify 接口的完整 HTTPS 地址。ESA 每拦截到一个爬虫请求,就 POST 这个地址要判定。 | 由你(服务商)提供:写在你的接入文档里,或在站长开通服务后展示在你的后台。所有站长共用同一个地址,按环境可以不同(测试 / 生产各一个)。 | https://verify.example-provider.com/v1/verify |
| Gateway Key 网关密钥 |
你为这一个站长签发的密钥。ESA 调用 verify 时放在 Authorization: Bearer 头里,对你同时完成两件事:证明请求真的来自 ESA、定位这是哪个站长的配置(§4)。 |
站长在你的平台注册开通后,由你签发并展示(如你后台的「API 密钥」页),站长自行复制到 ESA 控制台。一站长一密钥,建议按站点 / 环境隔离,必须支持轮转(§4)。 | esa_gw_9f8a7b6c5d4e3f2a1b0c(格式由你定义,建议带可识别前缀) |
11.3 接入三步(服务商视角)
- 实现并部署 verify 接口(§5–§8 契约)→ 得到你的 Endpoint;
- 站长在你的平台开通服务(注册、配规则与定价)→ 你为其签发 Gateway Key;
- 站长把这两个参数填入 ESA 控制台 → 接入完成。运行时 ESA 需要的其余一切信息(站点 Host、资源路径、原始爬虫 UA、爬虫 Token)都取自边缘请求本身并自动传给你(§5),规则与价格改动在你侧实时生效。
12Provider Profile(可选进阶:进入控制台下拉列表)
§11 的接入方式不需要向 ESA 提交任何材料。Provider Profile 是可选的进阶步骤,解决两件事:
- 品牌进入控制台服务商下拉列表:用户选择你后 Endpoint 自动带出,只需填 1 个密钥,体验更顺、更有品牌露出;
- 字段映射:你的存量接口头名 / 字段名与本规范默认值不同时,在 Profile 里声明映射,ESA 适配层自动转换,无需你改造已有接口。
| 接入形态 | 站长在控制台填什么 | 前提 |
|---|---|---|
| 自定义接入(§11) | Endpoint + Gateway Key(两项) | 严格实现本规范默认契约 |
| 内置下拉(本节) | 仅 Gateway Key(Endpoint 自动带出) | 向 ESA 提交 Provider Profile |
Profile 是一份声明「怎么调用我」的 JSON 模板:
{
"provider": "your-brand",
"integration_mode": "verification",
"verify_endpoint": "https://verify.example-provider.com/v1/verify",
"auth": { "scheme": "bearer", "key_field": "gateway_key" },
"headers": {
"crawler_token": "X-Crawler-Token", // 你实际使用的头名
"original_agent": "X-Original-Crawler-Agent"
},
"request_body": {
"publisher_field": "publisherDomain",
"resource_field": "resourceUrl",
"auto_price_field": "crawlerAutoPrice"
},
"response": {
"granted_field": "accessGranted",
"status_field": "statusCode",
"onboarding_field": "onboarding"
}
}| 字段 | 说明 |
|---|---|
provider | 服务商标识(控制台下拉展示名另行提供品牌资料)。 |
verify_endpoint | verify 接口地址,控制台自动带出(用户可改,便于测试环境)。 |
auth | 网关层鉴权方式。当前支持 bearer;key_field 是控制台向用户索取的密钥字段名。 |
headers / request_body / response | 头名与字段名映射。不声明则使用本规范默认名。 |
随 Profile 一并提交:品牌名与 Logo、引导页 / 文档 URL、技术联系人、测试环境 Endpoint 与测试密钥(供 ESA 联调验收,§13)。
13接入 Checklist 与验收测试矩阵
13.1 接入 Checklist
| # | 项 | 级别 |
|---|---|---|
| 1 | 提供 HTTPS POST verify 接口,任何情况下返回含 accessGranted 的 JSON | MUST |
| 2 | 校验 Authorization: Bearer <gateway_key>,失败返回 401 gateway_unauthorized;支持多 key 并存轮转 | MUST |
| 3 | 从 X-Crawler-Token 头 / body 取爬虫身份并计费;无 Token 不拒收,走 402 引导 | MUST |
| 4 | 支持 crawlerAutoPrice 自动扣费;402 响应携带 onboarding | MUST |
| 5 | block 场景返回 403 access_blocked,与 402 语义严格区分 | MUST |
| 6 | 错误码遵循 §8.2;扣费原子无透支(§10.3) | MUST |
| 7 | 支持价格发现 / exact / max 三种价格意图;响应带 crawlerIdentification;回写 X-Request-Id | SHOULD |
| 8 | 402/403 内嵌 guidance 引导块(§9.2);提供纯 API 注册与余额查询 | SHOULD |
| 9 | 向 ESA 提供测试环境 Endpoint / 密钥完成联调;如需进下拉列表另提交 Provider Profile(§12) | MUST |
13.2 验收测试矩阵:12 种返回值
以下矩阵覆盖 verify 接口的全部返回值组合。联调验收时逐条触发并断言——一条脚本即可自测契约完备性:
| # | 状态码 | error | 触发条件 | 如何构造 |
|---|---|---|---|---|
| 1 | 200 | — | 命中 allow 规则 | verify 一个配置为 allow 的路径 |
| 2 | 200 | — | 未命中任何规则(默认放行) | verify 一个未配置规则的路径 |
| 3 | 200 | — | 付费扣费成功 | pay 路径 + crawlerAutoPrice:true + 余额充足,断言余额精确减少 |
| 4 | 402 | invalid_token | Token 缺失 / 无效 / 禁用 | 不带 X-Crawler-Token 打 pay 路径,断言含 onboarding |
| 5 | 402 | insufficient_balance | 余额 < 价格 | 零余额账户打 pay 路径,断言 crawler.shortfall |
| 6 | 402 | price_required | pay 路径不带价格意图 | 断言返回 price / currency |
| 7 | 402 | price_mismatch | exact 价格与定价不一致 | crawlerExactPrice 填错误价格 |
| 8 | 402 | price_too_high | max 预算 < 定价 | crawlerMaxPrice 填低于定价的预算 |
| 9 | 400 | INVALID_PRICE_FORMAT | 价格字符串非法 | crawlerExactPrice: "notaprice" |
| 10 | 403 | access_blocked | 命中 block 规则 | verify 一个配置为 block 的路径(带有效 Token 也应 403) |
| 11 | 401 | gateway_unauthorized | 网关 key 缺失 / 错误 | 错误的 Authorization: Bearer 值 |
| 12 | 500 | INTERNAL_ERROR | 服务内部异常 | 黑盒不可稳定触发,代码审计确认兜底路径即可(文档化覆盖) |
X-Request-Id;#4 的 402 响应中 guidance.steps 可被 LLM 爬虫照做走通(冷启动实测)。14运维与工程建议
14.1 时延预算
verify 处在边缘请求的关键路径上(回源前同步等待),你的时延直接叠加在终端用户 / 爬虫的响应时间上:
- 目标建议:p50 < 100ms、p99 < 500ms(含网络往返),接入点尽量部署在靠近 ESA 节点的区域;
- 热路径只做必要工作:规则匹配走索引,识别用缓存,避免在 verify 里做外部同步调用;
- 纯决策类判定(allow / block / 参数错误)应在 10ms 量级返回。
14.2 故障与超时语义
- ESA 侧对 verify 调用设有超时与故障策略(fail-open 直接放行 / fail-close 拦截,以 ESA 产品配置为准)。你无法假设自己「挂了会怎样」,唯一可控的是快速、明确地返回;
- 内部异常返回 500 +
INTERNAL_ERROR,accessGranted:false——不要悬挂连接; - 5xx 的
message用通用文案,内部细节只进你自己的日志。
14.3 X-Request-Id 与对账
POST /v1/verify X-Request-Id: req-8c85ba19abef566b ← ESA 可选自带 ... HTTP/1.1 200 OK X-Request-Id: req-8c85ba19abef566b ← 你原样回写;ESA 未带时自行生成后回写
- 该 ID 贯穿你侧访问日志 + 双边交易流水,与 ESA 侧日志按同一 ID 逐笔对账;
- 建议约定:重试复用同一 ID——为将来的幂等扣费(同 ID 不重复扣款)留好接口,网络重试不会导致双扣。
14.4 安全清单
- gateway_key、爬虫 Token 一律走 HTTPS;密钥支持轮转(§4);
- 爬虫 Token 与账户会话凭证分离(§10.2);
- 开启试用额度必须配套注册限频(按 IP / 邮箱),防批量薅取;
- 对 verify 接口做基础速率限制与异常流量监控(防伪造 ESA 流量刷你的账本),以 gateway_key 未配置时段的灰度兼容为例外;
- 金额使用定点数(DECIMAL)存储与比较,避免浮点误差。
14.5 上线路径建议
- 按 §13.2 矩阵在你的测试环境自测 12 种返回值全通过;
- 向 ESA 提供测试 Endpoint / 密钥完成联调(ESA 侧用测试站点触发真实边缘链路);进下拉列表的再提交 Provider Profile;
- 灰度:先在测试站点开启,观察时延 / 判定分布 / 对账一致性;
- 正式进入控制台服务商列表。