鸣泽 AI 视频

接口文档

基址 https://api.mingzemanju888.bond,所有业务接口在 /v1 下。创建任务立即返回任务编号,之后轮询状态或等待回调,成功后下载结果。

  1. 在 控制台 的「API Key」页创建 Key(以 mz_live_ 开头,明文只显示一次)。
  2. 先查余额确认鉴权:
curl -sS https://api.mingzemanju888.bond/v1/balance \
  -H "Authorization: Bearer mz_live_你的Key"
  1. 提交一条 15 秒视频(每个新任务用新的 Idempotency-Key):
curl -sS -X POST https://api.mingzemanju888.bond/v1/videos \
  -H "Authorization: Bearer mz_live_你的Key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-20261011-0001" \
  -d '{"prompt":"雨后的城市街道,镜头缓慢前移","duration":15,"aspect_ratio":"9:16"}'

接入须知

  • 鉴权:请求头 Authorization: Bearer mz_live_…。控制台登录密码和兑换码不能代替 Key。
  • 异步:创建成功返回 HTTP 202 和任务对象,不会等生成完。202 不是失败。
  • 幂等:创建视频/图片必须带 Idempotency-Key(1–64 字符)。超时、断网、空响应时用同一个 Key + 同一个请求体重试,会返回原任务,不会重复扣费;同一个 Key 换了请求体返回 409。
  • 轮询:每 3–5 秒查一次,总等待预算至少 30 分钟(30 秒视频更久)。单次 HTTP 读超时建议 ≥ 60 秒。
  • 结果保存 24 小时,请及时下载或使用回调。下载链接带签名,有效期 1 小时,过期重新查询任务即可拿到新链接。
  • 所有响应都带 X-Request-ID,反馈问题时请一并提供。

接口一览

方法与路径用途鉴权
GET /v1/catalog商品、比例、参考图上限与公开价否
GET /v1/pricing不带 Key 为公开价;带 Key 为你的价格可选
GET /v1/balance余额、冻结、可用是
GET /v1/usage?from=&to=按天用量:调用次数、各商品成功数、扣费是
POST /v1/references上传参考图,返回 ref_…是
POST /v1/videos创建视频任务(15 / 30 秒)是
POST /v1/images创建图片任务(1–4 张)是
GET /v1/tasks/{id}查询任务:状态、进度、扣费、结果链接是
GET /v1/tasks任务列表(status、before、limit)是
POST /v1/tasks/{id}/cancel取消任务是
GET /v1/tasks/{id}/results/{n}302 跳转到结果下载链接是
POST /v1/redeem兑换码充值 {"code":"MZ-…"}是

创建视频 POST /v1/videos

字段类型说明
promptstring必填,1–4000 字
durationinteger必填,15 或 30(整数,不是 "15s")
aspect_ratiostring16:9(默认)、9:16、1:1、21:9
reference_idsstring[]可选,先上传参考图得到的 ref_…,最多 10 张
callback_urlstring可选,https 地址,任务结束时推送
metadataobject可选,原样返回,最多 2 KB

返回 202:

{"id":"tsk_3f6c…","object":"task","sku":"video-15s","status":"queued","progress":0,
 "billing":{"unit":"cent","unit_price":500,"quantity":1,"held":500,"charged":0,"refunded":0},
 "results":[],"created_at":"2026-10-11T03:00:00Z"}

创建图片 POST /v1/images

字段:prompt(必填)、count(1–4,默认 1)、aspect_ratio(1:1 默认,另有 2:3、3:4、4:3、3:2、9:16、16:9、21:9、auto)、reference_ids、callback_url、metadata。按实际交付张数扣费。

上传参考图 POST /v1/references

jpg / png / webp,单张 ≤ 10 MB,按文件内容识别格式。可用 multipart 的 file 字段,或直接把图片字节作为请求体。有效期 24 小时,只能被你自己的任务使用。

curl -sS -X POST https://api.mingzemanju888.bond/v1/references \
  -H "Authorization: Bearer mz_live_你的Key" \
  -F "file=@reference.png"
