ORedact API 文档:鉴权、提交与回调

图片、视频打码 API 的接入说明:注册控制台拿到 API Key,上传文件、提交任务、查询状态、获取结果三步异步接口,Webhook 回调与签名校验,错误码表,以及试用额度与计费口径。每个接口都给出请求与返回示例。

这是 ORedact 图片、视频打码 API 的接口说明。流程层面的准备工作见《企业 API 接入流程》,这里只讲接口。所有示例都是线上真实接口,字段名以本文为准。

准备:注册并创建 API Key

  1. 打开控制台 console.oredact.com,用邮箱注册(需要邮箱验证码)。注册即开通一个工作空间,并预置「图片打码」「视频打码」两个模板。
  2. 登录后进入「API 密钥」,点「创建」。密钥形如 sk_xxxxxxxx_...,只在创建时完整显示一次,请立即保存。创建时可选限制来源 IP、过期时间和可用模板。
  3. 默认模板只开人脸和车牌打码(模糊)。要改打码样式、强度或开启敏感文字识别,在「作业模板」里编辑或新建模板。

所有接口以 https://api.oredact.com/api/v1 为前缀,鉴权只需一个请求头:

X-API-Key: sk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

返回统一包成一层:code 为 SUCCESS 表示成功,数据在 payload;失败时 code 是错误码,msg 是说明,HTTP 状态码同时表达类别(见文末错误码表)。

{ "code": "SUCCESS", "msg": "Operation completed successfully", "payload": { } }

第 0 步:查模板

提交任务要指定模板,模板决定输入类型(图片或视频)和打码方式。

GET /templates
{
  "code": "SUCCESS",
  "payload": [
    { "uuid": "7c1f…", "name": "图片打码", "inputType": "IMAGE", "ctime": "2026-11-05T08:00:00.000Z" },
    { "uuid": "9a2e…", "name": "视频打码", "inputType": "VIDEO", "ctime": "2026-11-05T08:00:00.000Z" }
  ]
}

第 1 步:上传文件

文件不经过 API 服务器中转,而是用一次性的临时凭证直接传到对象存储,分两次调用。

1a. 申请上传凭证

POST /files/upload-token
Content-Type: application/json

{ "templateUUID": "7c1f…", "filename": "street.jpg", "fileSize": 184233, "fileExtension": ".jpg" }
{
  "code": "SUCCESS",
  "payload": {
    "sessionId": "0b3d…",
    "objectKey": "ws-uuid/template-uuid/0b3d…/f91c….jpg",
    "storageType": "oss",
    "stsToken": {
      "accessKeyId": "STS.…", "accessKeySecret": "…", "stsToken": "…",
      "expiration": "2026-11-05T09:00:00.000Z",
      "region": "oss-cn-hangzhou", "bucket": "…", "endpoint": "https://oss-cn-hangzhou.aliyuncs.com"
    }
  }
}

fileSize 必须是文件的真实字节数,完成上传时会按它校验。凭证只允许写入这一个 objectKey,一小时内有效。

1b. 用凭证上传,再确认完成

用阿里云 OSS SDK(或任何兼容 OSS 签名的客户端)以 stsToken 里的三元凭证把文件 PUT 到 objectKey。Node.js 示例:

const OSS = require('ali-oss');
const { stsToken, objectKey, sessionId } = payload;
const client = new OSS({
  region: stsToken.region, bucket: stsToken.bucket, endpoint: stsToken.endpoint,
  accessKeyId: stsToken.accessKeyId, accessKeySecret: stsToken.accessKeySecret, stsToken: stsToken.stsToken,
});
await client.put(objectKey, '/path/to/street.jpg');

Python 用 oss2.StsAuth(accessKeyId, accessKeySecret, stsToken) 加 Bucket.put_object_from_file(objectKey, path),效果相同。上传完成后告诉服务端:

POST /files/complete

{ "sessionId": "0b3d…", "objectKey": "ws-uuid/template-uuid/0b3d…/f91c….jpg" }

