开始接入
公开演员数据可由浏览器匿名读取;身份映射、购买和生成调用许可只能由合作方后端使用JD1签名访问,终端浏览器不访问SZKL。
- Base URL
https://www.szkl.cn/api/v1- 业务环境
- 合作方仅接受production;须审核通过并完成配置
- 响应格式
- JSON(媒体与字幕除外);错误使用稳定的
error.code - 请求追踪
- 响应头
x-request-id
- 公开宣传媒体只用于发现与展示,不构成生产素材资格或商业授权。
- JD1私钥只能保存在合作方服务端,不得进入浏览器、移动端包或日志。
- 合作方调用需完成平台审核、线下合同登记和凭证配置。
接入流程
- 线下签署B端合作合同(合作方与巨东AI之间的框架合同)。
- 在
/partners/apply提交申请:工商主体、联系人、平台显示名称与合作方服务端生成的Ed25519公钥(SPKI PEM)。 - 审核通过后配置平台,发放
credentialId与权威audience;公钥指纹可在后台核对。 - 完成合同登记、凭证和权限配置后,合作方可调用身份绑定、购买和生成接口。
- 预存余额充值后开始业务交易。
密钥生成(在合作方服务端执行)
openssl genpkey -algorithm ed25519 -out partner-private.pem # 私钥,仅保存在服务端
openssl pkey -in partner-private.pem -pubout -out partner-public.pem # 公钥,粘贴到申请表单公钥以-----BEGIN PUBLIC KEY-----开头;不要提交私钥、SSH格式或JWK。私钥丢失平台侧无法恢复;请联系管理员停用受影响凭证并安排重新配置。
Scope
- 身份与绑定
authorization_sessions:create / authorization_sessions:read / projects:bind / identity:assert_verified_email
以管理员实际配置的权限为准- 购买与资金
purchase:create / purchase:read / funds:read
以管理员实际配置的权限为准- 生成
generation:reserve / generation:read / generation:settle
需管理员对平台单独开通
公开演员API
演员目录、详情和媒体端点允许任意Origin无凭据 GET/OPTIONS,禁止携带Cookie或Authorization。公开核验端点只提供匿名 GET,不读取登录会话。媒体URL以响应中的绝对公开地址为准。
- GET匿名
/health读取服务健康与部署环境
- GET匿名
/actors搜索和分页读取公开演员
- GET匿名
/actors/{actorCode}读取演员详情和公开形象
- GET匿名
/media/{publicId}读取已发布宣传媒体
- GET匿名
/media/{publicId}/captions读取已发布字幕
- GET匿名
/verification/{token}查询公开授权核验事实
最小请求
curl -H "Accept: application/json" \
"https://www.szkl.cn/api/v1/actors?limit=24&offset=0"公开读取错误:参数无效为400 BAD_REQUEST,资源不存在为404 NOT_FOUND,依赖不可用为503 SERVICE_UNAVAILABLE,未预期异常为500 INTERNAL_ERROR。媒体还支持206部分内容、304未修改和416范围不可满足。
公开授权核验
当前核验接口仅支持历史 test/test_only 授权事实,不提供正式production授权核验。正式购买响应中的核验编号不能据此视为已经支持公开核验。
使用授权编号查询最小核验事实。非法编号、权威不存在返回 404;依赖或响应畸形返回 503;成功与错误均禁止缓存,成功响应不携带来源地址。
curl -H "Accept: application/json" \
"https://www.szkl.cn/api/v1/verification/JDT-ABCDEF0123456789ABCDEF01"合作方API
合作方接口只接受人工审核后配置的服务端凭证。合作方后端直接建立平台范围身份映射,响应不含授权URL、state、回跳或Cookie;合作网站完成自己的订单、合同和支付后,再调用购买接口。每个生成调用必须在模型启动前取得一次成功的额度预留,并以一个终态结算收敛。
- POSTJD1
/partner/authorization-sessions建立服务端身份映射;scope:authorization_sessions:create + projects:bind + identity:assert_verified_email
- GETJD1
/partner/authorization-sessions/{sessionId}查询身份映射与后续权威状态;scope:authorization_sessions:read
购买与资金
- GETJD1
/partner/purchase-options读取购买秒数、年限和场景规则;scope:purchase:read
- POSTJD1
/partner/purchase-orders原子完成扣款、合同、授权和额度建立;scope:purchase:create
- GETJD1
/partner/purchase-orders按外部订单号查询购买和授权事实;scope:purchase:read
- GETJD1
/partner/fund-balance读取合作平台预存余额;scope:funds:read
- GETJD1
/partner/fund-events分页读取不可变资金流水;scope:funds:read
合作网站需要保存
- 客户映射
externalUserId ↔ sessionId,同一用户长期保持稳定- 购买映射
externalOrderId ↔ purchaseId/projectId,购买后生成使用SZKL返回的projectId- 生成映射
externalGenerationId ↔ projectId/terminalStatus,模型启动前先预留,结束时只结算一次- 实名认证
- 只传已认证结果、认证时间和认证记录编号;不传身份证号、证件图片或原始材料
生成调用许可
- POSTJD1
/partner/generation-reservations模型启动前原子预留调用额度;scope:generation:reserve
- GETJD1
/partner/generation-reservations/{externalGenerationId}查询预留权威状态;scope:generation:read
- POSTJD1
/partner/generation-reservations/{externalGenerationId}/extend延长仍有效的预留;scope:generation:reserve
- POSTJD1
/partner/generation-reservations/{externalGenerationId}/success成功结算并消费额度;scope:generation:settle
- POSTJD1
/partner/generation-reservations/{externalGenerationId}/fail失败并释放额度;scope:generation:settle
- POSTJD1
/partner/generation-reservations/{externalGenerationId}/cancel取消并释放额度;scope:generation:settle
请求与响应示例
以下响应只摘录合作方成功响应的data字段,省略号和尖括号需替换为实际值。完整JSON包裹为{ "data": { ... }, "meta": { "request_id": "..." } };金额仅为示例,不代表当前报价。
① 建立服务端身份映射
POST /api/v1/partner/authorization-sessions
{
"externalUserId": "customer-42",
"externalProjectId": "drama-2026-001",
"contactEmail": "customer@example.com",
"emailVerified": true,
"emailVerificationMethod": "partner_account_v1",
"requestedScopes": ["projects:bind"],
"selection": { "version": 2, "mode": "editable", "actorCodes": ["ACT-781C32A7CC"] }
}
201 →
{ "status": "claimed", "accountLinked": true, "sessionId": "<uuid>",
"externalProjectId": "drama-2026-001", "selection": { ... } }响应不含授权URL、state、回跳、Cookie或token;同一externalUserId重复提交收敛到同一映射。购买时externalCustomerId必须与externalUserId完全一致。
② 购买授权与秒数额度
POST /api/v1/partner/purchase-orders
{
"externalOrderId": "order-2026-0001",
"externalCustomerId": "customer-42",
"subjectKind": "individual",
"subjectName": "张三",
"identityVerified": true,
"identityVerifiedAt": "2026-09-05T10:00:00+08:00",
"identityVerificationReference": "partner-verify-0001",
"customerAcceptedAt": "2026-09-05T10:05:00+08:00",
"acceptanceReference": "partner-accept-0001",
"projectName": "品牌短剧", "workType": "短剧",
"synopsis": "用于品牌故事展示的系列短剧项目。", "releaseChannels": ["合作网站"],
"scenarioId": "<purchase-options返回>",
"actorConfigurations": [
{ "actorCode": "ACT-781C32A7CC", "commercialYears": 1, "generationSeconds": 1500 }
],
"idempotencyKey": "order-2026-0001-create"
}
201 → { "purchaseId": "<uuid>", "projectId": "<uuid>", "contractNo": "...",
"licenses": [ { "actorCode": "...", "licenseId": "<uuid>", "purchasedSeconds": 1500,
"pricePerSecondCents": 33, "commercialExpiresAt": "..." } ],
"totalCents": 49500, "balanceAfterCents": ... }单事务全有或全无:余额不足(INSUFFICIENT_FUNDS)或任一环节失败整体回滚,不产生部分扣款。价格由服务端按演员当前权威价计算;全局1500秒起购、60秒步进、9000秒上限,年限1–3年。
③ 生成预留与终态结算
POST /api/v1/partner/generation-reservations
{ "projectId": "<购买返回的UUID>", "externalGenerationId": "gen-2026-0001",
"actorCodes": ["ACT-781C32A7CC"], "requestedSeconds": 1500,
"idempotencyKey": "gen-2026-0001-reserve" }
201 → { "status": "reserved", "expiresAt": "..." }
# 模型成功后(时长必须精确等于requestedSeconds)
POST .../generation-reservations/gen-2026-0001/success
{ "projectId": "...", "durationSeconds": 1500, "playableVideoId": "video-0001", "idempotencyKey": "gen-2026-0001-success" }
# 失败或主动取消(二选一,原子释放全部演员额度)
POST .../generation-reservations/gen-2026-0001/fail { "projectId": "...", "idempotencyKey": "..." }
POST .../generation-reservations/gen-2026-0001/cancel { "projectId": "...", "idempotencyKey": "..." }必须先取得reserved再启动模型;预留默认60分钟到期,长任务用extend续期;每个任务只有一次终态结算。
- 购买和生成写请求携带16–200字符
idempotencyKey:同键同载荷重放返回原结果(零新写);同键不同载荷返回IDEMPOTENCY_CONFLICT。 - 身份绑定不接收idempotencyKey;购买和生成写请求才使用业务幂等键。每次HTTP请求重新生成JD1 timestamp、nonce和签名;成功使用过的nonce不可重放。
- 响应不明确(超时、断连、5xx)时:用新nonce签名GET同一业务ID查询权威状态,不要盲目重放写请求。
- 所有POST正文为严格JSON(
additionalProperties=false):未知字段、控制字符、非整数都会被拒绝;原始JSON字节参与签名。
JD1签名
每次请求使用新的时间戳和nonce。签名覆盖HTTP方法、原始查询顺序和最终发送的body字节;响应不明确时使用新nonce查询权威状态,不盲目重放写请求。
x-jd-credential: <credential-id>
x-jd-environment: production
x-jd-audience: <configured-audience>
x-jd-timestamp: <unix-seconds>
x-jd-nonce: <base64url-random-bytes>
x-jd-signature: <base64url-ed25519-signature>完整规范原文以下载的OpenAPI及合作方接入契约为准。签名允许前后300秒时钟差,成功使用过的nonce不可重放。
签名原文(固定顺序)
JD1
credential:<credential-id>
environment:production
audience:<configured-logical-audience>
timestamp:<unix-seconds>
nonce:<base64url-random-bytes>
method:<UPPERCASE-METHOD>
target:<pathname-with-original-query-order>
body-sha256:<base64url-sha256-of-raw-body-bytes>UTF-8编码,字段顺序与换行固定,所有值禁止CR/LF。target不含scheme/host,查询参数不得在签名后重排;GET使用空body摘要。
Node.js签名示例(仅服务端)
import { createHash, createPrivateKey, randomBytes, sign } from "node:crypto";
const b64u = (b) => b.toString("base64url");
const body = Buffer.from(JSON.stringify(payload));
const canonical = [
"JD1",
`credential:${credentialId}`,
`environment:${environment}`,
`audience:${audience}`,
`timestamp:${Math.floor(Date.now() / 1000)}`,
`nonce:${b64u(randomBytes(24))}`,
`method:POST`,
`target:/api/v1/partner/authorization-sessions`,
`body-sha256:${b64u(createHash("sha256").update(body).digest())}`,
].join("\n");
const signature = b64u(sign(null, Buffer.from(canonical),
createPrivateKey({ key: privateKeyPkcs8Pem, format: "pem" })));集成建议
以下为参考建议而非接入门禁;服务端的原子购买、幂等、预留自动过期与单次终态结算已保证账本正确性。采纳这些建议可以减少接入问题与对账分歧。
- 只在合作方服务端确认收款(支付机构服务端回调验签落库)后才调用购买接口;浏览器回跳和前端支付结果不能作为收款依据。
- 购买响应不明确(超时、断连、5xx)时,用新nonce签名GET同一
externalOrderId查询权威状态,不要盲目重放POST。 - 收到
IDEMPOTENCY_CONFLICT先GET同一订单,与首次落库的请求快照逐项核对:完全匹配且settled则直接发权益,不匹配才进入人工对账;不要换订单号或幂等键重新购买。 - 在购买成功响应到达后再向您的客户发放权益,避免出现需要回滚的客户体验。
- 先在您的数据库持久化生成任务(任务ID、projectId、演员、秒数、幂等键),再发起预留;只有
201 reserved才启动模型。 - 预留默认60分钟到期并自动释放;预计运行较长的任务请在到期前约10分钟调用
extend续期。 - 终态结算(success/fail/cancel)每个任务只有一次,幂等键固定不可更换;建议由后台worker对响应不明确的结算做重试与告警,而不是人工补偿。
- success的
durationSeconds必须精确等于预留时长,请在提交前用成片实际时长核对。
- 记录每个响应的
x-request-id;向我们反馈问题时附上它可大幅缩短排查时间。 - 瞬时
SERVICE_UNAVAILABLE可安全退避重试(如1s/2s间隔);交易请求始终用新nonce。 - 演员目录与价格是低频变化数据,可在合作端缓存(如60分钟TTL);购买、资金和生成请求使用实时签名调用。
- 建议对购买→预留→终态做日终对账抽样,与我们流水(fund-events)核对一致后再结算内部账。
错误与重试
MISSING_AUTHENTICATION / MALFORMED_AUTHENTICATION / INVALID_SIGNATURE- 认证头或签名无效。
处置:先修复签名实现,不盲重试。 STALE_REQUEST- 时间戳超出±300秒窗口。
处置:校准时钟后用新nonce重试。 REPLAY_DETECTED- nonce已被使用。
处置:使用新nonce,不复用原请求。 ENVIRONMENT_MISMATCH- 凭证与目标环境不一致。
处置:修复environment配置。 AUDIENCE_MISMATCH- 请求audience与凭证环境配置不一致。
处置:修复audience配置,原样复制后台值。 CREDENTIAL_UNAVAILABLE / PLATFORM_UNAVAILABLE / ENVIRONMENT_NOT_READY- 凭证不可用,或平台/环境门禁未开放(production需平台approved+已登记合同)。
处置:联系管理员检查状态。 PLATFORM_REGISTRATION_INCOMPLETE- 提交projectAuthorization时平台登记主体资料不完整。
处置:联系巨东补全平台登记后重试。 SCOPE_FORBIDDEN- 凭证不含所需scope。
处置:由管理员审核开通,不能客户端扩权。 RATE_LIMITED- 当前凭证超过120次/分钟。
处置:等待窗口后用新nonce重试。 SESSION_FORBIDDEN / SESSION_NOT_FOUND- 会话属于其他平台或不存在。
处置:不重试、不枚举,核对ID。 PROJECT_NOT_FOUND / ACTOR_NOT_FOUND- 项目不属于当前平台或演员不存在/未上架。
处置:核对购买返回的projectId与公开actorCode。 BAD_REQUEST- 请求字段、结构或演员编号无效。
处置:修复请求正文后用新nonce重试。 IDEMPOTENCY_CONFLICT- 同一幂等键绑定了不同规范请求。
处置:停止重试;购买先GET同一externalOrderId与首份快照核对。 CONFLICT- 对象状态已变化(会话失效、生成任务或授权状态变化)。
处置:核对状态,不原样重放。 INSUFFICIENT_FUNDS- 预存余额不足。
处置:充值后用新nonce重新发起。 EXTERNAL_CUSTOMER_UNMAPPED- 外部客户尚未完成身份绑定。
处置:先完成authorization-sessions绑定。
机器可读字段、schema、scope和响应以 OpenAPI v1 为准;本文摘要不放宽认证、幂等、额度或失败关闭规则。
更新日志
按日期倒序列出已登记进 OpenAPI 的接口契约变更;机器契约以下载的 v1.yaml 为准。
2026-09-14 演员详情新增六个选填公开字段
GET /actors/{actorCode} 的 data 新增以下字段;后台尚未录入时值为 null。宽松解析(忽略未知键)的消费方无需任何改动;严格校验或代码生成的消费方请同步更新本地 v1.yaml 副本(字段在契约中为 required)。
ethnicity- 民族;公开文本或 null
birthDate- 生日;YYYY-MM-DD 或 null
occupation- 职业;公开文本或 null
birthplace- 出生地;公开文本或 null
personalTraits- 个人特质(特长短语);公开文本或 null
zodiac- 星座;由 birthDate 按公历固定日期区间派生,birthDate 为 null 时为 null,不落库
- 字段为后台维护的选填公开事实,可原样显示或省略,不要基于缺失或取值自行推断其他演员事实。
- SZKL官网详情页当前不展示这些字段;是否在你的合作网站展示由你自行决定。