# {"id":"ref_9a1b…","object":"reference","mime":"image/png","size":182233,"expires_at":"…"}

查询与下载

状态:queued 排队、dispatched 已派发、running 生成中、unknown 平台已受理但结果待核对(继续轮询)、succeeded 成功、failed 失败、cancelled 已取消。

成功后 results[n].url 是带签名的下载地址(无需 Key,支持断点续传),也可以请求 GET /v1/tasks/{id}/results/{n} 跳转下载。

curl -sS https://api.mingzemanju888.bond/v1/tasks/tsk_3f6c… -H "Authorization: Bearer mz_live_你的Key"

取消:排队中的任务立即取消并退款;生成中的任务会通知工作机,若平台尚未受理则取消退款,已受理的会继续完成并正常计费。

完成回调

填写 callback_url 后,任务成功、失败或取消时会 POST {"event":"task.succeeded","task":{…}}。失败按 1 分钟、5 分钟、30 分钟、2 小时、6 小时重试。请求头:

X-MZ-Event: task.succeeded
X-MZ-Signature: t=1760151600,v1=hex(HMAC-SHA256(签名密钥, "t.请求体"))

签名密钥在创建 Key 时与 Key 一起显示(whsec_…)。验证示例(Python):

import hmac, hashlib
def verify(secret: str, body: bytes, header: str) -> bool:
    parts = dict(item.split("=", 1) for item in header.split(","))
    expected = hmac.new(secret.encode(), parts["t"].encode() + b"." + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

计费与余额

金额字段都是整数,单位“分”(1 积分 = 0.01 元)。提交时冻结、成功扣款、失败退回;余额不足返回 402,不排队。GET /v1/balance 返回 balance(含冻结)、held、available。

错误码

错误体:{"error":{"code":"insufficient_balance","message":"可用余额不足","request_id":"…"}}

HTTPcode怎么办
401invalid_key检查 Authorization 头和 Key
402insufficient_balance充值后重试
403key_disabled / customer_frozen / sku_not_allowed / ip_not_allowed在控制台检查 Key 状态与限制
404not_found任务不存在或不属于你
409idempotency_conflict / invalid_state同一 Idempotency-Key 换了请求体;或当前状态不能操作
410expired结果已过保存期限
422invalid_request / sku_not_priced按 message 修正字段
429rate_limited / concurrency_limited / daily_limit按 Retry-After 等待后重试

Python 完整示例

Python 3.10+,无需第三方包。保存操作编号后再提交,中断后重新运行会继续原任务,不会重复下单。

import json, os, time, uuid, urllib.request
from pathlib import Path

BASE = os.environ.get("MZ_BASE", "https://api.mingzemanju888.bond")
KEY = os.environ["MZ_KEY"]
STATE = Path("order-001.json")

def call(method, path, body=None, headers=None):
    request = urllib.request.Request(BASE + path, method=method,
        data=None if body is None else json.dumps(body).encode(),
        headers={"Authorization": "Bearer " + KEY, "Content-Type": "application/json", **(headers or {})})
    with urllib.request.urlopen(request, timeout=90) as response:
        return json.loads(response.read() or b"{}")

state = json.loads(STATE.read_text()) if STATE.exists() else {
    "key": uuid.uuid4().hex, "body": {"prompt": "海边日落,镜头缓慢推进", "duration": 15, "aspect_ratio": "9:16"}}
STATE.write_text(json.dumps(state))
if "id" not in state:
    task = call("POST", "/v1/videos", state["body"], {"Idempotency-Key": state["key"]})
    state["id"] = task["id"]; STATE.write_text(json.dumps(state))

while True:
    task = call("GET", "/v1/tasks/" + state["id"])
    if task["status"] == "succeeded":
        urllib.request.urlretrieve(task["results"][0]["url"], "result.mp4"); print("saved result.mp4"); break
    if task["status"] in ("failed", "cancelled"):
        print("ended:", task["status"], task.get("error")); break
    time.sleep(5)