# Nex Captcha 产品参数模型 API

通过普通 HTTP 获取 MCP `get_product_schema` 的同一份产品契约，供下游动态生成表单、校验参数和选择结果处理流程。覆盖全部已启用产品；免费、只读，不创建任务、不扣款、不调用上游识别。

生产地址：`https://app.nexcaptcha.net`。自部署环境替换为实际服务地址。

## 调用顺序

1. `GET /api/product/list.cgi` 获取当前启用的产品和售价。
2. 优先选择与实际挑战及版本匹配的原生产品，用目录返回的准确 `productCode` 调用 `GET /api/product/schema.cgi`；看到图片网格不代表就该选 GRID。
3. 检查 `code === 0`，读取 `data.schema`、`data.integration` 和 `data.workflowGuide`。
4. 从当前挑战取得真实参数，用完整 Schema 校验 **adapter 对象**。
5. 参数及执行能力都满足时，才通过请求头 API Key 创建付费任务。
6. 查询任务至终态，按产品结果契约回填 Token 字段或回调，或成组替换或提交匹配的挑战标识与证明或答案；独立确认目标验证通过及业务完成。

优先使用原生产品的 `HTTP_SUBMIT` 或 `BROWSER_RESULT`，保持目标会话及要求的绑定条件；不能混用新旧挑战，也不能仅替换图片。GRID 仅在匹配的原生产品或接入方式不可用、且经排查确认后作为备选；HTTP 403、超时或参数错误不能单独作为切换依据。还须取得真实的当前网格图片、原始题目及浏览器交互能力。

GRID 的取图、排队识别、轮询、浏览器点击及多轮换图会增加耗时，可能超过目标挑战有效期；不宜作为时效敏感流程的默认方案，不承诺固定识别时长。应用前检查挑战及图片新鲜度，过期或变化后丢弃旧答案，不自动创建新付费任务。以下 GRID 示例仅用于展示响应格式，不代表推荐的首选产品。

产品可能在获取 Schema 后停用，创建时仍会再次校验。可在一次接入会话内复用模型；新会话、产品切换或遇到产品/参数变更时重新获取，不永久固定目录或模型。

reCAPTCHA 请区分 v2 与 v3、普通版与 Enterprise。普通 v2 的 `recaptchaDataSValue` 和 Enterprise v2 的 `enterprisePayload.s` 不可互换；`pageAction` 不能补足它们。三个 v2 产品新增选填 Cookie/代理上下文，代理条件必填通过 `allOf`、`anyOf`、`not` 表达；v3 不公开这些 v2 字段。旧请求仍可只提供原必填项；`RECAPTCHA_V3_ENTERPRISE` 始终保持 Enterprise 模式。

## hCaptcha 选型

hCaptcha 使用当前启用目录中的 `HCAPTCHA`；没有返回该编码时报告尚未开放，不要猜测编码或自动购买 GRID。首版原生请求只接受 `websiteURL`、`websiteKey`，返回原生 Token；它不是 Google reCAPTCHA，也不是 IMPERVA Cookie 流程。上游 MCP 的 `data/rqdata`、invisible、代理等字段并不自动成为本平台字段；目标要求未支持的上下文时应停止并报告。完整说明见 [/openapi/hcaptcha.md](/openapi/hcaptcha.md)。

## 特定产品的现场判定

Cutcaptcha 当前已核实的是旧版 miseryKey/siteApiKey 协议。加载 `api.cutcaptcha.net/v1/api.js`、只提供 `cc_` sitekey 的新版控件不属于该契约，不能编造旧字段；REST/MCP 会在扣费前拒绝混用。旧域名的网络错误不能代表新 API 状态。

atb 的 `sl` 前缀 Token 是厂商定义的网络异常降级结果，平台将其结算为失败并退还预扣，保留已知上游成本。正常证明格式及字段保持原样。appId 与 apiServer 必须来自同一目标配置，不能把 Dingxiang 的 appId 配到 AISecurius 域名；应确认实际代理可访问该 API。

CaptchaFox 的 `apiServer` 指实际 SDK 资源前缀，并非 challenge/config HTTP API 域名；普通版和 MAM 版的 Token 格式不同。Binance 同一 URL 可能选择原生 bCAPTCHA2 或 reCAPTCHA，必须按当前预检的提供商和版本选产品，不能仅按网站品牌选择 BINANCE。

## 请求示例

```http
GET /api/product/schema.cgi?productCode=GRID HTTP/1.1
Host: app.nexcaptcha.net
Accept: application/json
Accept-Language: zh-CN
```

```bash
curl --get 'https://app.nexcaptcha.net/api/product/schema.cgi' \
  --data-urlencode 'productCode=GRID' \
  --header 'Accept-Language: zh-CN'
```

无需请求体和 API Key。需要使用账户默认语言时，省略语言头并提供 `apiKey: YOUR_API_KEY` 请求头（也支持 `X-API-Key`）。此 Key 仅用于语言偏好，不是读取模型的前提；不得放入 URL、JSON 或表单。余额不足也可以读取模型。

## 响应示例