返回 payload.status 为 completed。服务端会核对对象存在且大小等于申请时的 fileSize,不一致返回 400。

第 2 步:提交任务

POST /process

{ "templateUUID": "7c1f…", "sessionId": "0b3d…" }
{ "code": "SUCCESS", "payload": { "taskId": "54930a7b-…", "status": "PENDING" } }

sessionId 必须属于同一模板且已 completed,一个上传会话只能提交一次。提交成功即计入试用额度(图片按张、视频按时长),系统处理失败的任务不计。视频在提交时会读取容器头取时长,只接受 MP4 / MOV(ISO BMFF)容器;读不出时长返回 400 VIDEO_DURATION_UNREADABLE。

第 3 步:查询状态、获取结果

GET /process/{taskId}
{
  "code": "SUCCESS",
  "payload": {
    "taskId": "54930a7b-…",
    "status": "RUNNING",
    "progress": 42,
    "stage": "detecting",
    "resultReady": false,
    "output": null,
    "createdAt": "2026-11-05T08:10:00.000Z",
    "updatedAt": "2026-11-05T08:10:21.000Z",
    "mediaPurgedAt": null
  }
}
  • status:PENDING → RUNNING → COMPLETED 或 FAILED。
  • stage:queued、detecting、rendering、finalizing、completed、failed,比 progress 更适合展示给用户。
  • resultReady 为 true 时可以下载;output 里有成片的存储路径和文件名。
  • 失败时多一个 failure 对象:{ "errorCode": "VIDEO_MEDIA_UNSUPPORTED", "stage": "media_compatibility", "retryable": false }。retryable 为 true 的失败重新提交通常就能过;为 false 的是素材本身的问题。
  • 轮询建议:图片每 2 秒,视频每 5 秒;或者配 Webhook 不轮询。

下载成片

GET /process/{taskId}/download?watermark=false
{ "code": "SUCCESS", "payload": { "downloadUrl": "https://….aliyuncs.com/…?Expires=…", "expiresIn": 900, "watermarked": false } }

downloadUrl 是 15 分钟有效的临时直链,过期再调一次即可,每次调用不重复计费。成片保留在你的工作空间里,直到你调用删除:

POST /process/{taskId}/purge

删除该任务的源文件、成片和检测缓存,只留元数据;幂等,重复调用返回 alreadyPurged: true。建议拿到结果并自行保存后就删。

Webhook 回调

在控制台「Webhook」里配置:回调地址(HTTPS)、要订阅的事件(assembly.completed、assembly.failed,至少一个)、可选只对某个模板生效。保存后得到一个签名密钥 secret。

任务到达终态时,服务端向你的地址 POST 一个 JSON:

{
  "event": "assembly.completed",
  "taskId": "54930a7b-…",
  "status": "COMPLETED",
  "progress": 100,
  "stageEvents": [ { "stage": "detecting", "progress": 10, "timestamp": "…" }, { "stage": "rendering", "progress": 60, "timestamp": "…" } ],
  "output": { "path": "…", "filename": "street.jpg", "fileExtension": ".jpg" },
  "timestamp": "2026-11-05T08:11:02.000Z"
}

失败事件的 status 为 FAILED,output 为 null,并带上面说的 failure 对象。请求头:

请求头 含义
X-Webhook-Event 事件名,和 body 里的 event 相同
X-Webhook-ID 本次投递的编号,重试时不变,用它去重
X-Webhook-Signature sha256= + 用 secret 对原始请求体做 HMAC-SHA256 的十六进制结果

校验签名时要用收到的原始字节计算,不要先解析再序列化。你的接口应在 10 秒内返回 2xx;非 2xx 或超时会在 10 秒、60 秒、5 分钟后各重试一次,三次都失败就停止,任务状态仍可通过查询接口取到。收到回调后再调一次 GET /process/{taskId} 确认,是最稳的做法。

查看用量与额度

