LoopToken
视频生成

HappyHorse 系列

HappyHorse 文生视频、图生视频、参考生视频与视频编辑 API

HappyHorse 系列通过 LoopToken 统一视频接口调用。本文包含完整请求协议、模型差异、素材限制、任务查询、错误处理和计费说明。

系列概览

模型用途
happyhorse-1.0-t2v根据文本提示词生成视频
happyhorse-1.0-i2v以一张首帧图片为基础生成视频
happyhorse-1.0-r2v使用普通参考图片驱动视频生成
happyhorse-1.0-video-edit根据文本指令编辑已有视频,可附带参考图片

所有模型均采用异步任务模式:提交成功不代表视频已经生成。客户端需要保存 LoopToken 返回的 task_id,再查询任务直到进入终态。

模型能力矩阵

“不在稳定兼容范围”表示该能力可能被拒绝或行为发生变化,生产环境不应依赖。

能力t2vi2vr2vvideo-edit
文本提示词必填可选必填必填,作为编辑指令
首帧图片不支持必填,1 张不支持不支持
尾帧图片不支持不在稳定兼容范围不支持不支持
普通参考图片不支持不支持1-9 张0-5 张
参考视频不支持不支持不在稳定兼容范围不支持
待编辑视频不支持不支持不支持必填,1 个
Base64 图片不适用支持 data URL支持 data URL仅参考图片支持 data URL
Base64 视频不适用不适用不在稳定兼容范围不支持
自动生成音频不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围
自定义音频不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围不支持单独音频素材
分辨率720P1080P720P1080P720P1080P720P1080P
宽高比ratio 指定跟随首帧ratio 指定沿用输入视频比例
时长3-15 秒,默认 5 秒3-15 秒,默认 5 秒3-15 秒,默认 5 秒跟随输入片段,最长输出 15 秒
水印支持支持支持支持
随机种子支持支持支持支持
回调通知支持支持支持支持
专属能力多种输出比例无提示词也可生成提示词引用多张参考图风格转换、主体或服装替换、画面修改

调用流程

  1. 调用 POST /v1/videos/generations 提交任务。
  2. 成功时返回 HTTP 202 和 LoopToken 平台任务对象。
  3. 使用 GET /v1/tasks/{task_id} 查询状态。
  4. pending 表示排队中;running 表示生成或结果处理中;两者都应继续轮询。
  5. succeeded 表示生成成功,此时读取 video_urlfailed 表示失败,此时读取 error
  6. 推荐每 5-10 秒查询一次,不要高频请求。
  7. video_url 只在 expires_at 前有效,请及时下载并转存到自己的存储服务。

task_id 是 LoopToken 平台任务 ID。客户端只能使用提交响应中的该 ID 查询任务。

请求头

Header必填说明
AuthorizationBearer <your-api-key>
Content-Typeapplication/json

公共请求参数

字段路径类型必填默认值适用模型枚举或范围说明
modelstring-全部本页四个精确模型名之一大小写敏感
inputobject-全部-模型输入对象
input.promptstring视模型-全部最多 5000 个非中文字符或 2500 个中文字符t2v、r2v、video-edit 必填;i2v 可选
input.mediaarray视模型-i2v、r2v、video-edit结构按模型区分素材类型和数量不能跨模型混用
parametersobject{}全部-生成参数
parameters.durationinteger5t2v、i2v、r2v3-15连续整数秒;video-edit 不使用此字段控制输出时长
parameters.resolutionstring1080P全部720P1080P提交响应可能先显示平台预估档位;终态以实际结果为准
parameters.ratiostring16:9t2v、r2v见模型表i2v 跟随首帧;video-edit 跟随输入视频
parameters.watermarkbooleantrue全部truefalse是否在输出视频中添加模型水印
parameters.seedinteger随机全部0-2147483647相同种子有助于复现,但不保证完全一致
callback_urlstring-全部公网 HTTPS URL任务状态变化时接收通知;不得使用本机、内网或包含凭据的地址

参数组合规则

  • t2v 不接受图片或视频素材。
  • i2v 必须且只能包含一个 first_frame,不要传 ratio
  • r2v 的稳定范围是 1-9 个 reference_image;参考视频和图视频混合输入不在稳定兼容范围。
  • video-edit 必须包含且只能包含一个 video,并可附加 0-5 个 reference_image
  • video-edit 的输出时长和比例来自输入视频,不要把 t2v 的 durationratio 直接用于该模型。
  • LoopToken 会异步处理模型输入。部分模型参数问题可能在任务创建后以 failed 终态返回,而不是同步 HTTP 400。

