Developer Docs

查询与下载

轮询任务状态、状态枚举、失败原因排查与成片下载。

查询与下载

五、查询任务状态

GET https://newapi.nskeven.uk/v1/video/generations/{task_id}
curl 'https://newapi.nskeven.uk/v1/video/generations/task_385412' \
  -H 'Authorization: Bearer sk-xxx'

返回示例

处理中

{
  "code": "success",
  "message": "",
  "data": {
    "id": 883,
    "task_id": "task_385412",
    "status": "IN_PROGRESS",
    "progress": "45%",
    "fail_reason": "",
    "result_url": "",
    "created_at": 1790224802,
    "finish_time": 0
  }
}

已完成

{
  "code": "success",
  "message": "",
  "data": {
    "id": 883,
    "task_id": "task_385412",
    "status": "SUCCESS",
    "progress": "100%",
    "fail_reason": "",
    "result_url": "https://newapi.nskeven.uk/v1/videos/task_385412/content",
    "created_at": 1790224802,
    "finish_time": 1790227431
  }
}

已失败

{
  "code": "success",
  "message": "",
  "data": {
    "id": 883,
    "task_id": "task_385412",
    "status": "FAILURE",
    "progress": "100%",
    "fail_reason": "生成被拒绝,内容安全审核未通过,修改提示词或素材后重试",
    "result_url": "",
    "created_at": 1790224802,
    "finish_time": 1790224804
  }
}

返回字段说明

字段类型说明
codestring固定为 success
data.idnumber任务自增 ID
data.task_idstring任务 ID,用于继续查询与下载
data.statusstring任务状态,取值见下表
data.progressstring进度百分比。仅供参考,常见 "100%",不要用它判断任务是否结束
data.fail_reasonstring失败原因。可能是中文或英文,详见下方说明。⚠️ 不要用它判断任务是否成功 —— 任务成功时该字段通常为空字符串,但不保证一定为空,判定一律以 data.status 为准
data.result_urlstring完成后的成片地址;未完成或失败时为空。GET 时须附带 Authorization 头,详见「关于 result_url」
data.created_atnumber创建时间戳,单位秒
data.finish_timenumber完成时间戳,单位秒;未完成时为 0
data.dataobject任务原始回执,内容已清洗,仅供排障,请勿用于任何逻辑判断

data.data 内部字段与外层同名但取值不同(例如内部 status 可能是 SUCCEEDED,外层是 SUCCESS),取值随模型变化。判断任务状态一律用 data.status。

关于 progress:常见值 "100%",排队中也可能出现,不可用于判断完成。

状态说明

data.status含义处理方式
NOT_START尚未开始继续轮询
SUBMITTED已提交继续轮询
QUEUED排队中继续轮询
IN_PROGRESS生成中继续轮询
SUCCESS已完成转下载成片
FAILURE失败读取 data.fail_reason
UNKNOWN状态未知继续轮询;长时间不变请联系我们

轮询建议

间隔 10~20 秒(sd-2-* 系列建议 ≥20 秒)。一般模型约 10 分钟内结束,超长时长约 30 分钟。超时未结束请保留 task_id 联系我们,不要重复提交。

失败原因

优先读取 data.fail_reason。若内容过于笼统,更具体的原因通常在 data.data 内部。

fail_reason 的文案由各模型服务返回,可能为中文或英文,措辞不固定。请不要用「关键词完全匹配」判断失败类型,也不要用它是否为空判断任务成败 —— 判断状态一律用 data.status。建议原样展示该文本,并按下面的分类决定是否重试。

提示信息(示例)含义建议处理
哎呀,出了一点小状况,请稍后再试。模型服务临时波动可稍后重试
Seedance blocked this request due to moderation rules.内容审核未通过(英文)修改提示词或素材
task failed未给出具体原因可重试一次;持续失败请联系我们
请求失败,输出视频可能涉及版权限制输出内容涉及版权更换素材 / 去掉受版权保护的音频
视频生成失败,请调整提示词或参考素材后重试,本次不会扣费。通用生成失败修改后重试;不扣费
参考图片被识别为可能包含真人,当前模型拒绝直接使用…素材含真人被拒更换素材,或改用支持真人参考的模型
task_failed: Upstream submit failed (400): …提交参数被拒检查参数与素材格式
OutputVideoSensitiveContentDetected.PolicyViolation: …输出内容触发审核(英文)修改提示词
生成失败:请重新提交任务。请检查上传的素材和引用的格式符合标准。素材或引用格式不符检查素材 URL 与 @ 引用
生成结果疑似包含敏感内容已被过滤…结果被内容过滤修改提示词后重试
task_failed: Reference material @ImageN could not be prepared参考素材无法抓取检查素材 URL 是否公网可访问、Content-Type 是否正确
NOT_ENOUGH_ALLOCATE_CREDIT_QUOTA: 积分分配额度不足账户额度不足联系管理员充值
InvalidParam: 不支持「文本+音频」组合(需配合图片或视频)参数组合不被支持按模型要求调整参数组合
文件响应头不匹配,修改后重试素材 Content-Type 不正确修正素材响应头
系统繁忙,请稍后重试平台临时繁忙稍后重试
图片被提供者屏蔽素材内容未通过安全审核更换素材

处理原则:涉及内容审核 / 素材问题的,修改后重试才有意义;标注「本次不会扣费」的失败,预扣费用会自动退回。


六、下载成片

GET https://newapi.nskeven.uk/v1/videos/{task_id}/content
curl -o out.mp4 'https://newapi.nskeven.uk/v1/videos/task_385412/content' \
  -H 'Authorization: Bearer sk-xxx'

返回视频文件数据流,直接写入文件即可。大文件请预留足够超时。

另有带下载头的等价端点,适合浏览器直接触发下载:

GET /v1/videos/{task_id}/download

关于 result_url

任务 SUCCESS 后,查询响应里的 data.result_url 恒为本平台地址,可直接用于下载:

https://newapi.nskeven.uk/v1/videos/{task_id}/content

推荐做法:优先调用本节 /v1/videos/{task_id}/content 接口下载(行为最稳定)。若使用 result_url,请原样直接 GET 并附带 Authorization 头(与调用查询接口使用同一个 Key)。

请在 SUCCESS 后尽快下载并转存到你自己的存储。成片仅保留约 10 小时,过期后无法再获取。

完整调用示例(Python)

import time, requests

BASE = "https://newapi.nskeven.uk"
H = {"Authorization": "Bearer sk-xxx"}

tid = requests.post(f"{BASE}/v1/video/generations", headers=H, json={
    "model": "even-sd2.5-A",
    "prompt": "一只猫在雨夜霓虹街道奔跑,电影感",
    "seconds": "8", "resolution": "720p", "aspect_ratio": "9:16",
}).json()["id"]

while True:
    r = requests.get(f"{BASE}/v1/video/generations/{tid}", headers=H).json()["data"]
    print(r["status"], r["progress"])
    if r["status"] == "SUCCESS":
        break
    if r["status"] == "FAILURE":
        raise RuntimeError(f"生成失败:{r['fail_reason']}")
    time.sleep(15)

with requests.get(f"{BASE}/v1/videos/{tid}/content", headers=H, stream=True) as resp:
    resp.raise_for_status()
    with open("out.mp4", "wb") as f:
        for chunk in resp.iter_content(1 << 20):
            f.write(chunk)