GET /usage
{
  "code": "SUCCESS",
  "payload": {
    "period": { "start": "2026-11-01", "end": "2026-11-30" },
    "processCount": 12, "processTimeMs": 184000, "storageBytes": 0,
    "plan": "TRIAL",
    "trial": {
      "endsAt": "2026-11-19T08:00:00.000Z", "expired": false,
      "images": { "limit": 100, "used": 7, "remaining": 93 },
      "videoSeconds": { "limit": 1800, "used": 61, "remaining": 1739 }
    }
  }
}

period 里的三个数是当月成功处理的统计;trial 只在试用计划下出现。

试用额度与计费口径

  • 试用:注册即发放,14 天、100 张图片 + 30 分钟视频(视频不区分分辨率,按实际秒数扣减),每个账号一次。图片按提交张数计;视频按容器时长向上取整到秒累计。处于 PENDING / RUNNING 的任务也占额度,FAILED 的不占。
  • 超额:到期后所有提交返回 403 TRIAL_EXPIRED;额度用完返回 429 QUOTA_EXCEEDED,payload 里有 resource(images 或 videoSeconds)、limit、used、requested。上传凭证接口也会做同样的预检,省掉无效上传。
  • 正式用量:参考价见定价页(图片按张;视频按分钟报价、按秒计费),目前不提供在线直接购买,经样本验证和商务确认后开通,开通时约定数据保留期和并发限额。
  • 不计费的情况:排队、状态查询、回调、下载链接的重复签发,以及系统处理失败。

错误码

鉴权与请求层面的错误直接作为 HTTP 响应返回:

HTTP code 含义与处理
400 BAD_REQUEST 参数缺失或格式错误,msg 里有具体字段
400 VIDEO_DURATION_UNREADABLE 读不出视频时长,换成 MP4 / MOV 容器
401 API_KEY_REQUIRED / API_KEY_NOT_FOUND 没带或带错 X-API-Key
401 API_KEY_REVOKED / API_KEY_EXPIRED 密钥已吊销或过期,到控制台重新创建
401 IP_NOT_ALLOWED 请求 IP 不在密钥白名单内
403 SCOPE_DENIED 密钥被限制了可用模板或输入类型
403 TRIAL_EXPIRED 试用期已结束
404 RESOURCE_NOT_FOUND 模板、上传会话或任务不存在,或不属于当前工作空间
429 QUOTA_EXCEEDED 试用额度用完
429 VERIFICATION_CODE_TOO_FREQUENT 注册验证码一分钟内只能发一次(只在注册时出现)

任务处理层面的失败不改变 HTTP 状态,体现在 status: "FAILED" 和 failure.errorCode 里:

errorCode retryable 含义
VIDEO_MEDIA_UNSUPPORTED 否 容器或编码不支持,转成 H.264 / HEVC 的 MP4 再提交
VIDEO_AUDIO_UNSUPPORTED 否 音轨编码不支持,去掉或转成 AAC
VIDEO_TIMELINE_MISMATCH 否 时间轴异常(可变帧率、起始偏移),重新封装后再提交
DETECTION_CACHE_REFRESH_REQUIRED 是 检测缓存失效,重新提交
PLATE_DETECTOR_UNAVAILABLE / OCR_MODEL_UNAVAILABLE 是 服务端模型暂不可用,稍后重试
VIDEO_DETECTION_INTERNAL_ERROR 是 服务端内部错误,重试仍失败请带 taskId 联系我们

规格与限制

  • 图片:JPEG / PNG / WebP,最高 12MP。
  • 视频:MP4 / MOV 容器,H.264 / HEVC,最高 1080p、30 FPS、单条 5 分钟;4K、高帧率、长视频先联系我们评估。
  • 单个 API Key 的并发提交没有硬上限,但试用期内队列按先来后到处理;需要固定并发的在开通正式用量时约定。
  • 上传凭证和下载链接都有有效期,不要缓存复用;每次都重新申请。

接入过程中的问题,发邮件到 contact@oredact.com,带上 taskId 和返回的 code,我们按工作日回复。

把打码接进你的系统

注册即可用你的素材免费验证效果,再谈接入和费用;自己处理用打码鸭。