happyhorse-1.0-t2v

字段表

字段类型必填默认值取值说明
modelstring-happyhorse-1.0-t2v模型名
input.promptstring-长度限制见公共参数描述主体、动作、环境、镜头和风格
parameters.resolutionstring1080P720P1080P分辨率档位
parameters.ratiostring16:916:99:161:14:33:44:55:49:2121:9与分辨率档位组合确定画布
parameters.durationinteger53-15视频秒数,支持连续整数
parameters.watermarkbooleantrue-是否添加水印
parameters.seedinteger随机0-2147483647随机种子

音频、反向提示词和 Prompt 智能改写均不在该模型的稳定兼容范围。不要提交 negative_promptprompt_extend 或音频字段并依赖其效果。

最简请求:

{"model":"happyhorse-1.0-t2v","input":{"prompt":"白色纸飞机穿过清晨的薄雾"}}

完整请求:

{
  "model": "happyhorse-1.0-t2v",
  "input": {"prompt": "白色纸飞机穿过清晨的薄雾,镜头平稳跟随"},
  "parameters": {
    "resolution": "720P",
    "ratio": "16:9",
    "duration": 3,
    "watermark": false,
    "seed": 12345
  }
}
curl https://api.vibelab.me/v1/videos/generations \
  -H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"happyhorse-1.0-t2v","input":{"prompt":"白色纸飞机穿过清晨的薄雾"},"parameters":{"resolution":"720P","ratio":"16:9","duration":3,"watermark":false}}'

Python 和 Node.js 的完整提交轮询代码见本文“完整轮询示例”,将其中的请求体替换为上面的 JSON 即可。

happyhorse-1.0-i2v

字段表

字段类型必填默认值取值说明
modelstring-happyhorse-1.0-i2v模型名
input.promptstring-长度限制见公共参数省略时仅根据首帧生成
input.mediaarray-1 个元素首帧数组
input.media[0].typestring-first_frame固定值
input.media[0].urlstring-公网 HTTP/HTTPS URL 或图片 data URL首帧图片
parameters.resolutionstring1080P720P1080P输出比例近似跟随首帧
parameters.durationinteger53-15视频秒数
parameters.watermarkbooleantrue-是否添加水印
parameters.seedinteger随机0-2147483647随机种子

仅首帧请求:

{"model":"happyhorse-1.0-i2v","input":{"media":[{"type":"first_frame","url":"https://assets.example.com/first-frame.jpg"}]}}

首帧加提示词:

{
  "model": "happyhorse-1.0-i2v",
  "input": {
    "prompt": "人物轻轻转头,背景树叶随风摆动",
    "media": [{"type": "first_frame", "url": "https://assets.example.com/first-frame.jpg"}]
  },
  "parameters": {"resolution": "720P", "duration": 3, "watermark": false}
}

Base64 图片:

{
  "model": "happyhorse-1.0-i2v",
  "input": {"media": [{"type": "first_frame", "url": "data:image/png;base64,iVBORw0KGgo..."}]}
}
curl https://api.vibelab.me/v1/videos/generations \
  -H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"happyhorse-1.0-i2v","input":{"prompt":"人物轻轻转头","media":[{"type":"first_frame","url":"https://assets.example.com/first-frame.jpg"}]},"parameters":{"resolution":"720P","duration":3}}'

happyhorse-1.0-r2v

稳定字段表

字段类型必填默认值取值说明
modelstring-happyhorse-1.0-r2v模型名
input.promptstring-长度限制见公共参数使用 [Image N] 引用参考图
input.mediaarray-1-9 个元素稳定范围内全部为参考图
input.media[].typestring-reference_image参考图片
input.media[].urlstring-公网 URL 或图片 data URL图片按数组顺序编号
parameters.resolutionstring1080P720P1080P分辨率档位
parameters.ratiostring16:9与 t2v 相同的比例集合输出比例
parameters.durationinteger53-15视频秒数
parameters.watermarkbooleantrue-是否添加水印
parameters.seedinteger随机0-2147483647随机种子

图片从 1 开始独立编号:第一个 reference_image[Image 1],第二个是 [Image 2]。提示词应明确每张图片承担的主体、服装、物体或场景作用。

单参考图:

