API 概览
通过统一的 REST API,将 ChatGPT 订阅激活接入你的业务。从套餐查询、卡密校验到任务提交与结果追踪,为服务端集成提供清晰、完整的接口约定。
接入准备#
开始前,请准备已签发的 API Key、有效卡密,以及目标 ChatGPT 账号的完整 Session JSON。API Key 和 Session 仅应由你的服务端安全处理。
基础信息#
| 配置项 | 值与说明 |
|---|---|
| 接口地址 | https://www.academicgate.org |
| 版本 | v1(路径内定版,见 13. 版本策略) |
| 认证 | X-API-Key 请求头 |
| 传输 | HTTPS only,TLS 1.2+ |
| 编码 | 请求与响应均为 application/json; charset=utf-8 |
| 自助激活页 | https://www.academicgate.org/store(可直接转给终端用户,用户无需 API Key;支持 Plus / Pro 5x / Pro 20x / Pro 500,见 8.3) |
POST /api/v1/gptplus/redeem 提交 card_code + session_data 拿到 task_id,再每 3 秒 GET /api/v1/gptplus/task/{task_id} 直到 finished: true。轮询中若出现 action_required 字段,按 5.6 安全验证 让用户完成一次验证。接口一览#
围绕订阅激活组织的全部接口。选择接口查看完整说明。
/api/v1/pingGET套餐目录/api/v1/productsGET服务状态/api/v1/gptplus/statusGET查询卡密使用情况/api/v1/gptplus/cdk-info?code=PLS-XXXXXXXXXXXXXXXXPOST提交激活任务/api/v1/gptplus/redeemGET查询任务结果/api/v1/gptplus/task/{task_id}GET任务记录查询/api/v1/gptplus/jobs?limit=50&offset=0&card_code=&status=&product=下一步#
快速开始
export API_KEY="aisub_你的Key"
export BASE="https://www.academicgate.org"
# 1) 校验 Key 是否可用
curl -s "$BASE/api/v1/ping" -H "X-API-Key: $API_KEY"
# 2) 看支持哪些套餐(别把卡密前缀硬编码在你那边)
curl -s "$BASE/api/v1/products" -H "X-API-Key: $API_KEY"
# 3) 提交激活(session_data 为 https://chatgpt.com/api/auth/session 的完整 JSON)
curl -s -X POST "$BASE/api/v1/gptplus/redeem" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"card_code":"PLS-XXXXXXXXXXXXXXXX","session_data":{"accessToken":"eyJ...","user":{"email":"[email protected]"}}}'
# 4) 轮询结果(每 3 秒一次)
curl -s "$BASE/api/v1/gptplus/task/替换为task_id" -H "X-API-Key: $API_KEY"套餐与卡密
档位由卡密前缀自动判定,请求中无需也不应包含任何档位参数。 把卡密原样传入即可,系统会识别其所属套餐并按相应方式处理。
这样设计是为了杜绝一类事故:档位一旦由调用方指定且指定错误,会被计为一次有效提交,直接消耗卡密次数且不可退。交由前缀判定则从根本上不存在这种可能。
| 套餐 | product | 卡密前缀 | 示例 | 凭据 |
|---|---|---|---|---|
| ChatGPT Plus | gpt_plus_self | PLS- | PLS-XXXXXXXXXXXXXXXX | Session JSON |
| ChatGPT Pro 5x | gpt_pro_5x_self | P5X- | P5X-XXXXXXXXXXXXXXXX | Session JSON |
| ChatGPT Pro 20x | gpt_pro_20x_self | P20X- | P20X-XXXXXXXXXXXXXXXX | Session JSON |
| ChatGPT Pro 20x 续费 | gpt_pro_20x_renew | PH20- | PH20-XXXX-XXXX-XXXX | Session JSON |
| ChatGPT Pro 500 | gpt_pro_500_self | P500- | P500-XXXXXXXXXXXXXXXX | Session JSON |
这张表以 GET /api/v1/products 的实时返回为准。套餐与卡密前缀可能调整,接口会先于文档更新,请按接口返回做提示与分流,不要在你的代码里写死前缀列表。此前发放的其他前缀卡密仍可正常兑换,但不会出现在目录里——本地校验只做提示、不要据此拒收,以服务端返回为准(格式不对返回 invalid_card_format,不消耗卡密)。
套餐选用说明#
- Plus / Pro 5x / Pro 20x:卡密前缀
PLS-/P5X-/P20X-。Plus 仅支持当前无生效订阅的账号;Pro 20x(2026-09-30 起支持新开):无订阅账号可直接开通,也支持已有生效菲区(PHP) Plus / Pro 5x 的账号升级(无需先取消原订阅;非菲区计费返回plus_not_ph_region、卡密不消耗);Pro 5x 额外支持已有生效 ChatGPT Plus 的账号(自动升级为 Pro 5x,无需先取消 Plus;仅限菲律宾区 PHP 的 Plus,非菲区 Plus 返回plus_not_ph_region、卡密不消耗)。其余不符合的账号(如已是 Pro 5x/更高档、或非 Plus 的付费订阅)会被拒绝(account_has_subscription),卡密不消耗。 - Pro 20x 开通条件:支持三类账号——① 无订阅的账号(免费版);② 已有生效的菲区(PHP) Plus;③ 已有生效的菲区(PHP) Pro 5x(②③ 自动升级,无需先取消)。已是生效 Pro 20x 的账号请到期后再续费;官方暂未对其开放 Pro 20x 的账号返回
account_not_eligible_pro20(较少出现),卡密不消耗。 - Pro 500 开通条件:卡密前缀
P500-。仅支持无任何订阅的免费账号,且不是升级产品——不支持从 Plus / Pro 5x / Pro 20x / Go / Team 升级,也没有补差价;已取消续订但未到期的账号同样视为有订阅,会被拒绝(account_has_subscription,卡密不消耗)。账号若已有计费币种且不是菲律宾(PHP),返回promax_billing_not_php。P500-卡密为人工发货,不提供在线购买,详见 2.4 Pro 500 开通说明。
所有套餐的共同前提#
- 目标账号当前不能有生效中的付费订阅(例外:Pro 5x 也接受已有生效 Plus 的菲区账号,Pro 20x 也接受已有生效 Plus / Pro 5x 的菲区账号,自动升级)。提交时会先校验账号当前的订阅状态,其它有生效订阅的账号立即返回
account_has_subscription(卡密不消耗)。已取消续订、但订阅尚未到期的账号同样视为有生效订阅(Plus 卡密需等订阅到期后再提交);订阅已过期的账号视为无订阅,可以正常开通。Pro 500 是方向相反的例外、条件更严:任何订阅都不接受,也没有升级路径(见 2.4)。 session_data必须是目标 ChatGPT 账号的完整 Session JSON,且含accessToken。- 提交后到出结果前,该账号需保持在浏览器中的登录态,否则 Session 会失效导致任务失败。
重复充值保护#
对同一个 ChatGPT 账号反复充值不会叠加时长,只会覆盖当前订阅,而卡密照常消耗且不退。为此我们在提交环节做了拦截,按距上次成功充值的时间分两档:
| 距上次成功充值 | 行为 | error |
|---|---|---|
| 24 小时以内 | 直接拒绝,confirm_duplicate 也不放行 | duplicate_email_blocked |
| 24 小时 ~ 30 天 | 拒绝并要求确认,带 confirm_duplicate: true 重发即可放行 | duplicate_email_confirm |
| 超过 30 天 | 正常放行 | — |
两者都返回 HTTP 409,响应体带上次记录(24 小时内的拒绝另带 blocked: true,需确认的另带 need_confirm: true;下例为需确认的情形):
{
"success": false,
"error": "duplicate_email_confirm",
"detail": "This account was already topped up on 2026-09-14 08:51:21 …",
"detail_zh": "该账号最近已充值过…",
"duplicate": true,
"last_product": "ChatGPT Plus",
"last_product_zh": "ChatGPT Plus",
"last_at": "2026-09-14 08:51:21",
"hours_ago": 77.83,
"need_confirm": true
}判定按邮箱 + 任意 GPT 套餐:该账号充过 Plus 之后再充 Plus 同样会命中,因为只要账号还有生效中的订阅,充任何档位都会失败或覆盖。升级(Plus→Pro 5x、Plus / Pro 5x→Pro 20x)不触发判重。Pro 500 不属于升级,同样适用判重。
need_confirm 时,把 last_product 与 last_at 展示给你的终端用户,由他确认后再带 confirm_duplicate: true 重发;不要在代码里无条件自动重发,那等于把这道保护关掉了。blocked 则应直接告知用户并终止,不要重试。判重覆盖我们的全部入口(本 API、自助激活页、我们自己的激活页),所以同一个账号在别处充过也会被识别到。
Pro 500 开通说明#
P500-(Pro 500)的规则与其它套餐不同,对接前请单独确认:
- 账号条件:仅限无任何订阅的免费账号。Plus / Pro 5x / Pro 20x / Go / Team、已取消续订但未到期、欠费的账号一律拒绝(
account_has_subscription),不提供升级与补差价;账号计费地区非菲律宾(PHP)返回promax_billing_not_php。提交时如果暂时读不清账号的订阅状态,同样拒绝(precheck_failed),不会放行。以上拒绝都发生在受理之前,卡密不消耗。 - 开通方式:先为账号开通一个基础档(Plus),再升级到 Pro 500,全程由我们自动完成;成功后我们会自动关闭自动续费。正因为分两步,升级失败时账号可能已停留在基础档(见下方「失败处理」)。
- 获取方式:
P500-卡密为人工发货,不提供在线下单,目录与接口也不返回价格。请联系我们按代理价获取;拿到卡密后,本 API 与自助激活页都可以兑换。 - 排队:Pro 500 在整个系统内同一时间只处理一单,我们自己的激活页、自助激活页和所有经销商共用这一条队列;处理中的 Pro 500 在调用引擎的那一小段,也可能让 Pro 5x / Pro 20x 任务短暂排队。任务受理后可能长时间停在
queued(数分钟甚至更久),这是正常排队而不是故障,请继续轮询、不要重提;单笔耗时也比其它套餐长,且不固定。建议轮询间隔 3–5 秒,等待上限至少 20 分钟,超时后转低频复查或联系我们,不要判失败。 - 同账号并发:提交 Pro 500 时,如果该账号已有
PLS-/P5X-/P20X-/P500-卡密的任务在受理 / 排队 / 处理中(不分入口与经销商),新提交返回409 account_busy,卡密不消耗;请等原任务结束后再提交。 - 失败处理(重要):Pro 500 失败后不要自动重提。
promax_upgrade_incomplete(基础档已开通、升级未成功)与payment_unverified(付款结果待核实)都表示请勿重复提交、请联系我们人工处理——此时账号已是基础档,重提会因账号已有订阅被拒绝。这与 Pro 20x 的upgrade_incomplete(可用同一卡密重提)含义相反,请分开处理,见 7.3。其余失败码以 7.3 的「处置」列为准。 - 失败冻结:同一账号计费类失败连续 2 次、任何原因失败连续 3 次将暂停提交,规则与其它套餐相同,见 7.3。
认证与安全
每个请求都要带 Key。两种写法等价:
X-API-Key: aisub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAuthorization: Bearer aisub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKey 由我们签发,形如 aisub_ + 32 位随机串。一个 Key 对应一个客户,所有流水按 Key 归属隔离——你只能查到自己提交的任务。
对接方安全要求#
以下是对接的最低要求,不是建议:
- Key 只存在于你的服务端。 放进浏览器、App、小程序或任何客户端等同于公开泄露。
- 不要把 Key、完整卡密、Session JSON、accessToken 写进日志。 需要排查时记录
task_id,它不含敏感信息。 - 出口 IP 固定的话请告知我们,可以为你的 Key 开启 IP 白名单。
- 怀疑泄露请立刻联系我们停用并换发。旧 Key 停用后所有请求立即返回
401。 - Key 不设有效期,但建议按贵方密钥轮换周期定期换发。
请求与响应约定
成功响应#
顶层恒有 success: true 与 client_name,业务字段平铺在同一层:
{
"success": true,
"client_name": "示例客户",
"task_id": "a1b2c3d4e5f64789abcd1234",
"status": "queued"
}错误响应#
同时判断 HTTP 状态码和响应体的 success 字段,不要只看其中一个。
{
"success": false,
"error": "invalid_card_format",
"detail": "Activation key format is invalid. Please check that the key is complete (including dashes).",
"detail_zh": "卡密格式不正确,请核对卡密是否完整(含横线)"
}| 字段 | 说明 |
|---|---|
error | 机器可读错误码,程序分支只认这个字段,不要匹配文案 |
detail | 英文说明,可直接展示给终端用户 |
detail_zh | 中文说明,可直接展示给终端用户 |
时间与字符#
- 所有时间为 UTC,格式
YYYY-MM-DD HH:MM:SS。 - 卡密大小写不敏感,服务端统一转大写后处理。
- 请求体必须是 JSON 对象;非法 JSON 返回
400 invalid_json_body。
频率限制#
按 Key 计算,滑动窗口:
| 类别 | 接口 | 限额 |
|---|---|---|
| 提交类 | POST /api/v1/gptplus/redeem | 60 次 / 分钟 |
| 查询类 | 其余全部 GET | 600 次 / 分钟 |
超限返回 429 rate_limited。请做指数退避(1s → 2s → 4s,上限 30s)后重试,但提交类接口例外,见 4.5。
重试语义(必读)#
redeem 不是幂等接口。提交成功即消耗一次卡密次数,重复提交等于再消耗一次,不可退。本接口没有 idempotency key。因此:
| 情况 | 正确做法 |
|---|---|
返回 2xx 并拿到 task_id | 存下 task_id,只轮询,不重发 |
返回 4xx(参数 / 卡密 / 格式类错误) | 卡密未被消耗,修正后可以重发 |
返回 429 | 未被消耗,退避后重发 |
返回 5xx / 502 / 网络超时 / 无响应 | 不要直接重发。 先用 GET /api/v1/gptplus/cdk-info?code=<卡密> 或 GET /api/v1/gptplus/jobs?card_code=<卡密> 确认任务是否已经建立;建立了就去轮询,确实没建立才重发 |
查询类接口都是只读的,可以放心重试。
提交的耗时与超时:redeem 在受理前要核验账号订阅状态,通常数秒,最坏约 80 秒才返回;请把提交请求的客户端超时设为 ≥ 90 秒(设 60 秒会比服务端先超时)。超时或收到 502 upstream_error 时,我们这边可能已经建单——先按上表查证(jobs / cdk-info)。若任务确已建立,用同一张卡密重提会得到 409 card_in_progress(带 job_id,即原 task_id),不会产生第二单;但不要换另一张卡密去提交同一个账号。
接口参考
浏览订阅激活的完整接口。所有请求通过 HTTPS 发送,并在请求头中携带 API Key。
校验 API Key
/api/v1/ping无参数。用于对接自检与健康探测。
响应示例#
{ "success": true, "message": "pong", "client_name": "示例客户" }套餐目录
/api/v1/products返回当前在售的全部套餐与卡密前缀。建议启动时拉一次并缓存,用它做界面分流与输入提示;目录之外的前缀交给服务端判定,不要在本地拒收。目录含 Pro 500(P500-),其 note / note_zh 写明了账号条件与排队说明;目录不返回价格。
响应示例#
{
"success": true,
"client_name": "示例客户",
"total": 5,
"items": [
{
"product": "gpt_plus_self",
"name": "ChatGPT Plus",
"name_zh": "ChatGPT Plus",
"key_prefix": "PLS-",
"key_sample": "PLS-XXXXXXXXXXXXXXXX",
"credential": "session_json",
"note": "Only accounts without an active subscription can be activated.",
"note_zh": "仅支持当前无订阅的账号开通。"
}
]
}服务状态
/api/v1/gptplus/status充值服务的实时可用性。建议在展示下单入口前调用,available 为 false 时先拦下用户,别让卡密提交进维护窗口。
响应示例#
{
"success": true,
"client_name": "示例客户",
"available": true,
"tier": "ready",
"label": "Operational",
"label_zh": "服务正常",
"tone": "ok",
"pending": 0,
"wait_seconds": 0,
"checked_at": "2026-09-17 10:10:50"
}请求参数#
| 字段 | 取值 | 含义 |
|---|---|---|
available | true / false | false 表示维护中,此刻不要提交 |
tier | ready / busy / down | busy 表示排队较多,仍可提交但耗时更长 |
pending | 整数 | 兼容保留字段,目前恒为 0,不反映排队情况 |
wait_seconds | 整数 | 兼容保留字段,目前恒为 0 |
结果有 20 秒服务端缓存,无需高频调用。该接口只反映充值服务整体是否可用,不反映单个任务的排队位置(尤其是 Pro 500 的单车道排队),请以任务自身的 status 为准。
查询卡密使用情况
/api/v1/gptplus/cdk-info?code=PLS-XXXXXXXXXXXXXXXX请求参数#
| 参数 | 必填 | 说明 |
|---|---|---|
code | 是 | 卡密。亦接受 card_code 或 cdk |
提交前先调这个,能挡掉绝大多数"卡密已用过"的客诉。
响应示例#
{
"success": true,
"client_name": "示例客户",
"product": "gpt_plus_self",
"product_name": "ChatGPT Plus",
"product_name_zh": "ChatGPT Plus",
"card_key": "PLS-XXXXXXXXXXXXXXXX",
"status": "unused",
"redeemable": true,
"total": 0,
"success_count": 0,
"running_count": 0,
"records": []
}| 字段 | 说明 |
|---|---|
status | unused 未使用 / running 充值中 / used 已成功用掉 |
redeemable | 当前是否可提交。为 false 时不要提交 |
records | 该卡密的历史记录,最多 20 条;其中账号邮箱按隐私要求打码 |
提交激活任务
/api/v1/gptplus/redeem请求参数#
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
card_code | string | 是 | 卡密。亦接受 cdk / cdk_code |
session_data | object | string | 是 | 目标账号完整 Session JSON,须含 accessToken。亦接受 session / session_json;传字符串时服务端会解析 |
confirm_duplicate | bool | 否 | 仅在收到 duplicate_email_confirm 后使用,表示用户已确认覆盖。默认 false,详见 2.3 重复充值保护 |
请求中不要包含任何档位参数,传了也会被忽略——档位一律按卡密前缀判定。
提交耗时:受理前会先核验账号状态,通常数秒,最坏约 80 秒才返回,客户端超时请设为 ≥ 90 秒(详见 4.5)。成功返回只代表已受理(queued),不代表已开通,结果以轮询为准;Pro 500 受理后可能排队较久,见 2.4。
请求示例#
{
"card_code": "P20X-XXXXXXXXXXXXXXXX",
"session_data": {
"accessToken": "eyJhbGciOi...",
"user": { "email": "[email protected]" },
"expires": "2026-12-16T00:00:00.000Z"
}
}成功返回 200:
响应示例#
{
"success": true,
"client_name": "示例客户",
"product": "gpt_pro_20x_self",
"product_name": "ChatGPT Pro 20x",
"product_name_zh": "ChatGPT Pro 20x",
"task_id": "a1b2c3d4e5f64789abcd1234",
"status": "queued",
"message": "Accepted",
"message_zh": "已受理",
"card_key": "P20X-XXXXXXXXXXXXXXXX",
"email": "[email protected]",
"submitted_at": "2026-09-17 10:12:00"
}成功响应不含 duplicate 字段;重复提交在提交阶段拦截(返回 duplicate_email_blocked / duplicate_email_confirm,见 2.3)。
查询任务结果
/api/v1/gptplus/task/{task_id}只能查到本 Key 提交的任务,查别人的返回 404 task_not_found。
响应示例#
{
"success": true,
"client_name": "示例客户",
"product": "gpt_plus_self",
"product_name": "ChatGPT Plus",
"task_id": "a1b2c3d4e5f64789abcd1234",
"status": "success",
"finished": true,
"message": "Activation completed",
"message_zh": "充值成功",
"error_code": "",
"duration_seconds": 142.6,
"card_key": "PLS-XXXXXXXXXXXXXXXX",
"email": "[email protected]",
"submitted_at": "2026-09-17 10:12:00"
}请求参数#
| 字段 | 说明 |
|---|---|
status | queued / running / success / failed |
finished | status 为 success 或 failed 时为 true,轮询以此为终止条件 |
message / message_zh | 状态说明;失败时为失败原因,可直接展示给终端用户 |
error_code | 仅失败时非空,取值见 7. 错误码;卡密是否消耗、能否重提以 7.3 为准 |
duration_seconds | 任务结束后才出现:本次处理耗时(秒),不含排队等待 |
activation_email | 保留字段,恒为空串;账号邮箱请看 email |
action_required | 仅在需要用户本人完成一次安全验证时出现,取值 manual_captcha(见下方「安全验证」) |
verification_url | 与 action_required 同时出现,我方托管的验证页地址 |
verification_expires_at | 验证有效截止时间(Unix 秒),过期后该字段消失、任务转失败 |
轮询建议:每 3 秒一次;单笔通常 1–3 分钟完成。上限建议 15 分钟(约 300 次);Pro 500 单车道排队、耗时更长,上限请至少 20 分钟(见 2.4)。超时后不要判失败,转为低频复查或人工跟进。等待用户完成验证的时间不要计入超时。
安全验证:少数订单在处理中需要用户本人完成一次安全验证,此时响应形如:
响应示例#
{
"success": true,
"status": "running",
"finished": false,
"action_required": "manual_captcha",
"verification_url": "https://www.academicgate.org/verify/a1b2c3d4e5f64789abcd1234",
"verification_expires_at": 1790000000
}status仍是running(不是成功)。把verification_url交给这笔订单的用户:在你的 HTTPS 页面用 iframe 嵌入(建议referrerpolicy="no-referrer")或新窗口打开。- 用户完成后继续轮询原
task_id,以success/failed为准;关闭窗口不代表成功。链接过期后如出现新链接再展示。 - 不要因此重新提交;验证链接只给这笔订单的用户,不要写进日志或转给无关第三方。
任务记录查询
/api/v1/gptplus/jobs?limit=50&offset=0&card_code=&status=&product=你名下的任务流水,用于对账与超时找回。
请求参数#
| 参数 | 默认 | 说明 |
|---|---|---|
limit | 50 | 1–200 |
offset | 0 | 分页偏移 |
card_code | — | 按卡密精确过滤 |
status | — | 按状态精确过滤,取值见 6. 任务状态机 |
product | — | 按套餐过滤,取值见 GET /api/v1/products 的 product |
响应示例#
{
"success": true,
"client_name": "示例客户",
"total": 128,
"limit": 50,
"offset": 0,
"items": [
{
"task_id": "a1b2c3d4e5f64789abcd1234",
"card_key": "PLS-XXXXXXXXXXXXXXXX",
"product": "gpt_plus_self",
"product_name": "ChatGPT Plus",
"product_name_zh": "ChatGPT Plus",
"status": "success",
"message": "Activation completed",
"email": "[email protected]",
"created_at": "2026-09-17 10:12:00",
"updated_at": "2026-09-17 10:14:31",
"finished_at": "2026-09-17 10:14:31"
}
]
}任务状态机
┌──────────┐
redeem ─────▶│ queued │ 已受理,等待处理
└────┬─────┘
▼
┌──────────┐
│ running │ 充值处理中
└────┬─────┘
┌─────────┴─────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ success │ │ failed │ ← 均为终态,finished: true
└──────────┘ └──────────┘- 状态只会向前推进,不会从终态回退。
rejected只出现在流水接口(5.7)里,表示请求在进入处理队列前就被拒绝、未消耗卡密次数;它不会作为task接口的status返回。- 流水接口(5.7)里还可能见到另外两种仅属于流水的状态:
submitting(提交已收到、任务尚在建立的短暂占位,最长约 3 分钟,随后转入其它状态)与reset(我们人工重置过的记录,卡密是否可再用请以cdk-info为准,有疑问请联系我们)。task接口的status只会是queued/running/success/failed。 - Pro 500 在
queued阶段可能停留较久(全系统单车道排队),这不是故障,见 2.4。 - 终态之后再轮询会持续返回同一结果,不产生副作用。
running期间可能要求用户做一次安全验证(响应带action_required)。这不是新状态,完成后照常走到终态,见 5.6。
错误码
程序分支只认 error 字段。
认证与配额#
| HTTP | error | 含义 | 处置 |
|---|---|---|---|
| 401 | missing_api_key | 未带 Key | 检查请求头拼写 |
| 401 | invalid_api_key | Key 无效或已停用 | 联系我们 |
| 403 | key_not_allowed | 该 Key 无权调用此接口 | 联系我们换发正式 Key |
| 429 | rate_limited | 超出频率限制 | 指数退避重试 |
参数与卡密#
| HTTP | error | 含义 | 处置 |
|---|---|---|---|
| 400 | invalid_json_body | 请求体不是 JSON 对象 | 检查 Content-Type 与序列化 |
| 400 | missing_card_code | 未传卡密 | — |
| 400 | invalid_card_format | 卡密前缀不在支持列表内 | 比对 GET /api/v1/products |
| 400 | missing_session | 未传 session_data | — |
| 400 | invalid_session_json | Session 不是合法 JSON 对象 | 让用户重新完整复制 Session 页面 |
| 400 | session_missing_access_token | Session 缺 accessToken | 用户未登录 ChatGPT 或只复制了片段 |
| 400 | missing_task_id | 未传 task_id | — |
| 404 | task_not_found | 任务不存在或不属于本 Key | 核对 task_id |
| 409 | duplicate_email_blocked | 该账号 24 小时内已充值过 | 终止并告知用户,不要重试 |
| 409 | duplicate_email_confirm | 该账号 30 天内已充值过,需确认 | 让用户确认后带 confirm_duplicate: true 重发 |
| 400 | product_not_supported_here | 该卡密类型暂不支持在此处激活(例如对应套餐的入口临时关闭) | 卡密未消耗;联系我们 |
充值业务错误#
以下出现在 redeem 的错误响应(带 HTTP 状态码),或 task 的 error_code(任务失败:HTTP 为 200、status: failed)中;同一个码两处都可能出现。是否消耗卡密、能否用原卡密重提,以「处置」列为准:标注「卡密未消耗」的修正后可重提;标注「请勿重复提交」的不要自动重试。
| HTTP | error / error_code | 含义 | 处置 |
|---|---|---|---|
| 400 | invalid_card_key | 卡密无效、不存在、未售出或剩余次数不足 | 用 cdk-info 核实后给终端用户明确答复 |
| 409 | card_already_used | 该卡密已成功使用过 | 卡密一次性,换一张 |
| 409 | card_in_progress | 该卡密已有任务在处理中,或刚刚(约 3 小时内)已用同一账号充值成功;响应体带 job_id(等于原 task_id,用同一 Key 提交的可直接轮询;刚受理的几秒内可能暂时没有该字段) | 别重复提交,改用 task 轮询原任务(已成功的会直接返回成功结果) |
| 409 | account_has_subscription | 目标账号当前有生效中的订阅(例外:Pro 5x 单已有生效 Plus 的菲区账号、Pro 20x 单已有生效 Plus / Pro 5x 的菲区账号可升级,不会返回此错误;已是生效 Pro 20x 的账号请到期后再续费;Pro 500 不接受任何订阅,也不支持升级) | 卡密未消耗;换一个无订阅的账号(或按上面的例外用可升级的账号),或等订阅到期 |
| 409 | account_busy | (Pro 500)该账号已有 PLS- / P5X- / P20X- / P500- 卡密的任务在受理 / 排队 / 处理中,不分入口与经销商 | 卡密未消耗;等原任务结束后再提交 |
| 409 | email_frozen | 该账号(邮箱)计费类失败(在付款环节被拒的失败)连续 2 次,已暂停提交;同一账号成功一次或我们解冻后重新计数 | 卡密未消耗;请勿对该账号继续重试,联系我们解冻 |
| 409 | session_failed_too_many | 该账号(session)无论什么原因连续失败 3 次,已暂停提交(detail_zh:当前session失败次数过多,请联系苏哲);同一账号成功一次或我们解冻后重新计数 | 卡密未消耗;请勿对该账号继续重试,联系我们解冻 |
| 409 | plus_not_ph_region | 该账号的 Plus 是非菲区(非 PHP)订阅,Pro 5x / Pro 20x 升级仅支持菲区(PHP) 订阅或免费账号 | 卡密未消耗;改用免费账号或菲区(PHP) Plus 账号 |
| 409 | promax_billing_not_php | (Pro 500)账号计费地区不是菲律宾(PHP) | 卡密未消耗;更换账号或联系我们 |
| 409 | account_not_eligible_pro20 | 官方明确暂未对该账号开放 Pro 20x(较少出现) | 卡密未消耗;换一个账号(免费账号,或菲区 Plus / Pro 5x)重试 |
| 409 | account_not_eligible_promax | (Pro 500)官方暂未对该账号开放 Pro 500(较少出现) | 卡密未消耗;联系我们 |
| 409 | pro20_already_active | 账号已是生效中的 Pro 20x,尚未到期 | 卡密未消耗;到期后再续费 |
| 400 | session_expired | 登录凭证(Session/accessToken)已过期或失效 | 卡密未消耗;让用户重新登录 ChatGPT 复制最新完整 Session 后重试 |
| 502 | precheck_failed | (Pro 20x / Pro 500)暂时无法核验账号的订阅状态或开通资格(预检服务临时不可用);无法核验就不会受理 | 卡密未消耗;稍后重试 |
| — | session_missing_access_token | Session 缺 accessToken | 让用户重新完整复制 Session 页面 |
| — | invalid_session_data | Session 被判定为无效 | 让用户重新导出 Session,用新 Session 重试 |
| — | invalid_product_line | 卡密类型暂不受支持 | 联系我们登记,通常是新卡种 |
| — | invalid_recharge_method | 该卡密暂不可用 | 联系我们 |
| — | card_key_busy_other_product | 卡密正被其他任务占用 | 稍后用 cdk-info 复查 |
| 200 | payment_declined | 开通 / 升级阶段付款未成功 | 卡密未消耗;稍后重试或联系我们。Pro 500 若在基础档开通之后失败,重提时会提示账号已有订阅(account_has_subscription),说明账号已是基础档,请联系我们人工处理 |
| 200 | upgrade_incomplete | 开通未完成:账号已开通基础档,尚需完成升级(Pro 20x 免费号新开可能出现;Pro 500 无此码,见下一行) | 卡密未消耗;用同一张卡密重新提交即可,仍失败请联系客服 |
| 200 | promax_upgrade_incomplete | (Pro 500)基础档已开通,但升级到 Pro 500 未成功,账号现在停在基础档 | 请勿重复提交(重提会因账号已有订阅被拒);联系我们人工处理。与 upgrade_incomplete 相反 |
| 200 | payment_unverified | 付款请求已发出,但无法核实结果(任何套餐都可能出现) | 请勿重复提交,也不要换卡密重试;联系我们核对 |
| 200 | verification_timeout / verification_failed | 安全验证超时未完成 / 未通过 | 卡密未消耗;可重新提交 |
| 200 | account_verification_required | 该 ChatGPT 账号需要额外验证,暂时无法自动开通 | 卡密未消耗;联系我们 |
| 200 | invoice_renew_required | 账号存在未结清的欠费账单,无法自动开通 | 卡密未消耗;处理欠费或更换账号后重试 |
| 200 | promax_trial_unsupported | (Pro 500)账号当前触发官方试用优惠,无法自动开通;未产生扣款 | 卡密未消耗;联系我们 |
| 200 | activation_failed | 兜底:开通未成功(具体原因不对外细分) | 卡密未消耗;Plus / Pro 5x / Pro 20x 可稍后用同一张卡密重试,多次失败联系我们;Pro 500 请勿自动重试,联系我们 |
HTTP 为「—」的码出现位置不固定(可能是同步错误,也可能是任务失败码),状态码以实际响应为准;程序分支始终只认 error / error_code。
PLS- / P5X- / P20X- / P500-),invalid_card_key / account_has_subscription / session_missing_access_token 都在受理前返回,卡密未消耗,修正后可直接重发;card_already_used / card_in_progress 表示这张卡已在用,不要另开新单。服务端异常#
| HTTP | error | 含义 | 处置 |
|---|---|---|---|
| 500 | server_error | 服务端异常 | 带 task_id 联系我们 |
| 502 | upstream_error | 充值服务暂时无响应 | 按 4.5 先查证再决定是否重发 |
| 503 | unavailable | 服务维护中 | 用 status 接口确认恢复后再提交 |
| 503 | tier_maintenance | Pro 5x / Pro 20x 自助开通临时维护中,或 Pro 500 暂未开放(Pro 500 有独立开关,不受 5x / 20x 维护影响),卡密未消耗;Pro 500 任务排队期间恰遇关闭时,也会以失败码形式出现(HTTP 200) | 稍后重试;Plus 不受影响 |
| 200 | system_maintenance | 不是 HTTP 错误:只会作为失败任务的 error_code(status: failed)出现,表示充值系统正在加急更新中,卡密未消耗 | 稍等片刻后用同一张卡密重试 |
推荐对接流程
① 用户在你站下单
│
▼
② GET /api/v1/gptplus/status ← available=false 就拦下,别收单
│
▼
③ GET /api/v1/gptplus/cdk-info ← redeemable=false 就换一张卡
│
▼
④ 引导用户提供 Session JSON
│
▼
⑤ POST /api/v1/gptplus/redeem ← 拿到 task_id 立刻落库
│
▼
⑥ 每 3 秒 GET /task/{id} 直到 finished=true
│
├─ success → 通知用户完成
└─ failed → 按 error_code 给出处置文案必须落库的字段#
task_id、card_code、product、提交时间、最后一次状态。出问题时这五个字段足以定位,缺一不可。
常见踩坑#
| 现象 | 原因 | 解法 |
|---|---|---|
| 提交后立即失败,提示 Session 无效 | 用户复制 Session 后退出了 ChatGPT 登录 | 要求提交期间保持登录 |
| 明明是新卡却提示已使用 | 同一张卡在其他入口也提交过 | 提交前用 cdk-info 核实 |
| 充值成功但用户看不到订阅 | 客户端缓存 | 让用户刷新 ChatGPT 网页或重新登录 |
| 超时后重发,卡密被扣两次 | 违反 4.5 的重试语义 | 5xx / 超时先查证再重发 |
| Pro 20x 提示已有订阅 | 账号已是生效中的 Pro 20x,或是 Plus / Pro 5x 以外的付费订阅 | 请在订阅到期后再续费;菲区的 Plus / Pro 5x 账号可直接升级,非菲区计费会返回 plus_not_ph_region |
| 提交超时后担心重复消耗卡密 | 提交最坏约 80 秒,客户端超时设得太短;服务端其实已建单 | 超时设 ≥ 90 秒;超时后先查 jobs,或用同一张卡密重提(已建单或刚成功会得到 409 card_in_progress + job_id,照常轮询即可) |
Pro 500 任务长时间停在 queued | Pro 500 全系统单车道,需要排队 | 继续轮询,等待上限设 ≥ 20 分钟,不要重提(见 2.4) |
Pro 500 失败后重提被 account_has_subscription 拒绝 | 失败发生在基础档开通之后,账号已是基础档 | 不要重提,联系我们人工处理(见 2.4、7.3) |
自助激活页(面向终端用户)#
如果你不想自己开发提交页面,可以直接把 https://www.academicgate.org/store 发给终端用户:
- 用户无需 API Key:粘贴你发给他的卡密和自己的 Session JSON 即可。页面按卡密前缀自动识别套餐,支持 Plus / Pro 5x / Pro 20x / Pro 500(Pro 500 有单独页签,粘贴
P500-卡密会自动切换),中英文界面。 - 账号规则、判重、失败冻结与失败文案与本 API 一致;页面提交的任务在
cdk-info的卡密历史里可见,但不会出现在你的jobs流水中(jobs只含用你的 Key 提交的任务)。 - 页面对每个终端用户 IP 的限额比本 API 更紧(提交 8 次 / 分钟、读取 60 次 / 分钟);大量用户共用同一出口 IP 时可能触发限频。
- 页面等待结果最长约 6.5 分钟(Pro 500 约 15 分钟),之后停止自动刷新并提示稍后用卡密重新查询,任务本身不受影响。页面没有账号资格预检,资格在提交时判定,被拒绝的卡密不消耗。
- 页面只供终端用户在浏览器里直接使用:它调用的是面向网页的匿名接口,不是 Key 接口,不能被第三方站点跨域调用。要在自己的站点内嵌入激活流程,请由你方服务端调用本 API(Key 只放服务端,见 3.1);如需在你方域名下提供同类激活页,请联系我们沟通部署方式。
代码示例
Python#
import time
import requests
BASE = "https://www.academicgate.org"
API_KEY = "aisub_你的Key"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json; charset=utf-8"}
class ActivationError(Exception):
def __init__(self, code, detail):
super().__init__(f"{code}: {detail}")
self.code = code
def _check(resp):
data = resp.json()
if resp.status_code >= 400 or not data.get("success"):
raise ActivationError(data.get("error", "http_%d" % resp.status_code),
data.get("detail_zh") or data.get("detail") or "")
return data
def activate(card_code, session_data, timeout_seconds=900): # Pro 500 排队较久,建议 ≥ 1200
# 1) 服务可用性
if not _check(requests.get(f"{BASE}/api/v1/gptplus/status", headers=HEADERS, timeout=30))["available"]:
raise ActivationError("unavailable", "充值服务维护中")
# 2) 卡密可用性
if not _check(requests.get(f"{BASE}/api/v1/gptplus/cdk-info",
params={"code": card_code}, headers=HEADERS, timeout=30))["redeemable"]:
raise ActivationError("invalid_card_key", "卡密已使用或正在处理中")
# 3) 提交。成功即消耗次数,此处绝不重试;提交最坏约 80 秒才返回,timeout 须 ≥ 90;超时 / 502 先查 jobs 再决定
job = _check(requests.post(f"{BASE}/api/v1/gptplus/redeem", headers=HEADERS, timeout=90,
json={"card_code": card_code, "session_data": session_data}))
task_id = job["task_id"]
print("submitted", task_id, job["product_name_zh"])
# 4) 轮询
deadline = time.time() + timeout_seconds
while time.time() < deadline:
time.sleep(3)
try:
st = _check(requests.get(f"{BASE}/api/v1/gptplus/task/{task_id}", headers=HEADERS, timeout=30))
except (requests.RequestException, ActivationError):
continue # 查询是只读的,网络抖动继续轮询即可
if st["finished"]:
return st
raise ActivationError("poll_timeout", f"超过 {timeout_seconds} 秒仍未出结果,task_id={task_id}")Node.js#
const BASE = 'https://www.academicgate.org';
const API_KEY = process.env.AISUB_API_KEY;
const HEADERS = { 'X-API-Key': API_KEY, 'Content-Type': 'application/json; charset=utf-8' };
class ActivationError extends Error {
constructor(code, detail) { super(`${code}: ${detail}`); this.code = code; }
}
async function call(path, options = {}) {
const res = await fetch(BASE + path, { headers: HEADERS, ...options });
const data = await res.json();
if (!res.ok || !data.success) {
throw new ActivationError(data.error || `http_${res.status}`, data.detail_zh || data.detail || '');
}
return data;
}
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function activate(cardCode, sessionData, timeoutMs = 900_000) { // Pro 500 排队较久,建议 ≥ 1_200_000
const status = await call('/api/v1/gptplus/status');
if (!status.available) throw new ActivationError('unavailable', '充值服务维护中');
const info = await call(`/api/v1/gptplus/cdk-info?code=${encodeURIComponent(cardCode)}`);
if (!info.redeemable) throw new ActivationError('invalid_card_key', '卡密已使用或正在处理中');
// 成功即消耗次数,此处绝不重试;提交最坏约 80 秒才返回,如设置请求超时须 ≥ 90 秒
const job = await call('/api/v1/gptplus/redeem', {
method: 'POST',
body: JSON.stringify({ card_code: cardCode, session_data: sessionData }),
});
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
await sleep(3000);
try {
const st = await call(`/api/v1/gptplus/task/${job.task_id}`);
if (st.finished) return st;
} catch (_) { /* 查询只读,抖动继续 */ }
}
throw new ActivationError('poll_timeout', `超时,task_id=${job.task_id}`);
}数据处理与隐私
Session 凭据#
session_data 仅用于完成本次充值,不作任何形式的存储。它不写入数据库、不落盘、不进日志,处理结束即从内存释放。
留存的数据#
为对账、售后与风控,我们留存以下字段:
| 数据 | 用途 | 留存 |
|---|---|---|
| 卡密、任务号、套餐、状态与结果说明 | 对账与售后举证 | 长期 |
| 从 Session 中提取的账号邮箱 | 定位是哪个账号被充值 | 长期 |
| 调用方 Key 标识与请求 IP | 归属判定与异常排查 | 长期 |
邮箱在 cdk-info 的历史记录中对外一律打码;你自己提交的任务在 task 与 jobs 接口中返回完整值。
你的义务#
终端用户的 ChatGPT Session 属于其个人凭据。请在你的产品中明确告知用户该凭据的用途,并遵守你所在司法辖区的个人信息保护要求。我们仅按本节所述处理你传入的数据。
服务等级与支持
| 项目 | 说明 |
|---|---|
| 单笔处理时长 | 通常 1–3 分钟,高峰期更长;建议轮询上限 15 分钟。Pro 500 全系统单车道排队,耗时更长且不固定,建议上限至少 20 分钟 |
| 计划内维护 | 期间 status 接口 available 返回 false,请据此拦截下单 |
| 故障处置 | 通过 status 与错误码实时反映,恢复后自动可用,无需你方操作 |
| 技术支持 | 工作时间响应;紧急问题请标注"紧急" |
提交支持请求时请提供 task_id + 卡密前 6 位 + UTC 时间。
联系方式见 https://suzhe.ai 页面底部。
上线自检清单
对接完成、放量之前逐条确认:
- [ ] API Key 只存在于服务端密钥管理中,代码仓库与前端产物里搜不到
- [ ] 日志中不含 Key、完整卡密、Session JSON、accessToken
- [ ] 同时校验了 HTTP 状态码与响应体
success - [ ] 业务分支基于
error字段,没有匹配detail文案 - [ ]
redeem的 5xx / 超时路径走的是"先查证再决定",不是无脑重试 - [ ]
task_id/card_code/product/ 提交时间 / 最后状态均已落库 - [ ] 轮询有上限,超时后转人工而不是判定失败
- [ ] 提交请求的客户端超时 ≥ 90 秒,超时后先查证(
jobs/cdk-info)再决定是否重发 - [ ] Pro 500:只提交给免费账号;
promax_upgrade_incomplete/payment_unverified不会被自动重提;轮询上限 ≥ 20 分钟 - [ ] 卡密前缀取自
GET /api/v1/products,没有硬编码;目录外的前缀交给服务端判定,本地不拒收 - [ ] 下单入口前查过
status,维护期不收单 - [ ]
429有指数退避 - [ ]
duplicate_email_confirm走的是「展示给用户 → 用户确认 → 重发」,不是代码里无条件自动确认 - [ ] 已跑通一次完整成功与一次失败路径
版本策略
- 版本定在路径上(
/api/v1/...)。 - 向后兼容的变更不升版本,随时可能发生,你的解析必须容忍:新增响应字段、新增错误码、新增套餐与卡密前缀、新增可选请求参数。
- 破坏性变更会启用新路径前缀(如
/api/v2/),老版本至少保留 90 天并提前通知。 - 请按"忽略未知字段"的方式解析响应,不要用严格模式反序列化。
变更记录
| 日期 | 变更 |
|---|---|
| 2026-10-10 | 文档补充(无接口变更):409 card_in_progress 的含义补充——除「该卡密已有任务在处理中」外,同一账号用同一张卡密在约 3 小时内重提且上次已成功时也返回它(带原 job_id,轮询即得成功结果),用于网络中断/响应丢失后的安全重提;超过窗口仍返回 card_already_used。 |
| 2026-10-06 | 新增 ChatGPT Pro 500:卡密前缀 P500-,product 为 gpt_pro_500_self,GET /api/v1/products 目录由 4 项变为 5 项;沿用同一组接口,自助激活页同步开放。仅支持无任何订阅的免费账号(无升级、无补差价),人工发货、不提供在线购买;全系统单车道,任务可能排队数分钟;失败码 promax_upgrade_incomplete / payment_unverified 表示请勿重复提交(与 upgrade_incomplete 含义相反)。新增错误码 account_busy、promax_billing_not_php、account_not_eligible_promax、promax_trial_unsupported、promax_upgrade_incomplete,详见 2.4、7.3。接口路径与既有字段不变,存量对接无需改动。 |
| 2026-10-06 | 文档与线上行为对齐(无接口变更):7.3 补全 HTTP 状态码,以及此前已上线但未入文档的错误码(pro20_already_active、payment_unverified、verification_timeout、verification_failed、account_verification_required、invoice_renew_required、activation_failed),并写明 email_frozen(计费类失败连续 2 次)与 session_failed_too_many(任何原因连续 3 次)的阈值;card_in_progress 响应带 job_id;订正 system_maintenance 为失败任务的 error_code(不是 HTTP 503);说明提交最坏约 80 秒、客户端超时请设 ≥ 90 秒;task 响应补充 duration_seconds,jobs 流水补充 submitting / reset 状态;status 的 pending / wait_seconds 标明为兼容保留字段;2.3 判重示例补充 last_product_zh / blocked;account_not_eligible_pro20 改为较少出现;新增 8.3 自助激活页说明。 |
| 2026-09-30 | Pro 20x 开放新开通与升级:无订阅账号可直接开通;已有生效菲区(PHP) Plus / Pro 5x 的账号自动升级为 Pro 20x(无需先取消原订阅)。已是生效 20x 的账号仍需到期后续费。新增错误码 upgrade_incomplete(账号已开通基础档、尚需完成升级,卡密未消耗,用同一卡密重提即可);account_not_eligible_pro20 含义更新为「官方暂未对该账号开放」。接口路径与字段不变,存量对接无需改动。 |
| 2026-09-25 | Pro 5x 现额外支持已有生效 ChatGPT Plus 的账号:自动升级为 Pro 5x(无需先取消 Plus),此类账号不再返回 account_has_subscription;Plus 仍仅支持当前无订阅的账号。(Pro 20x 的开通口径已于 2026-09-30 更新,见上一条。)接口路径与字段不变,存量对接无需改动。 |
| 2026-09-24 | 卡密前缀更新为 PLS-(Plus)/ P5X-(Pro 5x)/ P20X-(Pro 20x),product 为 gpt_plus_self / gpt_pro_5x_self / gpt_pro_20x_self(见 2、5.2)。仅支持当前无订阅的账号,有订阅返回新错误码 account_has_subscription;另新增 card_already_used / card_in_progress(见 7.3)。此前发放的卡密仍可兑换,只是不再出现在 /products 目录里。请以 /products 实时返回为准,不要硬编码前缀,也不要在本地拒收目录外的前缀。 |
| 2026-09-24 | 安全验证统一为 action_required: "manual_captcha" + verification_url(我方地址),iframe 或新窗口打开;status 仍为 running,完成后继续轮询原 task_id(见 5.6)。不再下发其他验证类型。 |
| 2026-09-23 | 接口地址改为 https://www.academicgate.org(原 aisubscription.vip 停用);接口路径、参数与 API Key 均不变,只需替换域名。 |
| 2026-09-17 | 新增重复充值保护:同一账号 24 小时内再次提交直接拒绝,30 天内需带 confirm_duplicate: true 确认,详见 2.3。新增错误码 duplicate_email_blocked / duplicate_email_confirm。 |
| 2026-09-17 | 覆盖全部 GPT 套餐(Plus / Pro 5x / Pro 20x 新开与续费)。新增 GET /api/v1/products;cdk-info / redeem / task / jobs 响应新增 product 等字段;jobs 新增 product 过滤参数。同步收敛对外字段:移除内部标识,cdk-info 历史记录中的账号邮箱改为打码(你自己提交的任务在 task / jobs 中仍返回完整值)。接口路径与既有业务字段未变,存量对接无需改动。 |
| 2026-09-07 | 文档迁至 suzhe.ai/gptapi;接口地址固定为 aisubscription.vip。 |
| 2026-08 | ChatGPT Plus 卡密格式更新。 |