鉴权、限流与幂等
密钥校验顺序、限流响应头、幂等键与请求 ID 的约定。
鉴权
每个请求按以下顺序校验:密钥存在且启用 → 未过期 → IP 白名单 → 模型存在且分组允许 → 余额 / 配额 / 预算 → 限流与并发。任何一步失败都返回标准协议格式的错误,并附带 error.code。
| 位置 | 写法 | 适用协议 |
|---|---|---|
| Authorization 头 | Bearer sk-… | OpenAI / Anthropic / 视频 |
| x-api-key 头 | sk-… | Anthropic |
| x-goog-api-key 头 | sk-… | Gemini |
| 请求体 apiKey | "apiKey": "ak-…" | 私有协议 |
限流与并发
限流按密钥、用户与分组三层生效(RPM / TPM / 并发)。超限返回 429,并带 Retry-After。
| 字段 | 类型 | 说明 |
|---|---|---|
| X-RateLimit-Limit-Requests | header | 当前窗口允许的请求数。 |
| X-RateLimit-Remaining-Requests | header | 当前窗口剩余请求数。 |
| X-RateLimit-Reset-Requests | header | 窗口重置的秒数。 |
| Retry-After | header | 被限流时建议的重试等待秒数。 |
幂等与请求 ID
创建类请求(视频任务、私有协议调用)支持幂等:标准协议使用 Idempotency-Key 头,私有协议使用 clientRequestId 字段。同一密钥所有者在 24 小时内以相同键重放,会返回首次的结果而不会重复计费。
响应头 X-Request-Id 标识本次请求;你也可以自行传入以便日志对齐。
查询密钥用量
GET/v1/key/usage
用密钥本身查询它的额度、限额、到期时间、近 30 天按模型的用量和最近 20 次调用,不需要登录,也不受密钥的用量接口开关限制。只返回这把密钥自己的数据:不含账户余额、其他密钥或平台成本。网页版在 /usage-lookup。
每个来源 IP 每分钟 10 次、每把密钥每分钟 30 次,超出返回 429 并带 Retry-After;无效、吊销或过期的密钥返回 401,停用的密钥返回 403。金额单位都是微美元(1 美元 = 1,000,000)。
| 字段 | 类型 | 说明 |
|---|---|---|
| key | object | name、prefix、last4、status、expires_at(可为 null)、created_at。 |
| quota | object | total / daily / monthly_micro_usd 为 null 表示不限额;used_* 为已用;remaining_* 只在设了对应额度时有值,最小为 0。 |
| limits | object | rpm_limit、tpm_limit、concurrency_limit,null 表示不限。 |
| last_30_days | object | start、end、models[](model、requests、errors、input_tokens、output_tokens、cached_tokens、charged_micro_usd)与同字段的 total。 |
| recent | array | 最近 20 次调用:request_id、created_at、model、status_code、input_tokens、output_tokens、charged_micro_usd。 |
curl https://www.link42.ai/v1/key/usage \
-H "Authorization: Bearer $LINK42_API_KEY"密钥的素材访问范围
每把密钥都有一个素材访问范围(asset_access),决定它能在请求里用 asset://<id> 引用哪些素材。在控制台 → API 密钥里创建或编辑密钥时可以修改这一项。
引用超出范围的素材时,返回的错误和素材不存在时完全相同:视频任务返回 not_found 或 reference_asset_unavailable,图像生成返回 reference_asset_unavailable。这样别人无法借错误信息探测某个素材是否存在。
同一个范围也决定这把密钥通过 /v1/assets 接口能查看、下载和删除哪些素材,见“素材库”页的“访问范围对素材接口的影响”。
| 取值 | 能引用的素材 |
|---|---|
| own | 新建密钥的默认值。只能引用这把密钥上传的素材,以及在控制台上传的素材。 |
| all | 账户下的全部素材。 |
| none | 不能引用任何素材;请求里带 asset:// 会返回 403 asset_access_denied。 |
- 这项设置上线之前创建的密钥保持 all,现有集成不受影响;需要收紧时,在控制台把它改成 own 或 none。
兼容档案
密钥绑定一个不可变的兼容档案。standard_v1 是新密钥默认档案;legacy_v1 保留旧系统的响应媒体类型、空结果与流式行为,仅用于迁移密钥。档案变更需新建密钥,不会静默改变历史行为。
| 行为 | legacy_v1 | standard_v1 |
|---|---|---|
| 私有协议响应类型 | text/plain | application/json |
| getResult 未命中 | 空字符串 | {"code":-1,"message":"task not found"} |
| 私有协议 stream=true | 缓冲整体返回 | 真实 SSE |
| 跨用户访问 | 禁止 | 禁止 |
控制台 API
除了网关数据面(/v1、/v1beta、/server),平台还有一组 /api/v1 控制台接口,用于管理账号、密钥、用量、收支与代理批发。它们不接受 API Key:凭据是浏览器会话 Cookie,或同一会话签发的 Bearer 令牌,且每一次查询都限定在当前登录用户的数据范围内。
成功响应是 {data, request_id},分页接口是 {list, total, page, page_size}。失败响应是扁平信封 {code, error_code, message, request_id},详见“错误码”页。
- 下面示例里的 $LINK42_CONSOLE 指控制台站点地址,也就是你登录的那个域名;它与网关地址不同。
- 请求体使用严格解析:出现未声明的字段会返回 400 invalid_json。修改类接口省略某个字段表示保持不变。
修改个人资料
PATCH/api/v1/auth/me
修改当前登录用户的昵称、界面语言与地区。三个字段都可选,只提交需要修改的部分;响应返回更新后的用户对象。
| 字段 | 类型 | 说明 | |
|---|---|---|---|
| nickname | string | 可选 | 显示名称。 |
| locale | string | 可选 | 界面语言,例如 zh-CN 或 en-US。 |
| region | string | 可选 | 地区代码,决定可见的支付方式与合规策略。 |
curl -X PATCH "$LINK42_CONSOLE/api/v1/auth/me" \
-H "Content-Type: application/json" \
-b "$LINK42_SESSION_COOKIE" \
-d '{"nickname": "Ada", "locale": "zh-CN"}'两步验证与敏感操作确认
GET/api/v1/auth/mfa/status
两步验证开启后,每次登录(密码、第三方登录、单点登录)通过后都要再输入一个发到账号邮箱的验证码。通行密钥登录本身是强认证,不再额外要求验证码。
改密码、注销账号、添加或删除通行密钥、开关两步验证、绑定或解绑第三方登录、申请佣金提现属于敏感操作,需要“当前密码 + 邮箱验证码”确认;没有密码的账号(只用第三方登录注册)只需要验证码。验证码与具体操作绑定,为一个操作申请的验证码不能用于另一个操作。
| 端点 | 作用 | 请求体 |
|---|---|---|
| GET /api/v1/auth/mfa/status | 查询是否已开启两步验证,返回 {enabled}。 | — |
| POST /api/v1/auth/sensitive-code | 为一个敏感操作发送邮箱验证码,返回 202 {expires_at, cooldown_seconds}。action 取 change_password、close_account、add_passkey、remove_passkey、two_factor、link_provider、unlink_provider、withdrawal 之一。 | {"action": "two_factor"} |
| POST /api/v1/auth/two-factor | 开启或关闭两步验证,返回 {enabled}。 | {"enabled": true, "password": "…", "code": "123456"} |
| POST /api/v1/auth/login/2fa | 带验证码的完整登录入口。 | {"identifier": "…", "password": "…", "code": "123456"} |
| POST /api/v1/auth/passkeys/{id}/remove | 删除一个通行密钥。先用 action=remove_passkey 申请邮箱验证码。 | {"password": "…", "code": "123456"} |
- 开启两步验证后,登录时不带 code 会返回 401 mfa_required,同时把登录验证码发到账号邮箱;不带 code 再提交一次即重新发送(受发送冷却限制)。验证码错误或过期返回 401 mfa_invalid,错误次数计入账号锁定。
- 敏感操作的密码或验证码填错同样计入账号锁定;验证码只能使用一次。
密码找回与修改
POST/api/v1/auth/password/reset/request
找回密码是两步:先按邮箱申请验证码,再用验证码设置新密码。已登录时改密码走单独的端点,需要当前密码和一个 change_password 验证码(先调用 POST /api/v1/auth/sensitive-code 获取);还没有密码的账号可以只凭验证码设置第一个密码。
| 端点 | 作用 | 请求体 |
|---|---|---|
| POST /api/v1/auth/password/reset/request | 发送重置验证码,返回 202 {expires_at, cooldown_seconds}。 | {"email": "…", "captcha_token": "…"} |
| POST /api/v1/auth/password/reset/confirm | 用验证码设置新密码,成功返回 204。 | {"email": "…", "code": "…", "new_password": "…"} |
| POST /api/v1/auth/password/change | 已登录时修改密码,成功返回 204。 | {"current_password": "…", "new_password": "…", "code": "123456"} |
- 改密码成功后,除当前会话外的所有会话都会被吊销,其他设备需要重新登录。
- 申请过于频繁返回 429 verification_cooldown,并带 Retry-After 与 X-RateLimit-* 头;验证码连续输错会返回 verification_exhausted,需要重新申请。新密码过弱返回 weak_password,与旧密码相同返回 password_reused。
第三方账号绑定
GET/api/v1/auth/identities
列出、绑定与解绑第三方登录身份。可用提供方由平台配置决定,先用 GET /api/v1/auth/oauth/providers 查询。绑定需要“当前密码 + link_provider 验证码”确认,解绑需要“当前密码 + unlink_provider 验证码”确认;验证码都先用 POST /api/v1/auth/sensitive-code 按对应 action 申请。
| 端点 | 作用 |
|---|---|
| GET /api/v1/auth/oauth/providers | 列出已启用的登录提供方。 |
| GET /api/v1/auth/oauth/{provider}/authorize | 用第三方账号登录或注册:发起授权跳转,回调落在同名 callback 路由。 |
| POST /api/v1/auth/oauth/{provider}/link | 把第三方账号绑定到当前登录用户。请求体 {password, code},返回 {url, expires_at},浏览器跳转到 url 完成授权。 |
| GET /api/v1/auth/identities | 列出当前用户已绑定的身份。 |
| POST /api/v1/auth/identities/{provider}/unlink | 解绑某个提供方。请求体 {password, code},code 为 unlink_provider 用途的邮箱验证码。 |
- 同一个第三方账号只能绑定到一个平台用户;重复绑定返回 409 identity_already_linked,同一提供方重复绑定返回 409 provider_already_linked。