{"model":"happyhorse-1.0-r2v","input":{"prompt":"[Image 1] 中的人物轻轻转头","media":[{"type":"reference_image","url":"https://assets.example.com/person.jpg"}]},"parameters":{"resolution":"720P","ratio":"16:9","duration":3}}

多参考图:

{
  "model": "happyhorse-1.0-r2v",
  "input": {
    "prompt": "[Image 1] 中的人物拿起 [Image 2] 中的折扇,镜头缓慢推近",
    "media": [
      {"type": "reference_image", "url": "https://assets.example.com/person.jpg"},
      {"type": "reference_image", "url": "https://assets.example.com/fan.jpg"}
    ]
  },
  "parameters": {"resolution": "720P", "ratio": "16:9", "duration": 3, "watermark": false}
}

Base64 参考图:

{"model":"happyhorse-1.0-r2v","input":{"prompt":"[Image 1] 中的花朵缓缓绽放","media":[{"type":"reference_image","url":"data:image/jpeg;base64,/9j/4AAQSkZJRg..."}]}}

参考视频与混合素材

reference_video、参考视频编号方式、参考视频数量,以及图片和视频混合输入均不在 happyhorse-1.0-r2v 的稳定兼容范围。以下结构仅用于识别不稳定输入,不应作为生产请求:

{"type":"reference_video","url":"https://assets.example.com/reference.mp4"}
curl https://api.vibelab.me/v1/videos/generations \
  -H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"happyhorse-1.0-r2v","input":{"prompt":"[Image 1] 中的人物向前行走","media":[{"type":"reference_image","url":"https://assets.example.com/person.jpg"}]},"parameters":{"resolution":"720P","ratio":"16:9","duration":3}}'

happyhorse-1.0-video-edit

字段表

字段类型必填默认值取值说明
modelstring-happyhorse-1.0-video-edit模型名
input.promptstring-长度限制见公共参数编辑指令
input.mediaarray-1 个视频 + 0-5 张图片素材数组
视频对象 typestring-video有且仅有一个
视频对象 urlstring-公网 HTTP/HTTPS URL不支持 Base64 视频
视频对象 role---LoopToken 稳定协议不使用 role 字段
图片对象 typestring-reference_image可选参考图
图片对象 urlstring-公网 URL 或图片 data URL最多 5 张
parameters.resolutionstring1080P720P1080P输出分辨率档位
parameters.watermarkbooleantrue-是否添加水印
parameters.audio_settingstringautoautoorigin自动处理音频或保留原视频音频
parameters.seedinteger随机0-2147483647随机种子

支持的稳定编辑场景包括整体风格转换、背景或画面内容修改、服装替换、主体外观替换。复杂局部编辑的效果具有随机性,应先用代表性素材验证。

输入视频为 MP4 或 MOV,建议 H.264;时长 3-60 秒、文件不超过 100MB、短边至少 360 像素、长边不超过 4096 像素、宽高比 1:2.5 至 2.5:1、帧率高于 8fps。输入超过 15 秒时只取前 15 秒,输出最长 15 秒;输入不超过 15 秒时输出时长跟随输入片段。输出比例沿用输入视频。

仅视频加编辑指令:

{"model":"happyhorse-1.0-video-edit","input":{"prompt":"将视频整体调整为复古胶片风格","media":[{"type":"video","url":"https://assets.example.com/input.mp4"}]}}

视频加单张参考图(服装替换):

{
  "model": "happyhorse-1.0-video-edit",
  "input": {
    "prompt": "让视频中的主体穿上参考图片中的条纹外套",
    "media": [
      {"type": "video", "url": "https://assets.example.com/input.mp4"},
      {"type": "reference_image", "url": "https://assets.example.com/jacket.jpg"}
    ]
  },
  "parameters": {"resolution": "720P", "watermark": false, "audio_setting": "origin"}
}

视频加多张参考图:

{
  "model": "happyhorse-1.0-video-edit",
  "input": {
    "prompt": "将背景替换为第一张图片的室内场景,并采用第二张图片的服装",
    "media": [
      {"type": "video", "url": "https://assets.example.com/input.mp4"},
      {"type": "reference_image", "url": "https://assets.example.com/room.jpg"},
      {"type": "reference_image", "url": "data:image/webp;base64,UklGR..."}
    ]
  }
}

风格迁移只需将 input.prompt 改为例如“将视频整体调整为柔和的水彩画风格”,无需参考图。

