数字克隆 SZKL.CN

API文档

公开演员目录与经审核合作方的服务端接入契约。

API V1 · 合作方服务端

最近更新2026-09-14演员详情新增六个选填公开字段

GETTING STARTED

开始接入

公开演员数据可由浏览器匿名读取;身份映射、购买和生成调用许可只能由合作方后端使用JD1签名访问,终端浏览器不访问SZKL。

Base URL
https://www.szkl.cn/api/v1
业务环境
合作方仅接受production;须审核通过并完成配置
响应格式
JSON(媒体与字幕除外);错误使用稳定的 error.code
请求追踪
响应头 x-request-id
接入边界
  • 公开宣传媒体只用于发现与展示,不构成生产素材资格或商业授权。
  • JD1私钥只能保存在合作方服务端,不得进入浏览器、移动端包或日志。
  • 合作方调用需完成平台审核、线下合同登记和凭证配置。

接入流程

  1. 线下签署B端合作合同(合作方与巨东AI之间的框架合同)。
  2. /partners/apply提交申请:工商主体、联系人、平台显示名称与合作方服务端生成的Ed25519公钥(SPKI PEM)。
  3. 审核通过后配置平台,发放credentialId与权威audience;公钥指纹可在后台核对。
  4. 完成合同登记、凭证和权限配置后,合作方可调用身份绑定、购买和生成接口。
  5. 预存余额充值后开始业务交易。

密钥生成(在合作方服务端执行)

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
需管理员对平台单独开通
PUBLIC DISCOVERY

公开演员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"
PARTNER SERVER API

合作方API

合作方接口只接受人工审核后配置的服务端凭证。合作方后端直接建立平台范围身份映射,响应不含授权URL、state、回跳或Cookie;合作网站完成自己的订单、合同和支付后,再调用购买接口。每个生成调用必须在模型启动前取得一次成功的额度预留,并以一个终态结算收敛。

  • POST
    /partner/authorization-sessions

    建立服务端身份映射;scope:authorization_sessions:create + projects:bind + identity:assert_verified_email

    JD1
  • GET
    /partner/authorization-sessions/{sessionId}

    查询身份映射与后续权威状态;scope:authorization_sessions:read

    JD1

购买与资金

  • GET
    /partner/purchase-options

    读取购买秒数、年限和场景规则;scope:purchase:read

    JD1
  • POST
    /partner/purchase-orders

    原子完成扣款、合同、授权和额度建立;scope:purchase:create

    JD1
  • GET
    /partner/purchase-orders

    按外部订单号查询购买和授权事实;scope:purchase:read

    JD1
  • GET
    /partner/fund-balance

    读取合作平台预存余额;scope:funds:read

    JD1
  • GET
    /partner/fund-events

    分页读取不可变资金流水;scope:funds:read

    JD1

合作网站需要保存

客户映射
externalUserId ↔ sessionId,同一用户长期保持稳定
购买映射
externalOrderId ↔ purchaseId/projectId,购买后生成使用SZKL返回的projectId
生成映射
externalGenerationId ↔ projectId/terminalStatus,模型启动前先预留,结束时只结算一次
实名认证
只传已认证结果、认证时间和认证记录编号;不传身份证号、证件图片或原始材料

生成调用许可

  • POST
    /partner/generation-reservations

    模型启动前原子预留调用额度;scope:generation:reserve

    JD1
  • GET
    /partner/generation-reservations/{externalGenerationId}

    查询预留权威状态;scope:generation:read

    JD1
  • POST
    /partner/generation-reservations/{externalGenerationId}/extend

    延长仍有效的预留;scope:generation:reserve

    JD1
  • POST
    /partner/generation-reservations/{externalGenerationId}/success

    成功结算并消费额度;scope:generation:settle

    JD1
  • POST
    /partner/generation-reservations/{externalGenerationId}/fail

    失败并释放额度;scope:generation:settle

    JD1
  • POST
    /partner/generation-reservations/{externalGenerationId}/cancel

    取消并释放额度;scope:generation:settle

    JD1

请求与响应示例

以下响应只摘录合作方成功响应的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字节参与签名。
REQUEST SIGNING

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" })));
INTEGRATION TIPS

集成建议

以下为参考建议而非接入门禁;服务端的原子购买、幂等、预留自动过期与单次终态结算已保证账本正确性。采纳这些建议可以减少接入问题与对账分歧。

支付与购买时机
  • 只在合作方服务端确认收款(支付机构服务端回调验签落库)后才调用购买接口;浏览器回跳和前端支付结果不能作为收款依据。
  • 购买响应不明确(超时、断连、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)核对一致后再结算内部账。
FAIL CLOSED

错误与重试

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 为准;本文摘要不放宽认证、幂等、额度或失败关闭规则。

CHANGELOG

更新日志

按日期倒序列出已登记进 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官网详情页当前不展示这些字段;是否在你的合作网站展示由你自行决定。