AI 工作台 · API返回网站

API 文档

用程序批量生成图片和视频。API 和网站共用同一个账号、同一份积分,价格与网站一致;任务失败会自动退回积分。

快速开始

1. 登录网站,打开「设置」页,在最下面的「API 密钥」里点「生成新密钥」,复制保存(密钥只显示一次)。

2. 所有请求的地址前缀为:

https://niuzhatian.com

3. 试一下查余额:

curl https://niuzhatian.com/v1/balance \
  -H "Authorization: Bearer nzt-你的密钥"

认证

在每个请求的请求头里带上密钥:

Authorization: Bearer nzt-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
密钥等于你的账号积分,请不要放在网页前端代码或公开仓库里。泄露后到「设置」页删除它,再生成一个新的即可,旧密钥会立刻失效。

调用流程

生成是异步的:

① GET /v1/models 查有哪些模型、各自支持的参数和价格
(可选)POST /v1/media 上传视频要参考的图片 / 音频 / 视频,拿到素材编号
② POST /v1/generations 提交任务,立刻拿到任务 id(同时扣积分)
③ 每隔 5–10 秒 GET /v1/generations/{id} 查进度,直到 status 变成 succeeded 或 failed
④ 成功后 GET /v1/generations/{id}/content 下载图片 / 视频

可以一次性并发提交很多任务,不用等上一个完成。

模型列表

GET/v1/models

返回当前可用的全部模型。模型会随平台更新,请以这个接口的返回为准,不要把模型写死在代码里太久。

{
  "object": "list",
  "data": [
    {
      "id": "m-3f8a1c92d4",
      "name": "Seedance 2.5 VIP(720p)",
      "type": "video",
      "resolutions": ["720p"],
      "durations": { "min": 5, "max": 30 },
      "aspect_ratios": ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"],
      "references": { "images": 9, "audios": 3, "videos": 3 },
      "price": { "unit": "per_task", "by_resolution": { "720p": 400 } }
    },
    {
      "id": "m-xxxxxxxxxx",
      "name": "某图片模型",
      "type": "image",
      "sizes": [ { "value": "2K", "price": 30 } ],
      "max_reference_images": 4,
      "price": { "unit": "per_image", "by_size": { "2K": 30 } }
    }
  ]
}
字段说明
id提交任务时填的 model
typeimage 图片 / video 视频
resolutions视频可选分辨率
durations视频可选时长(秒)。可能是列表 [5,10,15],也可能是范围 {"min":5,"max":30}
max_duration_by_resolution(部分模型)不同分辨率的最长时长
aspect_ratios视频可选比例
sizes(部分图片模型)可选尺寸及每张价格
max_reference_images(图片模型)最多可传几张参考图,0 表示不支持
references(视频模型)最多可传的参考图片 / 音频 / 视频数量,0 表示不支持
modes(部分视频模型)支持的参考方式,见下方 generation_mode
price.unitper_task 每条 / per_second 每秒 / per_image 每张,单位都是积分
按秒计费的视频:花费 = 每秒价格 × 时长,向上取整。提交成功后返回的 cost 是实际扣除的积分。

上传参考素材

POST/v1/media?type={类型}&name={文件名}

给视频模型用的参考素材要先上传,拿到素材编号后再提交任务。请求体直接放文件内容(不是表单),并设置对应的 Content-Type。

type格式大小上限
imageJPG / PNG / WEBP(建议边长 300–6000 像素)20MB
audio常见音频格式(推荐 MP3)15MB
videoMP450MB
curl "https://niuzhatian.com/v1/media?type=image&name=hero.jpg" \
  -H "Authorization: Bearer nzt-你的密钥" \
  -H "Content-Type: image/jpeg" \
  --data-binary @hero.jpg

返回:

{ "id": "xxxxxxxx:rAbCdEf...", "type": "image" }
· 上传不扣积分,但账号余额需要大于 0。
· 素材编号请在 3 天内使用,同一个素材可以在多个任务里重复使用。
· 部分模型对参考视频有时长要求(例如参考视频时长 + 生成时长不超过 25 秒),超出时提交会报错并且不扣积分。

提交任务

POST/v1/generations

请求体为 JSON(Content-Type: application/json)。

生成视频

参数必填说明
model是模型 id
prompt是画面描述
resolution否分辨率,如 720p,默认第一个
duration否时长(秒)。不在可选范围内时自动取最接近的值
aspect_ratio否比例,如 16:9、9:16
media否参考素材数组,每项是上传接口返回的 {"id": "...", "type": "image"},数量不超过模型的 references。在 prompt 里用 @图片1、@音频1、@视频1 指代它们(按同类素材在数组里的顺序编号,从 1 开始)
generation_mode否模型带 modes 时可选:reference 普通参考(默认);first_frame 首帧(只传 1 张图,作为视频开头);first_last_frame 首尾帧(只传 2 张图,第 1 张开头、第 2 张结尾)
curl https://niuzhatian.com/v1/generations \
  -H "Authorization: Bearer nzt-你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"model":"m-3f8a1c92d4","prompt":"清晨的海边,一只金毛在奔跑,电影感","duration":10,"aspect_ratio":"9:16"}'

带参考素材生成视频

curl https://niuzhatian.com/v1/generations \
  -H "Authorization: Bearer nzt-你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"model":"m-3f8a1c92d4","prompt":"@图片1 是主角,在海边奔跑,背景音乐用 @音频1","duration":10,
       "media":[{"id":"上传返回的图片编号","type":"image"},{"id":"上传返回的音频编号","type":"audio"}]}'