curl https://api.vibelab.me/v1/videos/generations \
  -H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"happyhorse-1.0-video-edit","input":{"prompt":"将视频整体调整为柔和的水彩画风格","media":[{"type":"video","url":"https://assets.example.com/input.mp4"}]},"parameters":{"resolution":"720P","watermark":false}}'

素材限制

素材公网 URLBase64MIME/格式大小时长分辨率与比例数量
首帧图片HTTP/HTTPSdata URLimage/jpegimage/pngimage/webp;JPEG/JPG/PNG/WEBP≤20MB-宽高均 ≥300px;比例 1:2.5 至 2.5:11
普通参考图片HTTP/HTTPSdata URLimage/jpegimage/pngimage/webp;JPEG/JPG/PNG/WEBP≤20MB/张-宽高均 ≥300px;比例 1:2.5 至 2.5:1r2v 1-9;编辑 0-5
参考视频不在稳定兼容范围不支持不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围不在稳定兼容范围
待编辑视频HTTP/HTTPS不支持MP4、MOV,建议 H.264≤100MB3-60 秒短边 ≥360px、长边 ≤4096px;比例 1:2.5 至 2.5:1;>8fps1

素材 URL 必须能被公网直接访问,在任务处理期间保持有效,不得依赖登录 Cookie、来源页、防盗链 Header 或内网 DNS。Base64 图片必须使用完整 data:{MIME};base64,{data} 格式。

分辨率、比例与时长

模型分辨率比例最小时长最大时长默认时长
happyhorse-1.0-t2v720P1080P通过 resolution + ratio 指定3155
happyhorse-1.0-i2v720P1080P跟随首帧,不传 ratio3155
happyhorse-1.0-r2v720P1080P通过 resolution + ratio 指定3155
happyhorse-1.0-video-edit720P1080P沿用输入视频3 秒输入60 秒输入;最长输出 15 秒跟随输入片段

t2v 和 r2v 支持 16:99:161:14:33:44:55:49:2121:9。3-15 秒范围内可传连续整数。非法组合可能在提交时返回错误,也可能创建任务后进入 failed

完整轮询示例

Python

import os
import time
import requests

BASE_URL = "https://api.vibelab.me"
HEADERS = {
    "Authorization": f"Bearer {os.environ['LOOPTOKEN_API_KEY']}",
    "Content-Type": "application/json",
}
payload = {
    "model": "happyhorse-1.0-t2v",
    "input": {"prompt": "白色纸飞机穿过清晨的薄雾"},
    "parameters": {"resolution": "720P", "ratio": "16:9", "duration": 3},
}

response = requests.post(f"{BASE_URL}/v1/videos/generations", headers=HEADERS, json=payload)
response.raise_for_status()
task = response.json()
task_id = task["task_id"]

while True:
    time.sleep(5)
    response = requests.get(f"{BASE_URL}/v1/tasks/{task_id}", headers=HEADERS)
    response.raise_for_status()
    task = response.json()
    if task["status"] == "succeeded":
        print(task["video_url"])
        break
    if task["status"] == "failed":
        raise RuntimeError(task["error"])

Node.js

const baseURL = 'https://api.vibelab.me';
const headers = {
  Authorization: `Bearer ${process.env.LOOPTOKEN_API_KEY}`,
  'Content-Type': 'application/json',
};
const payload = {
  model: 'happyhorse-1.0-t2v',
  input: { prompt: '白色纸飞机穿过清晨的薄雾' },
  parameters: { resolution: '720P', ratio: '16:9', duration: 3 },
};