完整未删减的 GRID 英文响应：[/openapi/examples/product-schema-grid.json](/openapi/examples/product-schema-grid.json)。在线文档的完整响应示例按页面语言展示。以下仅展示常用字段的**投影**，不是完整响应：

```jsonc
{
  "code": 0, // 必须检查业务码，不能只检查 HTTP 200
  "msg": "操作成功", // 展示消息，不作为程序分支
  "data": {
    "productCode": "GRID",
    "schema": {
      "type": "object",
      "required": ["body"],
      "anyOf": [{"required": ["comment"]}, {"required": ["imgInstructions"]}],
      "properties": {
        "body": {"type": "string", "minLength": 1},
        "comment": {"type": "string", "minLength": 1}
      }
    },
    "example": {
      "body": "BASE64_CONTENT", // 替换为实际图片 Base64
      "comment": "Select all images containing stairs." // 替换为当前挑战原始题目
    }
  }
}
```

真实响应还包含下表的 `integration`、`workflowGuide`，以及 Schema 描述和其他约束。复制业务请求时使用标准 JSON，不包含注释。

## 请求参数说明

| 位置 | 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| Query | `productCode` | string | 是 | 目录返回的准确编码，区分大小写。去除首尾空格，空白视为缺失。 |
| Header | `Accept-Language` | string | 否 | `zh-CN`、`zh-TW`、`en-US`；支持 q 权重。 |
| Header | `apiKey` | string | 否 | 未传语言头时用于读取用户语言偏好，也支持 `X-API-Key`。 |

语言优先级：非空 `Accept-Language` → 请求头 API Key 对应用户语言 → `en-US`。不支持的非空语言头直接回落 `en-US`。`X-Language`、URL `lang`、`X-I18n-Cache` 不覆盖此接口。

`msg`、`integration`、`workflowGuide` 的人类可读说明按上述策略选择。产品编码、字段名、枚举、Schema 原始描述和示例值保持原值；不能假设 Schema 的全部文字都随语言变化。

## 响应参数说明

| 字段 | 类型 | 说明 |
|---|---|---|
| `code` | integer | `0` 成功，非零为业务失败。 |
| `msg` | string | 本地化消息；不能依据消息文字判断错误。 |
| `data` | object / null | 成功为产品契约，业务失败为 `null`。 |
| `data.productCode` | string | 规范化后的准确编码。 |
| `data.schema` | object | adapter 的 JSON Schema，本地 `$ref` 已展开，无需下载其他定义。 |
| `data.example` | object | 包含必填字段和首个条件分支的最小占位示例；不是实际挑战。 |
| `data.integration` | object | 产品接入与结果契约，见下表。 |
| `data.workflowGuide` | object | 通用执行流程与失败处理，见后表。 |

### integration

| 字段 | 类型 | 说明 |
|---|---|---|
| `workflows` | string[] | 条件满足时适用的 `HTTP_SUBMIT`、`BROWSER_RESULT`、`BROWSER_INTERACTION`；可能为空。 |
| `readiness` | string | `CONDITIONAL` 为有条件的契约；`DOCUMENTATION_REQUIRED` 表示先补齐文档，不自动推荐付费调用。 |
| `resultKind` | string | 结果类别，需结合 Schema 和使用说明处理。 |
| `resultGuide` | string | 结果使用方式与限制。 |
| `requirements` | string[] | 当前挑战、绑定关系、示例占位等前提。 |
| `inputSources` | object<string,string> | 每个字段应从哪里取得，不应由 AI 猜测。 |
| `resultContract` | string | `DOCUMENTED_FIELDS`、`MODE_SPECIFIC` 或 `UNDOCUMENTED`。 |
| `targetAcceptanceVerified` | boolean | 当前为 `false`，不保证结果已被目标接受。 |
| `resultSchema` | object | 成功时 `solution` 的 Schema，不是整个任务查询响应的 Schema。 |
| `indexBase` | integer，可选 | 如 GRID 格子编号从 `1` 开始。 |
| `order` | string，可选 | 如 GRID 的 `ROW_MAJOR`，从左上角逐行排列。 |

### workflowGuide

| 字段 | 类型 | 说明 |
|---|---|---|
| `title` | string | 流程标题。 |
| `rules` | string[] | 通用规则。 |
| `workflows` | object[] | 每项包含 string 类型的 `id`、`title`、`precondition`、`steps`。 |
| `completionStages` | string[] | `SOLVER_SUCCEEDED` → `CHALLENGE_ACCEPTED` → `BUSINESS_COMPLETED`。 |
| `stageNote` | string | 三层完成状态的区别。 |
| `failures` | object[] | 每项包含 string 类型的 `code`、`nextAction`、`description`。涵盖平台失败与调用方观察的失败。 |
| `labels` | object<string,string> | 本地化界面标签，不用于机器判断。 |

客户端应容忍新增响应字段；机器分支使用编码，不使用翻译后的标签。

## 动态适配规则与示例

