通过 PoYo 的 MiniMax H3 API,你可以用文字、首尾帧或参考素材生成 5–15 秒的 2K 视频。不使用参考素材时,生成 5 秒视频的预估费用为 105 积分($0.525)。
下面先用一条请求完成首次接入,再介绍计费、输入模式、Python 与 Node.js 示例,以及不同场景的提示词写法。本文的接口和价格均适用于 PoYo。
快速开始:提交任务并获取视频
1. 提交一个 5 秒视频任务
在 PoYo 控制台获取 API Key,替换下方的 YOUR_POYO_API_KEY,然后在终端或服务端运行。密钥应保存在服务端,不要放入浏览器代码或公开仓库。
PoYo 请求中,MiniMax H3 的 model 值为 hailuo-03。下面的示例会提交一次需要计费的生成任务。
export POYO_API_KEY="YOUR_POYO_API_KEY"
curl --fail-with-body --max-time 30 \
--request POST 'https://api.poyo.ai/api/generate/submit' \
--header "Authorization: Bearer ${POYO_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"model": "hailuo-03",
"input": {
"prompt": "A golden retriever walks through a sunlit autumn park. One slow tracking shot, natural movement, warm afternoon light.",
"duration": 5,
"resolution": "2K",
"aspect_ratio": "16:9"
}
}'
提交成功后,从 data.task_id 读取任务 ID。以下是响应结构示例,任务 ID 为占位值:
{
"code": 200,
"message": "success",
"data": {
"task_id": "YOUR_TASK_ID"
}
}
2. 查询任务结果
将返回的任务 ID 填入 TASK_ID,沿用同一个 API Key:
TASK_ID="YOUR_TASK_ID"
curl --fail-with-body --max-time 30 \
--request GET "https://api.poyo.ai/api/generate/status/${TASK_ID}" \
--header "Authorization: Bearer ${POYO_API_KEY}"
提交成功表示任务已被接受,视频需要等待生成完成。查询响应中的 data.status 有四种状态:
| 状态 | 含义 | 后续操作 |
|---|---|---|
not_started | 等待处理 | 稍后查询 |
running | 正在生成 | 稍后查询 |
finished | 生成完成 | 读取 data.files[].file_url |
failed | 生成失败 | 查看 data.error_message,停止轮询 |
下面是完成响应的示例,链接和时间均为演示值:
{
"code": 200,
"data": {
"task_id": "YOUR_TASK_ID",
"status": "finished",
"credits_amount": 105,
"files": [
{
"file_url": "https://example.com/generated/video.mp4",
"file_type": "video"
}
],
"created_time": "2026-09-22T08:30:00",
"progress": 100,
"error_message": null
}
}
字段定义和其他状态的响应示例见 PoYo 任务查询文档。查询暂时失败或等待超时后,保留任务 ID,稍后继续查询;不要因此自动重新提交付费生成。
MiniMax H3 在 PoYo 上如何计费
以下价格核对于 2026 年 9 月 21 日,金额均为美元,按 1 积分 = $0.005 换算。批量生成前,请在模型页确认最新价格。
| 计费项目 | 积分 | 美元 |
|---|---|---|
| 生成视频时长 | 21 积分/秒 | $0.105/秒 |
| 输入的参考视频时长 | 21 积分/秒 | $0.105/秒 |
| 每次生成的前 5 张参考图 | 0 | $0 |
| 第 6 张起的每张参考图 | 6.4 积分 | $0.032 |
预估积分 = 21 ×(输出秒数 + 参考视频计费秒数)+ 6.4 × 超出 5 张的参考图数量。 参考图不足或等于 5 张时,图片附加费用为 0;美元费用为预估积分乘以 $0.005。参考视频含小数秒时,以服务端实际采用的计费时长为准。
| 示例 | 预估积分 | 预估美元 |
|---|---|---|
| 生成 5 秒,不使用参考素材 | 105 | $0.525 |
| 生成 10 秒,不使用参考素材 | 210 | $1.05 |
| 生成 15 秒,不使用参考素材 | 315 | $1.575 |
| 生成 10 秒 + 5 秒参考视频 + 7 张参考图 | 327.8 | $1.639 |
最后一项按 21 × (10 + 5) + 6.4 × (7 − 5) 计算。这里列出的是单次生成费用;如果一个镜头需要多次尝试,预算应包含每次生成的费用。
选择输入模式与参考素材
输入模式由提交的媒体字段决定。上面的快速开始示例属于文生视频;需要指定起止画面或引用素材时,再添加相应字段。
| 模式 | 输入字段 | 使用方式 |
|---|---|---|
| 文生视频 | prompt,不传媒体 URL | 用文字描述场景、动作和镜头 |
| 首尾帧生成 | image_urls | 第一张为首帧,可选第二张尾帧;不传 aspect_ratio,画幅由首帧决定 |
| 多模态参考生成 | reference_image_urls、reference_video_urls、reference_audio_urls | 可组合图片、视频和音频;参考音频必须搭配参考图或参考视频 |
image_urls 不能与任何 reference_*_urls 字段混用。所有素材链接都需要公开可访问,并能直接下载。
参数与素材限制
以下限制来自 PoYo MiniMax H3 接口文档:
prompt必填,最多 2000 个字符。duration为 5–15 的整数,单位为秒,默认 5;resolution仅支持2K。- 文生视频支持
21:9、16:9、4:3、1:1、3:4、9:16,默认16:9。参考模式还支持adaptive,并以它为默认值。 - 最多 9 张参考图、3 段参考视频和 3 段参考音频。每段视频或音频为 2–15 秒;视频总时长和音频总时长分别不得超过 15 秒。
首尾帧请求示例
将下方 JSON 作为 POST /api/generate/submit 的请求体。example.com 下的素材地址都是占位链接,提交前须换成你自己的可下载素材;只用首帧时,删除数组中的第二个地址。
{
"model": "hailuo-03",
"input": {
"prompt": "The camera slowly moves through the temple doorway, starting at the entrance and ending inside the hall. Dust floats in the sunlight.",
"duration": 6,
"resolution": "2K",
"image_urls": [
"https://example.com/assets/temple-entrance.jpg",
"https://example.com/assets/temple-interior.jpg"
]
}
}
图片与视频组合参考示例
用 Image 1 指定人物外观,用 Video 1 指定希望参考的运镜。顺序分别对应图片数组和视频数组中的第一项。提交前同样需要替换素材地址,并检查参考视频时长。
{
"model": "hailuo-03",
"input": {
"prompt": "Use Image 1 for the character appearance and outfit. The character turns and walks toward the window. Use Video 1 as the camera movement reference.",
"duration": 8,
"resolution": "2K",
"aspect_ratio": "adaptive",
"reference_image_urls": [
"https://example.com/assets/character.png"
],
"reference_video_urls": [
"https://example.com/assets/camera-motion.mp4"
]
}
}
Python 与 Node.js 接入示例
下面将提交和查询拆成两个函数:先获得并保存任务 ID,再等待结果。这样即使查询中断,也可以使用原任务 ID 恢复查询,无须重新生成。示例只在状态查询阶段重试连接异常、超时、HTTP 429 和部分 5xx 错误,提交阶段不自动重试。
两种实现均每隔 10 秒查询一次,最多查询 60 次,单次请求超时为 30 秒。因此总等待时间还包含请求耗时;这些值是示例的应用设置,不代表生成耗时承诺。接入已有项目时,可以按业务需要调整间隔和重试策略。
Python:提交任务与轮询结果
先安装依赖 python -m pip install requests,并设置前文的 POYO_API_KEY 环境变量。这里使用同步 Python 脚本轮询异步生成任务。
import os
import time
import requests
BASE_URL = "https://api.poyo.ai"
API_KEY = os.environ["POYO_API_KEY"]
if not API_KEY.strip():
raise ValueError("请设置 POYO_API_KEY")
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
RETRYABLE_HTTP = {429, 500, 502, 503, 504}
def response_data(response):
response.raise_for_status()
body = response.json()
if body.get("code") != 200 or not isinstance(body.get("data"), dict):
raise RuntimeError(f"API 响应异常: {body}")
return body["data"]
def submit_h3(prompt, duration=5):
response = requests.post(
f"{BASE_URL}/api/generate/submit",
headers=HEADERS,
json={"model": "hailuo-03", "input": {
"prompt": prompt, "duration": duration,
"resolution": "2K", "aspect_ratio": "16:9",
}},
timeout=30,
)
task_id = response_data(response).get("task_id")
if not isinstance(task_id, str) or not task_id:
raise RuntimeError("提交响应缺少任务 ID,请核查记录,不要自动重新提交")
return task_id
def wait_for_h3(task_id, max_polls=60):
for _ in range(max_polls):
time.sleep(10)
try:
response = requests.get(
f"{BASE_URL}/api/generate/status/{task_id}",
headers=HEADERS, timeout=30,
)
except (requests.Timeout, requests.ConnectionError):
continue
if response.status_code in RETRYABLE_HTTP:
continue
task = response_data(response)
status = task.get("status")
if status == "finished":
for item in task.get("files") or []:
if item.get("file_type") == "video" and item.get("file_url"):
return item["file_url"]
raise RuntimeError(f"任务 {task_id} 已完成,但响应缺少视频地址")
if status == "failed":
raise RuntimeError(f"任务 {task_id} 失败: {task.get('error_message')}")
if status not in {"not_started", "running"}:
raise RuntimeError(f"任务 {task_id} 返回未知状态: {status}")
raise TimeoutError(f"已达到查询次数上限,保留任务 ID 稍后继续查询: {task_id}")
if __name__ == "__main__":
task_id = submit_h3("A golden retriever walks through a sunlit autumn park.")
# 在应用中,此处应将 task_id 保存到数据库,再开始轮询。
print(f"Task ID: {task_id}", flush=True)
print(wait_for_h3(task_id))
恢复查询时直接调用 wait_for_h3(已保存的任务 ID)。401、403 等 HTTP 错误、业务错误或不符合预期的响应会终止查询,应先处理原因。
Node.js:使用内置 fetch
以下 JavaScript 使用 Node.js 20 或更新版本的内置 fetch,无须安装 HTTP 客户端依赖。保存为 .mjs 文件,并在服务端运行。
const BASE_URL = 'https://api.poyo.ai';
const apiKey = process.env.POYO_API_KEY;
if (!apiKey?.trim()) throw new Error('请设置 POYO_API_KEY');
const headers = {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
};
const retryableHttp = new Set([429, 500, 502, 503, 504]);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function responseData(response) {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const body = await response.json();
if (body.code !== 200 || !body.data || typeof body.data !== 'object') {
throw new Error(`API 响应异常: ${JSON.stringify(body)}`);
}
return body.data;
}
export async function submitH3(prompt, duration = 5) {
const response = await fetch(`${BASE_URL}/api/generate/submit`, {
method: 'POST', headers,
body: JSON.stringify({
model: 'hailuo-03',
input: { prompt, duration, resolution: '2K', aspect_ratio: '16:9' },
}),
signal: AbortSignal.timeout(30_000),
});
const data = await responseData(response);
if (typeof data.task_id !== 'string' || !data.task_id) {
throw new Error('提交响应缺少任务 ID,请核查记录,不要自动重新提交');
}
return data.task_id;
}
export async function waitForH3(taskId, maxPolls = 60) {
for (let attempt = 0; attempt < maxPolls; attempt++) {
await sleep(10_000);
let response;
try {
response = await fetch(
`${BASE_URL}/api/generate/status/${encodeURIComponent(taskId)}`,
{ headers, signal: AbortSignal.timeout(30_000) },
);
} catch (error) {
if (error instanceof Error &&
(error.name === 'TimeoutError' || error.name === 'TypeError')) {
continue;
}
throw error;
}
if (retryableHttp.has(response.status)) {
await response.body?.cancel();
continue;
}
const task = await responseData(response);
if (task.status === 'finished') {
const video = task.files?.find((file) => file.file_type === 'video' && file.file_url);
if (!video) throw new Error(`任务 ${taskId} 已完成,但响应缺少视频地址`);
return video.file_url;
}
if (task.status === 'failed') {
throw new Error(`任务 ${taskId} 失败: ${task.error_message || '未提供错误详情'}`);
}
if (!['not_started', 'running'].includes(task.status)) {
throw new Error(`任务 ${taskId} 返回未知状态: ${task.status}`);
}
}
throw new Error(`已达到查询次数上限,保留任务 ID 稍后继续查询: ${taskId}`);
}
const taskId = await submitH3('A golden retriever walks through a sunlit autumn park.');
// 在应用中,此处应将 taskId 保存到数据库,再开始轮询。
console.log(`Task ID: ${taskId}`);
console.log(await waitForH3(taskId));
恢复查询时,用 waitForH3(已保存的任务 ID) 替换文件末尾的提交与查询代码。示例中的轮询适合脚本或后台任务;在 Web 应用中,应把任务 ID 返回给前端,由后台跟踪生成状态,避免让一次页面请求持续等待。
使用 Webhook 接收结果
也可以在提交请求顶层、与 model 和 input 同级的位置传入 callback_url,例如 https://your-domain.com/webhooks/poyo。任务成功或失败后,PoYo 会向该地址发送结果。
接收端应核对任务 ID 与本地记录,并按任务 ID 处理重复通知,避免重复执行后续业务。视频下载和转码等耗时操作可以交给后台任务。回调接入期间仍可使用状态查询接口核对结果。
提示词与场景示例
先描述主体和动作,再补充镜头、环境、光线与声音。使用参考素材时,写清 Image 1、Video 1 或 Audio 1 的用途,避免让同一素材同时承担互相冲突的要求。
下面四个英文示例用于展示写法,尚未附实测生成结果。英文术语便于直接复用,不表示英文一定优于中文。时间段和保留外观等描述是生成目标,实际结果需要检查。
产品广告:8 秒,参考图模式
将产品图片放入 input.reference_image_urls 的第一项,设置 duration: 8、aspect_ratio: "16:9",并将以下内容填入 prompt。请求结构可沿用前面的参考模式示例,不需要参考视频时删除 reference_video_urls。
Use Image 1 as the product reference. A clear glass perfume bottle rests on
wet black stone after rain. Preserve the bottle shape, cap, and label placement.
One continuous 8-second shot: begin close to the water droplets, then slowly
pull back to reveal the bottle in warm rim light. Realistic glass reflections,
no added text. Soft rain ambience.
先用一个简单镜头检查瓶身和标签是否稳定,再尝试更复杂的环绕运镜。
人物对白:8 秒,参考图模式
将人物图片放入 input.reference_image_urls 的第一项,设置 duration: 8、aspect_ratio: "16:9"。短句便于检查口型、语速和人物外观。
Use Image 1 as the character reference. An 8-second medium close-up of a pastry
chef in a quiet kitchen at sunrise. She looks into the camera and says:
"Every detail matters in baking." Natural breathing, a subtle smile,
soft window light. Preserve her face, hairstyle, and apron. A steady camera,
clear speech, quiet room tone.
竖屏游戏广告:10 秒,文生视频
设置 duration: 10、aspect_ratio: "9:16"。分段描述用于表达动作顺序;如果画面过于拥挤,可以先减少动作和角色数量。
A 10-second vertical fantasy game trailer.
0-3s: An armored knight walks through a ruined stone gate.
3-6s: One creature charges; the knight blocks once with a shield.
6-9s: The camera rises to reveal the fortress walls.
9-10s: Hold the final composition.
Readable action, consistent armor, wind and impact sounds, no UI or captions.
连续跟拍:10 秒,文生视频
设置 duration: 10、aspect_ratio: "16:9"。用同一主体和一条行进路线组织镜头,检查是否出现切镜、主体变化或不连贯的运动。
One unbroken 10-second tracking shot follows a cyclist through a night market.
Begin behind the rear wheel, rise to shoulder height, then move alongside
without cutting. Wet pavement reflections, a clear path between stalls,
consistent bicycle geometry, no speed ramps or scene transitions.
Natural street ambience and bicycle tires rolling on wet pavement.
常见问题与接入排查
可以直接使用 MiniMax 官方接口的请求格式吗?
本文示例使用 PoYo 的 POST /api/generate/submit 和 GET /api/generate/status/{task_id}。不同平台的地址、模型标识和字段结构可能不同,接入时以所用平台的文档为准。
任务一直是 not_started,是否需要重新提交?
not_started 表示等待处理,本身不是失败。保留任务 ID 继续查询;如果超过应用设定的等待上限,记录任务并稍后核对,必要时携带任务 ID 联系支持。
提交请求超时,但没有拿到任务 ID,怎么办?
请求超时不能证明服务端没有接收任务。先核查任务记录,必要时提供提交时间等信息联系支持。只有取得任务 ID 后,才能使用状态查询接口;不要把重新提交当作查询失败的补救措施。
图片、视频和音频可以同时作为参考吗?
可以,在参考模式中按前述数量和时长限制组合。参考音频必须搭配参考图或参考视频;这组字段不能与首尾帧模式的 image_urls 混用。
生成 10 秒视频需要多少钱?
按本文列出的价格,不使用参考素材时为 10 × 21 = 210 积分,即 $1.05。参考视频和超过 5 张的参考图会增加费用。
接入应用前,还应确认素材链接能直接下载、任务 ID 已保存,并为每个用户设置适当的生成次数和并发限制。发布生成的视频前,检查人物外观、商品形状、文字、动作与声音是否符合用途。
你可以在 MiniMax H3 模型页先尝试生成,或前往 API 密钥页开始接入。更多模型介绍见 MiniMax H3 评测与 MiniMax H3 和 Seedance 2.5 对比。