let response = await fetch(`${baseURL}/v1/videos/generations`, {
  method: 'POST', headers, body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(await response.text());
let task = await response.json();

while (true) {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  response = await fetch(`${baseURL}/v1/tasks/${task.task_id}`, { headers });
  if (!response.ok) throw new Error(await response.text());
  task = await response.json();
  if (task.status === 'succeeded') {
    console.log(task.video_url);
    break;
  }
  if (task.status === 'failed') throw new Error(JSON.stringify(task.error));
}

提交响应

成功提交返回 HTTP 202

字段类型说明
task_idstringLoopToken 平台任务 ID
modelstring请求使用的模型
statusstring初始通常为 pending
created_atintegerUnix 秒时间戳
durationinteger平台提交阶段识别的预估时长
resolutionstring平台提交阶段识别的预估档位
{
  "task_id": "vt_01900000-0000-7000-8000-000000000000",
  "model": "happyhorse-1.0-t2v",
  "status": "pending",
  "created_at": 1783841050,
  "duration": 3,
  "resolution": "720p"
}

任务查询

状态处理方式
pending任务排队中,5-10 秒后继续查询
running正在生成或处理结果,继续查询
succeeded读取结果字段并及时下载视频
failed停止轮询,记录 error.codeerror.message

成功任务字段:

字段说明
task_idmodelstatuscreated_at任务基础信息
completed_at终态 Unix 秒时间戳
video_urlexpires_at临时下载地址及到期时间;过期后可能不再返回
durationresolutionratio实际结果规格;模型未报告比例时 ratio 可能省略
usage模型报告的实际时长、分辨率短边和比例等白名单用量字段
credits_charged最终实际扣除的 credits
{"task_id":"vt_01900000-0000-7000-8000-000000000000","model":"happyhorse-1.0-t2v","status":"pending","created_at":1783841050,"duration":3,"resolution":"720p"}
{"task_id":"vt_01900000-0000-7000-8000-000000000000","model":"happyhorse-1.0-t2v","status":"running","created_at":1783841050,"duration":3,"resolution":"720p"}
{
  "task_id": "vt_01900000-0000-7000-8000-000000000000",
  "model": "happyhorse-1.0-t2v",
  "status": "succeeded",
  "created_at": 1783841050,
  "completed_at": 1783841119,
  "video_url": "https://media.example.com/generated/video.mp4?signature=example",
  "expires_at": 1784090000,
  "duration": 3,
  "resolution": "720p",
  "ratio": "16:9",
  "usage": {"duration": 3, "SR": 720, "ratio": "16:9"},
  "credits_charged": 27
}

失败任务包含 completed_aterror

{
  "task_id": "vt_01900000-0000-7000-8000-000000000000",
  "model": "happyhorse-1.0-r2v",
  "status": "failed",
  "created_at": 1783841050,
  "completed_at": 1783841062,
  "duration": 5,
  "resolution": "720p",
  "error": {"code": "upstream_error", "message": "video generation failed"}
}

错误处理

部分模型输入错误会先返回 HTTP 202,随后任务进入 failed。客户端必须同时处理同步 HTTP 错误和异步任务错误。

HTTP/任务结果error.code触发条件处理建议
400invalid_request_errorJSON 无效、callback_url 类型或地址不合法修正请求格式或使用公网 HTTPS 回调
401invalid_api_key缺少、无效或已吊销的 API Key检查 Bearer 鉴权并更换有效 Key
402insufficient_credits余额不足以完成提交预估充值或降低时长、分辨率
404model_not_found缺少模型、模型不存在或不可计费使用模型列表中的精确名称
404task_not_found任务不存在或不属于当前用户使用提交响应中的 LoopToken task_id
503no_available_channel模型暂时没有可用服务能力稍后重试并使用退避策略
502upstream_error提交阶段生成服务失败短暂等待后有限重试
500internal_error平台内部处理失败保存请求时间和 request ID,联系支持
failedupstream_error缺提示词、缺必要素材、素材类型或组合错误、数量超限、URL 无法访问、Base64 错误、分辨率/比例/时长不支持或生成失败对照本页模型字段表修正后重新提交;平台不会稳定透出更细的模型错误码
failedtimeout任务超过平台允许的最长处理时间稍后重新提交;持续发生时联系支持

“模型不存在”是同步错误;“模型暂不可用”通常是 503;素材和生成类错误既可能同步返回,也可能表现为任务失败,客户端不要只依赖 HTTP 状态码判断最终结果。

计费

  • 视频按实际视频时长和分辨率档位计费。
  • 提交任务时平台进行费用预估并预留相应 credits。
  • 任务完成后按实际用量结算,与预估不一致时多退少补。
  • credits_charged 是该任务最终实际扣除的 credits,以终态任务对象为准。
  • 生成失败的任务不收取最终生成费用;预留金额会退回。
  • 最终价格以模型列表显示的当前价格为准。

信息安全

  • API Key 只应保存在服务端环境变量或密钥管理系统中,不要写入浏览器代码、仓库或日志。
  • 示例中的域名、任务 ID、签名和素材均为占位内容,不包含真实凭据。
  • 不要在 callback_url 或素材 URL 中携带长期密钥。
  • 用户素材 URL 应使用最小权限和合理有效期;只有在明确允许公开展示时才能写入公开文档。
  • 结果 URL 是临时地址,应在 expires_at 前下载并转存。

本页内容