生成图片

参数必填说明
model是模型 id
prompt是画面描述
size否模型带 sizes 时填其中的 value,默认第一个
reference_images否参考图数组(不超过 max_reference_images)。每张为 base64 数据:data:image/jpeg;base64,....,支持 JPG / PNG / WEBP,建议单张不超过 5MB。yk: 开头的模型也可以直接填公开的 https 图片地址
curl https://niuzhatian.com/v1/generations \
  -H "Authorization: Bearer nzt-你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"model":"模型id","prompt":"一杯冰美式,白色背景,商业摄影"}'

返回

{
  "id": "tQ2x9vLm4kP7wZ",
  "type": "video",
  "model": "m-3f8a1c92d4",
  "status": "queued",
  "cost": 400
}
可以在请求头加 Idempotency-Key: 任意唯一字符串,网络重试时避免重复提交。

查询任务

GET/v1/generations/{id}
{
  "id": "tQ2x9vLm4kP7wZ",
  "type": "video",
  "model": "Seedance 2.5 VIP(720p)",
  "status": "succeeded",
  "progress": null,
  "error": null,
  "cost": 400,
  "result_url": "https://niuzhatian.com/v1/generations/tQ2x9vLm4kP7wZ/content",
  "created_at": "2026-11-02T08:00:00.000Z"
}
status含义
queued排队中
processing生成中(部分模型会在 progress 里给出进度)
succeeded完成,可以从 result_url 下载
failed失败,原因在 error,积分已自动退回(refunded: true)
canceled被平台取消,积分已退回

建议每 5–10 秒查一次。图片一般几十秒,视频一般几分钟到十几分钟。

下载结果

GET/v1/generations/{id}/content

返回图片或视频文件本身,同样需要带 Authorization。加 ?dl=1 时可能会 302 跳转到平台的下载地址,请让你的程序跟随跳转(curl 加 -L)。

curl -L https://niuzhatian.com/v1/generations/tQ2x9vLm4kP7wZ/content \
  -H "Authorization: Bearer nzt-你的密钥" -o result.mp4
生成结果不保证长期保存,请完成后尽快下载到自己的存储里。

查询余额

GET/v1/balance
{ "balance": 12800 }

错误码

出错时返回对应的 HTTP 状态码,响应体为:

{ "error": { "message": "积分不足:这个任务需要 400 积分,当前只有 120 积分,请先到「积分」页兑换" } }
状态码含义建议
400参数不对、模型不存在或暂未开放按 message 修改后再提交
401密钥无效、已删除或被停用检查密钥
402积分不足到网站「积分」页兑换
403密钥不能用于这个接口只能调用本文档列出的接口
404任务不存在,或不是这个账号的任务检查 id
409任务还没完成就去下载等 succeeded 后再下载
429同时进行中的任务太多等前面的完成后再提交
502上游平台暂时连不上稍后重试;提交阶段失败不会扣积分

限制与计费

· 积分与网站共用,价格与网站一致;提交时扣除,任务失败或被取消自动退回。
· 每个账号默认最多同时有 1000 个进行中的任务,需要更多请联系站长。
· 每个账号最多 5 个 API 密钥,可随时在「设置」页删除。
· API 生成的任务也会出现在网站的积分记录里。
· 视频的参考素材先用 /v1/media 上传,上传不扣积分。

完整示例(Python)

import time, requests

BASE = "https://niuzhatian.com"
H = {"Authorization": "Bearer nzt-你的密钥"}

# 1. 提交
r = requests.post(f"{BASE}/v1/generations", headers=H, json={
    "model": "m-3f8a1c92d4",
    "prompt": "清晨的海边,一只金毛在奔跑,电影感",
    "duration": 10,
    "aspect_ratio": "9:16",
})
r.raise_for_status()
task = r.json()
print("已提交", task["id"], "花费", task["cost"], "积分")

# 2. 等待完成
while True:
    t = requests.get(f"{BASE}/v1/generations/{task['id']}", headers=H).json()
    if t["status"] in ("succeeded", "failed", "canceled"):
        break
    time.sleep(8)

# 3. 下载
if t["status"] == "succeeded":
    data = requests.get(t["result_url"], headers=H).content
    open(task["id"] + ".mp4", "wb").write(data)
    print("已保存")
else:
    print("失败:", t["error"], "(积分已退回)")

带参考图生成视频(Python)

def upload(path, kind, ctype):
    with open(path, "rb") as f:
        r = requests.post(f"{BASE}/v1/media", params={"type": kind, "name": path},
                          headers={**H, "Content-Type": ctype}, data=f.read())
    r.raise_for_status()
    return r.json()          # {"id": "...", "type": "image"}

hero = upload("hero.jpg", "image", "image/jpeg")
r = requests.post(f"{BASE}/v1/generations", headers=H, json={
    "model": "m-3f8a1c92d4",
    "prompt": "@图片1 是主角,在雨夜的街头回头微笑",
    "duration": 10,
    "media": [hero],
})
print(r.json())

批量并发提交

from concurrent.futures import ThreadPoolExecutor

prompts = ["海边日出", "雪山日落", "城市夜景"]  # 可以是几百条

def submit(p):
    r = requests.post(f"{BASE}/v1/generations", headers=H,
                      json={"model": "m-3f8a1c92d4", "prompt": p, "duration": 5})
    return r.json()

with ThreadPoolExecutor(20) as ex:
    tasks = list(ex.map(submit, prompts))
print([t.get("id") or t.get("error") for t in tasks])