- `schema.properties` 决定字段，`type` 决定基础类型，`required` 决定无条件必填。
- 使用标准 JSON Schema 校验器执行完整约束，不能只检查 `required`。必须支持 `oneOf` / `anyOf` / `allOf` / `not`、`additionalProperties`、数组及取值限制。OpenAPI 文档版本为 3.1；返回的 `data.schema` 本身是 JSON Schema，不是 OpenAPI 文档。
- `oneOf` 要恰好匹配一个分支。VK 的图片/链接模式、ALTCHA 的挑战来源不能混在一起提交。
- 所有选填字段从 `properties` 读取，不从最小 `example` 反推字段全集。仅提交实际取得且需要的值，不添加未知字段。
- 校验通过只说明参数结构正确，不证明挑战有效、浏览器能够使用结果或目标一定接受。
- 不返回内部 Adapter Bean、渠道 task type、成本、配置密钥或上游原始响应。

下面 JavaScript 只免费读取模型，不自动创建付费任务。`validateSchema` 由下游标准 JSON Schema 校验器提供，不满足约束时应抛出错误。

```javascript
const base = 'https://app.nexcaptcha.net';
async function readApi(path, headers) {
  const response = await fetch(base + path, { headers });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const result = await response.json();
  if (result.code !== 0) throw new Error(`Nex Captcha ${result.code}: ${result.msg}`);
  return result.data;
}
async function loadContract(productCode, language = 'zh-CN') {
  const headers = { 'Accept-Language': language };
  const products = await readApi('/api/product/list.cgi', headers);
  if (!products.some(p => p.productCode === productCode)) throw new Error('产品未启用');
  return readApi('/api/product/schema.cgi?productCode=' +
    encodeURIComponent(productCode), headers);
}
function buildCreateRequest(contract, adapter, workflowId, validateSchema) {
  if (contract.integration.readiness === 'DOCUMENTATION_REQUIRED') {
    throw new Error('先补齐接入文档');
  }
  if (!contract.integration.workflows.includes(workflowId)) throw new Error('流程不适用');
  // 调用方还须确认 workflowGuide 中的执行前提和自身能力。
  validateSchema(contract.schema, adapter);
  return { productCode: contract.productCode, adapter };
}
const contract = await loadContract('GRID'); // 只读免费查询
console.log(contract.schema, contract.integration.inputSources);
```

准备好真实参数后，`POST /api/validator/create.cgi`：请求头 `apiKey: YOUR_API_KEY`、`Content-Type: application/json`，正文仅 `{ "productCode": "...", "adapter": {...} }`。返回 `data.taskId`。查询 `POST /api/validator/query.cgi` 使用同样请求头，正文 `{ "taskId": "..." }`。

REST 没有 MCP 的 `requestId` 幂等参数，超时后不要自动盲目重建付费任务。`SUCCEEDED` 仅表示识别成功，目标验证和业务完成由下游确认。

## 错误与边界

| code | 含义 | 处理 |
|---|---|---|
| `0` | 成功 | 读取 `data`。 |
| `-1101` | 缺少/空白编码 | 从目录选择。 |
| `-1100` | 无效编码，如 `grid` 或未知编码 | 刷新目录，使用准确编码。 |
| `-1008` | 该编码产品不存在或已停用 | 刷新目录，不创建该产品任务。 |
| `-1001` 等 | 服务异常 | 保留错误信息，稍后重试免费读取。 |

业务失败通常仍是 HTTP 200，例如 `{"code":-1100,"msg":"Invalid parameters","data":null}`。HTTP 403、网关失败、超时及非 JSON 响应须单独处理，不能推断验证码类型或盲目改成 GRID。

`CUSTOM`、`SLIDER_CAPTCHA` 当前为 `DOCUMENTATION_REQUIRED`，不要自动购买。CUSTOM 无确认的上游执行契约，创建在入库及扣费前拒绝。SLIDER_CAPTCHA 保留 body/comment，按官方 CoordinatesTask 修正映射，返回相对原图的 coordinates 像素点；已用自有已知坐标样本验证点位，不把像素点冒称任意第三方滑块的拖动距离或轨迹。VK 图片模式的 steps 是与 image 配对的有序整数数组，不是最大旋转次数；兼容 JSON 数组字符串，不接受单个 "3"。GRID 必须提供正确图片及原始题目，结果为格子编号，不是像素坐标，换图后重新检查。示例不是可移植的“验证码与答案”。

## MCP 对照与机器文档

| HTTP | MCP |
|---|---|
| `GET /api/product/list.cgi` | `list_products`；目录展示字段有所不同。 |
| 此接口的 `data` | `get_product_schema({"productCode":"GRID"})` 的 `structuredContent`；模型、示例、机器字段一致，MCP 说明为规范英文，HTTP 说明按语言策略展示。 |
| 创建正文 `productCode, adapter` | `create_task` 另需 `requestId`。 |
| 查询正文 `taskId` | `get_task` 使用 `id`。 |

OpenAPI 3.1 JSON：[/openapi/nexcaptcha-openapi.json](/openapi/nexcaptcha-openapi.json)，operationId 为 `getProductSchema`，响应定义为 `ProductSchemaResponse` / `ProductSchemaData`。在线文档：[/openapi/docs.cgi#schema](/openapi/docs.cgi#schema)。MCP 仍保持现有五个工具。
