MiniMax H3 视频生成
用 MiniMax H3 系列模型生成视频,支持文生视频、首尾帧图生视频,以及用参考图、参考视频、参考音频做多模态参考生视频。除了普通的视频生成,minimax/minimax-h3 还提供两个只有它支持的接口:视频升清(POST /v1/videos/regenerations,把 768P 视频重新生成为 2K)和上下文增强(POST /v1/videos/context,产物是增强后的提示词文本)。三种任务都以异步任务的方式提供,用同一个查询接口跟踪进度。接口形状参照 OpenAI 的 Videos API,网关把统一的参数转换成 MiniMax 的格式。任务生命周期的通用说明见异步任务。
支持的模型
| 模型 ID | 特点 | 时长与分辨率 | 计费口径 |
|---|---|---|---|
minimax/minimax-h3 |
标准版:文生视频、首尾帧图生视频、多模态参考(参考图 / 视频 / 音频);支持视频升清和上下文增强 | 4~15 秒;480P、768P、2K | 视频按秒(输入 + 输出),按分辨率分档;升清单独一档;参考图单独计一项;上下文增强按输入、输出 Token 计 |
minimax/minimax-h3-max |
已被服务商下线,目前不可用,请改用 minimax/minimax-h3。极速版:文生视频、首尾帧图生视频、多模态参考;不支持多张参考图,不支持升清和上下文增强 |
5~15 秒;480P、768P | 视频按秒,按 480P、768P 分档;参考图单独计一项 |
minimax/minimax-h3-max已被服务商下线:目前调用它会返回 HTTP 200,但任务对象是空的、没有任务 ID,无法轮询,也不扣费。请改用minimax/minimax-h3。
模型需要在工作空间的模型广场开通后才能调用;具体单价以模型广场显示的为准。
端点
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /v1/videos |
提交视频生成任务,立即返回任务 ID |
| GET | /v1/videos/{id} |
查询任务状态,三种任务通用 |
| GET | /v1/videos/{id}/content |
下载视频(302 跳转到视频地址) |
| POST | /v1/videos/regenerations |
视频升清:把 H3 生成的 768P 视频重新生成为 2K,仅 minimax/minimax-h3 |
| POST | /v1/videos/context |
上下文增强:把多模态上下文整理成更丰富的提示词,产物是文本,仅 minimax/minimax-h3 |
| DELETE | /v1/videos/{id} |
删除已结束的任务;不能取消进行中的任务 |
完整地址为 https://api.lyrouter.com 加上表中的路径。三个提交接口用的是同一个模型名、同一套任务 ID,返回的任务都用 GET /v1/videos/{id} 查询。
鉴权
在请求头中携带 API Key:
Authorization: Bearer <API Key>
Bearer 区分大小写。也可以改用 x-api-key: <API Key>,两者同时存在时只读 Authorization。API Key 在工作空间的 API 密钥 页面创建,只用于 LYRouter 鉴权,不会转发给上游服务商。完整说明见接入地址与鉴权。
同一工作空间内的任意 API Key 都能查询、下载该工作空间的任务;其他工作空间的 Key 查询时返回 404。
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
Content-Type |
提交时必填 | application/json。POST /v1/videos 也接受 multipart/form-data,见下文「用表单提交」;升清和上下文增强只接受 JSON |
X-Gateway-Strict-Parameters |
否 | 设为 true 时,请求中有会被丢弃的参数就直接返回 400,不提交任务、不计费,见网关扩展请求头与响应头 |
提交任务
/v1/videos提交一个视频生成任务。网关校验参数、转换成 MiniMax 的格式后提交给服务商,立即返回 status 为 queued 的任务对象,视频在后台生成。提交请求本身不产生费用。
请求体
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | minimax/minimax-h3 或 minimax/minimax-h3-max(已被服务商下线,目前不可用,请改用 minimax/minimax-h3)。必须是具体的模型 ID:虚拟模型 @vmodel/<名称> 和 lyrouter/auto 返回 403,失败时也不会改用工作空间的默认模型 |
prompt |
string | 是 | 提示词 |
seconds |
integer | 是 | 视频时长(秒),必须是正整数。H3 为 4~15,H3-Max 为 5~15(H3-Max 已被服务商下线,目前不可用)。MiniMax 要求提供时长,网关不补默认值 |
size |
string | 是 | 分辨率:档位名(480P、768P、2K)或 宽x高(短边必须正好是 480 或 768),见下文「size:短边必须正好落在档位上」。H3-Max 不支持 2K(H3-Max 已被服务商下线,目前不可用)。MiniMax 要求提供分辨率 |
first_frame |
string | 否 | 首帧图片的 URL(图生视频),1 张 |
last_frame |
string | 否 | 尾帧图片的 URL,1 张 |
reference_image |
string | string[] | 否 | 参考图的 URL,单张写字符串,多张写数组,最多 9 张 |
input_reference |
string | string[] | 否 | 参考视频的 URL,最多 3 个 |
reference_audio |
string | string[] | 否 | 参考音频的 URL,最多 3 个 |
watermark |
boolean | 否 | 是否给视频加水印 |
- 图生视频与多模态参考互斥:传了
reference_image、input_reference或reference_audio,就不能再传first_frame/last_frame,反之亦然。这条由服务商校验。 - 以下参数在网关契约里存在(其他模型用得上),但 MiniMax 没有对应概念,传了返回 400
<参数名> is not supported for this model:generate_audio(有声由参考音频承载)、output_format(没有容器格式选项)、omni_reference_task_type(没有全模态任务类型)、source_video(只属于视频升清接口)。 - 表中没有的其他字段会被丢弃,响应头
X-Gateway-Unsupported-Parameters列出它们的名字;带X-Gateway-Strict-Parameters: true时改为返回 400。MiniMax 原生的duration、resolution、ratio、content也属于这一类,请改用seconds、size和上面的素材字段。 - 本接口不支持
n,每次请求生成一个视频。
用表单提交
POST /v1/videos 也接受 multipart/form-data,OpenAI 官方 SDK 的 videos.create() 就用这种格式。表单中网关读取 model、prompt、seconds、size、input_reference、watermark 等字段:
input_reference只能传 URL,传文件不会报错但会被忽略:请填可公开访问的https://地址;目前上传文件时,任务按没有参考视频的方式生成,并照常计费。watermark只接受字面量true或false。first_frame、last_frame、reference_image、reference_audio请用 JSON 请求体提交。目前表单里的这些字段会被换成占位值转发给服务商,例如带reference_audio时提交返回 200,任务随后失败,error.message为content[1].audio_url: invalid param: audio url must be http(s):// or data:...;base64(失败不收费)。
请求示例
示例从环境变量 LYROUTER_API_KEY 读取 API Key,设置方法见完成第一次模型调用。
curl https://api.lyrouter.com/v1/videos \
-H "Authorization: Bearer $LYROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax/minimax-h3",
"prompt": "史诗级太空歌剧预告:女舰长独自站在观景窗前",
"size": "768P",
"seconds": 5
}'
import os
import httpx
resp = httpx.post(
"https://api.lyrouter.com/v1/videos",
headers={"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"},
json={
"model": "minimax/minimax-h3",
"prompt": "史诗级太空歌剧预告:女舰长独自站在观景窗前",
"size": "768P",
"seconds": 5,
},
timeout=60,
)
resp.raise_for_status()
dropped = resp.headers.get("X-Gateway-Unsupported-Parameters")
if dropped:
print("这些参数没有生效:", dropped)
task = resp.json()
print(task["id"], task["status"])
const resp = await fetch("https://api.lyrouter.com/v1/videos", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LYROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "minimax/minimax-h3",
prompt: "史诗级太空歌剧预告:女舰长独自站在观景窗前",
size: "768P",
seconds: 5,
}),
});
if (!resp.ok) throw new Error(await resp.text());
const dropped = resp.headers.get("X-Gateway-Unsupported-Parameters");
if (dropped) console.log("这些参数没有生效:", dropped);
const task = await resp.json();
console.log(task.id, task.status);
响应
提交成功返回 HTTP 200 和任务对象,status 为 queued,字段含义见下文「查询任务」。提交响应里没有 usage,费用在任务完成时结算。下面的 400 是 size 写成了 1280x720(短边 720 不在 MiniMax 的档位里),403 是模型没有在本工作空间开通(或用了虚拟模型、lyrouter/auto),429 是服务商账户的并发任务已满。
{
"id": "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA",
"object": "video",
"model": "MiniMax-H3",
"status": "queued",
"progress": 0,
"created_at": 1791950400,
"expires_at": 1792555200,
"seconds": 5,
"size": "768P"
}
{
"error": {
"message": "this model takes discrete resolution tiers, not arbitrary sizes: 1280x720 (short side 720). Use a size whose short side is 480 or 768, or pass the tier name directly as size (e.g. \"768P\", \"2K\")",
"type": "invalid_request_error",
"code": "invalid_parameter"
}
}
{
"error": {
"message": "Model is not available in the model plaza",
"type": "access_denied",
"code": "model_not_available"
}
}
{
"error": {
"message": "upstream concurrency full",
"type": "rate_limit_error",
"code": "upstream_concurrency_full"
}
}
- 保存好返回的
id。查询时网络出错或超时,用同一个 ID 继续查询,不要重新提交:重新提交会生成新任务并再次计费。 - 429
upstream_concurrency_full的并发限制按服务商账户共享,换一个 API Key 也一样,请稍后重新提交。
查询任务
/v1/videos/{id}读取任务的当前状态,视频生成、视频升清、上下文增强三种任务都用这个接口。网关在后台替你向服务商轮询进度,这个接口只返回网关记录的状态,查得更频繁不会更早拿到结果。
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
string | 是 | 提交时返回的任务 ID,以 aigwt_ 开头。服务商自己的任务 ID 查不到,返回 404 |
请求示例
curl https://api.lyrouter.com/v1/videos/$TASK_ID \
-H "Authorization: Bearer $LYROUTER_API_KEY"
import os
import httpx
task_id = "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA"
resp = httpx.get(
f"https://api.lyrouter.com/v1/videos/{task_id}",
headers={"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"},
timeout=60,
)
resp.raise_for_status()
task = resp.json()
print(task["status"], task.get("usage"), task.get("error"))
const taskId = "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA";
const resp = await fetch(`https://api.lyrouter.com/v1/videos/${taskId}`, {
headers: { Authorization: `Bearer ${process.env.LYROUTER_API_KEY}` },
});
if (!resp.ok) throw new Error(await resp.text());
const task = await resp.json();
console.log(task.status, task.usage, task.error);
响应
任务存在时总是返回 HTTP 200,任务本身失败也一样,以 status 判断结果。任务 ID 不存在、已超过 7 天或属于其他工作空间时返回 404。
{
"id": "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA",
"object": "video",
"model": "MiniMax-H3",
"status": "completed",
"progress": 100,
"created_at": 1791950400,
"completed_at": 1791950507,
"expires_at": 1792555200,
"seconds": 5,
"size": "768P",
"usage": { "duration_seconds": 5 }
}
{
"id": "aigwt_minimax_videos-context_Zp8Rk2Vt5Lq9Wx3Ny6Bh1A",
"object": "video",
"model": "MiniMax-H3",
"status": "completed",
"progress": 100,
"created_at": 1791950400,
"completed_at": 1791950421,
"expires_at": 1792555200,
"seconds": 5,
"output_text": "integrated_multimodal_description: [Shot 1] Cinematic, a medium shot featuring a slow push-in on ...",
"usage": { "completion_tokens": 1820 }
}
{
"id": "aigwt_minimax_videos_Fj4Ns7Kd2Pw9Lm5Qx8Rt3Y",
"object": "video",
"model": "MiniMax-H3",
"status": "failed",
"progress": 0,
"created_at": 1791950400,
"completed_at": 1791950482,
"expires_at": 1792555200,
"seconds": 5,
"size": "768P",
"error": {
"code": "upstream_error",
"message": "upstream task failed"
}
}
{
"error": {
"message": "video task not found",
"type": "invalid_request_error",
"code": "not_found"
}
}
status |
含义 | 你需要做的 |
|---|---|---|
queued |
已受理,尚未开始生成 | 继续轮询 |
in_progress |
服务商正在生成 | 继续轮询 |
completed |
已完成 | 视频任务调用 /content 下载;上下文增强任务读取 output_text |
failed |
已失败 | 读取 error,不收费 |
| 字段 | 说明 |
|---|---|
id |
网关的任务 ID,格式为 aigwt_<服务商>_<任务类型>_<随机串>,例如 aigwt_minimax_videos_…、aigwt_minimax_videos-regenerations_…、aigwt_minimax_videos-context_…。它不是服务商的任务 ID,向服务商报障时请用 error.provider_request_id |
object |
固定为 video,上下文增强任务也一样 |
model |
实际调用的上游模型名,例如 MiniMax-H3 |
status |
queued、in_progress、completed、failed 之一 |
progress |
完成前为 0,完成后为 100,不表示中间进度,请以 status 判断 |
created_at / completed_at |
提交时间、结束时间(Unix 秒)。completed_at 只在任务结束后出现 |
expires_at |
任务记录的过期时间,提交后 7 天。过期后查询返回 404 |
seconds / size |
原样回显提交时的值,没有提交的不出现 |
output_text |
仅上下文增强任务有,为增强后的提示词 |
error |
仅 failed 时出现:code、message,以及有值时才出现的 provider_request_id(服务商的请求标识)和 retryable |
usage |
任务完成后出现:视频生成和升清为 duration_seconds(计费秒数:视频生成含参考视频的秒数;升清只计源视频的秒数),上下文增强为 completion_tokens(输出 Token 数) |
- 失败任务的
error.code是服务商给出的错误码;服务商没有给出可识别的错误码时为upstream_error。error.retryable为false表示原样重试不会成功,true表示可以重试,没有这个字段表示网关无法判断。完整的取值见异步任务。 - 轮询间隔:提交后约 10 秒开始查询,之后逐步放宽到每 30 秒一次。
- 等待上限:提交 24 小时后仍未完成的任务不会再有结果,也不收费,可以停止轮询。这时查询结果可能仍显示
queued或in_progress,任务的实际状态请在控制台工作空间的 多媒体生成 页面按任务 ID 搜索查看(「状态」显示「已过期」)。
下载视频
/v1/videos/{id}/content视频生成或升清任务变为 completed 后调用,返回 302,Location 响应头是服务商提供的带签名的视频地址。让客户端跟随跳转即可下载:cURL 加 -L,Python httpx 设 follow_redirects=True,Node.js 的 fetch 默认跟随。上下文增强任务的结果是 output_text 中的文本,没有视频可下载,不要对它调用这个接口:目前对已完成的上下文增强任务调用会返回 HTTP 500,正文是 HTML 页面,不是 JSON 错误。
请求示例
# 下载到本地
curl -L https://api.lyrouter.com/v1/videos/$TASK_ID/content \
-H "Authorization: Bearer $LYROUTER_API_KEY" \
-o video.mp4
# 只取视频地址,不下载
curl -s -o /dev/null -w '%{redirect_url}\n' \
https://api.lyrouter.com/v1/videos/$TASK_ID/content \
-H "Authorization: Bearer $LYROUTER_API_KEY"
import os
import httpx
task_id = "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA"
with httpx.stream(
"GET",
f"https://api.lyrouter.com/v1/videos/{task_id}/content",
headers={"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"},
follow_redirects=True,
timeout=600,
) as video:
video.raise_for_status()
with open("video.mp4", "wb") as f:
for chunk in video.iter_bytes():
f.write(chunk)
import { writeFile } from "node:fs/promises";
const taskId = "aigwt_minimax_videos_Qm3Tz8VbN1sLk0pYc4dReA";
const video = await fetch(`https://api.lyrouter.com/v1/videos/${taskId}/content`, {
headers: { Authorization: `Bearer ${process.env.LYROUTER_API_KEY}` },
});
if (!video.ok) throw new Error(`download failed: ${video.status}`);
await writeFile("video.mp4", Buffer.from(await video.arrayBuffer()));
响应
状态码:302
Location: <服务商提供的带签名的视频地址>
{
"error": {
"message": "video is not ready yet",
"type": "invalid_request_error",
"code": "not_ready"
}
}
{
"error": {
"message": "video task not found",
"type": "invalid_request_error",
"code": "not_found"
}
}
- 视频地址在任务完成时确定,之后每次调用都跳转到同一个地址。地址的有效期由服务商决定,通常为 24 小时,过期后无法通过网关重新获取,请拿到后立即下载或转存到自己的存储。
- 任务还没完成(或已失败)时返回 409。这类 4xx 也会计入 API Key 的错误率,频繁调用可能触发熔断,请先查询到
completed再下载。
视频升清
/v1/videos/regenerations把一条 H3 生成的 768P 视频重新生成为 2K,仅 minimax/minimax-h3 支持。它只适用于 H3 自己产出、符合 768P 规格的视频,不是通用的视频放大。提交后返回同样的任务对象,用 GET /v1/videos/{id} 查询,完成后用 /content 下载。只接受 JSON 请求体。
请求体
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | minimax/minimax-h3 |
prompt |
string | 是 | 生成那条 768P 视频时实际送入模型的最终提示词。当时用过上下文增强的,填增强之后的提示词 |
source_video |
string | 是 | 要升清的 768P 视频的 URL |
size |
string | 否 | 目标分辨率,默认 2K |
first_frame / last_frame / reference_image / input_reference / reference_audio |
— | 否 | 生成源视频时用过的参考素材,按当时的输入原样附上,写法同「提交任务」 |
watermark |
boolean | 否 | 是否给视频加水印 |
- 不要传
seconds:时长由源视频决定,传了返回 400seconds is not supported for video regeneration (the source video determines the duration)。 generate_audio、output_format、omni_reference_task_type同样返回 400<参数名> is not supported for this model。- 源视频必须满足:含音轨、24 fps、宽和高都能被 32 整除、面积在 589,824~1,032,192 像素之间、总帧数 107~362(每档递增 17 帧,约 4~15 秒)。
- 服务商要求
prompt和参考素材与生成源视频时完全一致。给的不是当时那一份时不会报错,只是拿不到预期的效果,网关也无法替你校验。
请求示例
curl https://api.lyrouter.com/v1/videos/regenerations \
-H "Authorization: Bearer $LYROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax/minimax-h3",
"prompt": "生成那条 768P 视频时实际送入模型的最终提示词",
"source_video": "https://example.com/h3-768p.mp4",
"size": "2K"
}'
import os
import httpx
resp = httpx.post(
"https://api.lyrouter.com/v1/videos/regenerations",
headers={"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"},
json={
"model": "minimax/minimax-h3",
"prompt": "生成那条 768P 视频时实际送入模型的最终提示词",
"source_video": "https://example.com/h3-768p.mp4",
"size": "2K",
},
timeout=60,
)
resp.raise_for_status()
print(resp.json()["id"])
const resp = await fetch("https://api.lyrouter.com/v1/videos/regenerations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LYROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "minimax/minimax-h3",
prompt: "生成那条 768P 视频时实际送入模型的最终提示词",
source_video: "https://example.com/h3-768p.mp4",
size: "2K",
}),
});
if (!resp.ok) throw new Error(await resp.text());
console.log((await resp.json()).id);
响应
提交成功返回 HTTP 200 和任务对象,id 以 aigwt_minimax_videos-regenerations_ 开头;完成后的 usage.duration_seconds 为计费秒数。下面的 400 是没有传 source_video。
{
"id": "aigwt_minimax_videos-regenerations_Hk2Lp9WqR4tYv7Xz1Bc3Nd",
"object": "video",
"model": "MiniMax-H3",
"status": "queued",
"progress": 0,
"created_at": 1791950400,
"expires_at": 1792555200,
"size": "2K"
}
{
"error": {
"message": "source_video is required for video regeneration (the 768P video to upscale)",
"type": "invalid_request_error",
"code": "invalid_parameter"
}
}
上下文增强
/v1/videos/context把提示词和多模态上下文整理成一段结构化、语义更丰富的提示词,仅 minimax/minimax-h3 支持。这个接口只返回文本,不生成视频。 它同样是异步任务:提交后用 GET /v1/videos/{id} 查询,完成后增强后的提示词在任务对象的 output_text 中,没有 /content 可下载。典型用法是两步:先调本接口拿到 output_text,再把它作为 prompt 提交给 POST /v1/videos。只接受 JSON 请求体。
目前这个接口不会拒绝 Seedance 模型:传 Seedance 的模型 ID 会生成一条普通视频(没有
output_text),并按视频计费。请只用minimax/minimax-h3调用本接口。
请求体
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | minimax/minimax-h3 |
prompt |
string | 是 | 原始提示词 |
seconds |
integer | 是 | 计划生成的视频时长(秒),4~15。不传时返回 400,正文是纯文本 binding: expr_path=duration, cause=missing required parameter(响应头目前仍是 Content-Type: application/json) |
size |
string | 否 | 写法同「提交任务」。不传时网关按 2K 发给服务商 |
first_frame / last_frame / reference_image / input_reference / reference_audio |
— | 否 | 多模态上下文,写法和限制同「提交任务」 |
generate_audio、output_format、omni_reference_task_type、source_video 返回 400 <参数名> is not supported for this model。
请求示例
curl https://api.lyrouter.com/v1/videos/context \
-H "Authorization: Bearer $LYROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax/minimax-h3",
"prompt": "一只猫在雨里走过霓虹街道",
"seconds": 5
}'
import os
import httpx
resp = httpx.post(
"https://api.lyrouter.com/v1/videos/context",
headers={"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"},
json={
"model": "minimax/minimax-h3",
"prompt": "一只猫在雨里走过霓虹街道",
"seconds": 5,
},
timeout=60,
)
resp.raise_for_status()
print(resp.json()["id"])
const resp = await fetch("https://api.lyrouter.com/v1/videos/context", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LYROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "minimax/minimax-h3",
prompt: "一只猫在雨里走过霓虹街道",
seconds: 5,
}),
});
if (!resp.ok) throw new Error(await resp.text());
console.log((await resp.json()).id);
响应
提交成功返回 HTTP 200 和任务对象,id 以 aigwt_minimax_videos-context_ 开头。完成后的结果见上文「查询任务」中的「200 上下文增强」:output_text 是增强后的提示词,usage.completion_tokens 是输出 Token 数。下面的 400 是用 minimax/minimax-h3-max(已下线)调用本接口时服务商返回的报错,网关原样透传,没有 error.code。
{
"id": "aigwt_minimax_videos-context_Zp8Rk2Vt5Lq9Wx3Ny6Bh1A",
"object": "video",
"model": "MiniMax-H3",
"status": "queued",
"progress": 0,
"created_at": 1791950400,
"expires_at": 1792555200,
"seconds": 5
}
{
"type": "error",
"error": {
"type": "bad_request_error",
"message": "invalid params, model MiniMax-H3-Max does not support resolution 2K, supported resolutions: 480P, 768P (2013)",
"http_code": "400"
},
"request_id": "<服务商的请求标识>"
}
删除任务
/v1/videos/{id}对已结束(completed 或 failed)的任务返回 HTTP 200 和任务对象,并带 "deleted": true;任务记录不会因此删除,在 expires_at 之前仍可查询和下载。对进行中的任务调用返回 409 cancel_not_supported:服务商不提供取消接口,请等待任务结束。OpenAI 官方 SDK 的 videos.delete() 读取的就是这个 deleted 字段。
MiniMax 特有参数与限制
size:短边必须正好落在档位上
| 写法 | 网关怎么处理 |
|---|---|
档位名(480P、768P、2K) |
原样送出 |
宽x高 |
取短边查档位表:短边必须正好是 480 或 768,否则网关直接返回 400 并列出合法写法;宽高比按就近匹配 |
1280x720的短边是 720,不在档位里,会被拒绝;768P 横屏可以写1366x768,竖屏写768x1366。2K没有固定的短边,只能写档位名"2K"。- 用
宽x高时,宽高比也要落在 21:9、16:9、4:3、1:1、3:4、9:16 之一(允许 2% 误差),否则返回 400size implies an aspect ratio this model does not support: <取值>。 - 档位决定的是分辨率档,产物的实际像素由服务商决定,以下载到的视频为准。实测:文生视频和多模态参考用
480P或854x480时产物为 1038×576(短边 576,不是 480);768P为 1344×768;首尾帧图生视频用 1:1 的图片 +854x480时为 768×768;升清到2K为 2560×1440。
三种输入场景与宽高比
| 场景 | 怎么传 | 宽高比 |
|---|---|---|
| 文生视频 | 只传 prompt |
必须是明确的比例,不能自适应:网关按 size 推出比例;size 写的是档位名时按 16:9 生成 |
| 图生视频 | first_frame(+ last_frame) |
由输入图片决定,size 只决定分辨率 |
| 多模态参考生视频 | reference_image / input_reference / reference_audio |
size 写 宽x高 时按它推出的比例,写档位名时自适应。传参考视频时不能自适应:size 请写成 宽x高(如 854x480、1366x768),写档位名时任务会失败 |
输入素材限制
| 素材 | 限制 |
|---|---|
| 图片 | JPG、JPEG、PNG、WEBP、HEIC、HEIF;宽高 [256, 5760] px;宽高比 [0.4, 2.5];≤ 30 MB;首帧 ≤ 1、尾帧 ≤ 1、参考图 ≤ 9 |
| 视频 | MP4、MOV(视频 H.264 / H.265,音频 AAC / MP3);≤ 50 MB;≤ 3 个;单段 [2, 15] 秒且总时长 ≤ 15 秒;宽高 [256, 5760] px;宽高比 [0.4, 2.5];帧率 [23.976, 60] |
| 音频 | WAV、MP3;≤ 15 MB;≤ 3 个;单段 [2, 15] 秒且总时长 ≤ 15 秒 |
| 请求体 | 总大小 ≤ 64 MB,大文件请用公网 URL |
参考素材的尺寸和宽高比由服务商校验:不符合时服务商以错误码 2013 拒绝,并在报错中指出是哪一项(如 content[N].image_url),不收费。H3-Max 不支持多张参考图,服务商会拒绝并建议改用 H3(H3-Max 已被服务商下线,目前不可用)。
计费
| 任务 | 计量 | 分档 |
|---|---|---|
视频生成(minimax-h3) |
按秒 | 480P / 768P / 2K 三档 |
视频生成(minimax-h3-max,已被服务商下线,目前不可用,请改用 minimax-h3) |
按秒 | 480P / 768P 两档 |
视频升清(/v1/videos/regenerations) |
按秒 | 单独一档 |
上下文增强(/v1/videos/context) |
按 Token | 输入、输出两项分开计 |
- 计费秒数是输入 + 输出的总和,即任务对象中的
usage.duration_seconds:传了参考视频时,参考视频的秒数同样计入(例如 4 秒参考视频 + 4 秒输出,duration_seconds为 8)。参考音频不收费。视频升清不相加,duration_seconds只计源视频的秒数(实测源视频 4 秒,计 4)。 - 参考图单独计一项(两个模型的参考图单价不同):
minimax-h3的参考图前 5 张免费,超出部分按张计费。张数不在usage中,费用可在日志中查看。 - 上下文增强按输入、输出 Token 两项计费,任务对象的
usage只列出completion_tokens(输出),输入 Token 的费用同样计入。 - 价格在提交时锁定;任务变为
completed时按服务商实际返回的计量结算;failed的任务(包括超时)不收费。在日志中查看任务费用的方法见异步任务。
完整调用示例
先用上下文增强把提示词扩写,再用增强后的提示词生成 768P 视频,轮询到结束后下载。cURL 示例需要 jq,请保存为脚本文件后用 bash 运行(出错时用 exit 退出)。
BASE=https://api.lyrouter.com/v1
AUTH="Authorization: Bearer $LYROUTER_API_KEY"
# 提交任务(请求体从标准输入读取),输出任务 ID;没拿到任务 ID 时打印响应并返回失败
submit() {
local resp id
resp=$(curl -s "$BASE/$1" -H "$AUTH" -H "Content-Type: application/json" -d @-)
id=$(echo "$resp" | jq -r '.id // empty')
if [ -z "$id" ]; then echo "提交失败:$resp" >&2; return 1; fi
echo "task: $id" >&2
echo "$id"
}
# 轮询一个任务直到结束,输出最终的任务对象;查询出错或等待超过 2 小时时返回失败
wait_task() {
local delay=10 give_up_at=$(( $(date +%s) + 2 * 3600 )) task status
while [ "$(date +%s)" -le "$give_up_at" ]; do
sleep $delay
delay=$(( delay * 3 / 2 > 30 ? 30 : delay * 3 / 2 ))
task=$(curl -s "$BASE/videos/$1" -H "$AUTH")
status=$(echo "$task" | jq -r '.status')
case "$status" in
completed|failed) echo "$task"; return 0 ;;
queued|in_progress|"") ;; # 空值多为网络抖动:保留任务 ID 继续查
*) echo "查询出错:$task" >&2; return 1 ;;
esac
done
echo "$1 仍在处理,可稍后用同一个 ID 继续查询" >&2; return 1
}
# 1. 上下文增强,拿到增强后的提示词;失败时打印原因并退出
CTX_ID=$(echo '{"model":"minimax/minimax-h3","prompt":"一只猫在雨里走过霓虹街道","seconds":5}' \
| submit videos/context) || exit 1
CTX=$(wait_task "$CTX_ID") || exit 1
PROMPT=$(echo "$CTX" | jq -r '.output_text // empty')
if [ -z "$PROMPT" ]; then echo "$CTX" | jq '.error'; exit 1; fi
# 2. 用增强后的提示词生成视频
VIDEO_ID=$(jq -n --arg p "$PROMPT" \
'{model:"minimax/minimax-h3",prompt:$p,size:"768P",seconds:5}' \
| submit videos) || exit 1
TASK=$(wait_task "$VIDEO_ID") || exit 1
# 3. 完成则下载,失败则打印原因
if [ "$(echo "$TASK" | jq -r '.status')" = "completed" ]; then
curl -sL "$BASE/videos/$VIDEO_ID/content" -H "$AUTH" -o video.mp4
else
echo "$TASK" | jq '.error'
fi
import os
import time
import httpx
BASE = "https://api.lyrouter.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['LYROUTER_API_KEY']}"}
def wait_task(client: httpx.Client, task: dict, max_wait: int = 2 * 3600) -> dict:
"""从 10 秒开始轮询,逐步放宽到 30 秒,直到任务结束。"""
if not task.get("id"):
raise RuntimeError(f"没有拿到任务 ID:{task}")
print("task:", task["id"])
delay, give_up_at = 10, time.time() + max_wait
while task["status"] in ("queued", "in_progress"):
if time.time() > give_up_at:
raise TimeoutError(f"{task['id']} 仍在处理,可稍后用同一个 ID 继续查询")
time.sleep(delay)
delay = min(delay * 1.5, 30)
try:
resp = client.get(f"{BASE}/videos/{task['id']}")
resp.raise_for_status()
except httpx.TransportError:
continue # 网络抖动:保留任务 ID 继续查,不要重新提交
task = resp.json()
if task["status"] == "failed":
err = task.get("error", {})
raise RuntimeError(f"{err.get('code')}: {err.get('message')}")
return task
with httpx.Client(headers=HEADERS, timeout=60) as client:
# 1. 上下文增强,拿到增强后的提示词
resp = client.post(f"{BASE}/videos/context", json={
"model": "minimax/minimax-h3",
"prompt": "一只猫在雨里走过霓虹街道",
"seconds": 5,
})
resp.raise_for_status()
prompt = wait_task(client, resp.json())["output_text"]
# 2. 用增强后的提示词生成视频
resp = client.post(f"{BASE}/videos", json={
"model": "minimax/minimax-h3",
"prompt": prompt,
"size": "768P",
"seconds": 5,
})
resp.raise_for_status()
task = wait_task(client, resp.json())
# 3. 下载:接口返回 302,跟随跳转即可
with client.stream("GET", f"{BASE}/videos/{task['id']}/content",
follow_redirects=True, timeout=600) as video:
video.raise_for_status()
with open("video.mp4", "wb") as f:
for chunk in video.iter_bytes():
f.write(chunk)
print("已保存 video.mp4,用量:", task.get("usage"))
import { writeFile } from "node:fs/promises";
const BASE = "https://api.lyrouter.com/v1";
const headers = { Authorization: `Bearer ${process.env.LYROUTER_API_KEY}` };
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function submit(path, body) {
const resp = await fetch(`${BASE}${path}`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!resp.ok) throw new Error(await resp.text());
return resp.json();
}
// 从 10 秒开始轮询,逐步放宽到 30 秒,直到任务结束
async function waitTask(task) {
if (!task.id) throw new Error(`没有拿到任务 ID:${JSON.stringify(task)}`);
console.log("task:", task.id);
let delay = 10_000;
while (task.status === "queued" || task.status === "in_progress") {
await sleep(delay);
delay = Math.min(delay * 1.5, 30_000);
let resp;
try {
resp = await fetch(`${BASE}/videos/${task.id}`, { headers });
} catch {
continue; // 网络抖动:保留任务 ID 继续查,不要重新提交
}
if (!resp.ok) throw new Error(await resp.text());
task = await resp.json();
}
if (task.status === "failed") {
throw new Error(`${task.error?.code}: ${task.error?.message}`);
}
return task;
}
// 1. 上下文增强,拿到增强后的提示词
const ctx = await waitTask(await submit("/videos/context", {
model: "minimax/minimax-h3",
prompt: "一只猫在雨里走过霓虹街道",
seconds: 5,
}));
// 2. 用增强后的提示词生成视频
const task = await waitTask(await submit("/videos", {
model: "minimax/minimax-h3",
prompt: ctx.output_text,
size: "768P",
seconds: 5,
}));
// 3. 下载:fetch 默认跟随 302 跳转
const video = await fetch(`${BASE}/videos/${task.id}/content`, { headers });
if (!video.ok) throw new Error(`download failed: ${video.status}`);
await writeFile("video.mp4", Buffer.from(await video.arrayBuffer()));
console.log("saved video.mp4", task.usage);
常见错误
错误响应为 {"error":{"message":"...","type":"...","code":"..."}}。
| 状态码 | error.message |
error.code |
原因与处理 |
|---|---|---|---|
| 400 | this model takes discrete resolution tiers, not arbitrary sizes: ... |
invalid_parameter |
size 的短边不是 480 或 768。改写档位名(如 768P、2K)或短边正好为 480 / 768 的尺寸 |
| 400 | size implies an aspect ratio this model does not support: <取值> |
invalid_parameter |
size 推出的宽高比不在支持的比例中 |
| 400 | seconds must be a positive whole number of seconds |
invalid_parameter |
seconds 不是正整数 |
| 400 | <参数名> is not supported for this model |
invalid_parameter |
传了 MiniMax 不支持的 generate_audio、output_format、omni_reference_task_type,或在 /v1/videos 上传了 source_video。从请求中删掉 |
| 400 | seconds is not supported for video regeneration (the source video determines the duration) |
invalid_parameter |
视频升清不接受 seconds,删掉即可 |
| 400 | source_video is required for video regeneration (the 768P video to upscale) |
invalid_parameter |
视频升清缺少源视频 |
| 400 | This model does not support the videos_regenerations operation(或 videos_context) |
unsupported_model_operation |
所选模型不支持视频升清或上下文增强,改用 minimax/minimax-h3。目前并非所有不支持的模型都返回这条,见表下说明 |
| 400 | unsupported parameters for this model: <参数名> |
unsupported_parameters |
带了 X-Gateway-Strict-Parameters: true,且请求中有会被丢弃的参数 |
| 403 | Model is not available in the model plaza |
model_not_available |
模型没有在本工作空间开通,或使用了虚拟模型、lyrouter/auto。换用已开通的具体模型 ID |
| 404 | video task not found |
not_found |
任务 ID 不存在、已超过 7 天、属于其他工作空间,或传入的是服务商的任务 ID |
| 409 | video is not ready yet |
not_ready |
任务还没完成(或已失败)就调用了 /content。先查询到 completed |
| 409 | cancelling an in-flight video task is not supported: ... |
cancel_not_supported |
对进行中的任务调用了 DELETE。请等待任务结束 |
| 429 | upstream concurrency full |
upstream_concurrency_full |
服务商账户的并发任务已满,换 API Key 无效,稍后重新提交 |
- 目前用其他模型调用视频升清或上下文增强,不一定返回
unsupported_model_operation:Seedance 2.5 调视频升清返回 400source_video is not supported for this model(invalid_parameter);Seedance 模型调上下文增强会被受理,生成一条普通视频并照常计费;minimax/minimax-h3-max(已下线)调视频升清会被受理并建出任务,调上下文增强返回服务商透传的 400(invalid params, model MiniMax-H3-Max does not support resolution 2K, …,没有error.code)。这两个接口请只用minimax/minimax-h3调用。 - 用表单提交时
input_reference只能传 URL。目前上传文件不会报错,文件会被忽略,任务按没有参考视频的方式生成并照常计费;只有填了非 URL 的文本(如video.mp4)时才返回 400 纯文本input_reference must be a URL; uploading a file is not supported by this gateway (pass a publicly reachable https:// URL instead)。这类由网关返回的纯文本报错,响应头目前仍是Content-Type: application/json,解析前请先判断正文是不是 JSON。 - 时长超出范围、图生视频与多模态参考混用、参考素材不合规等由服务商拒绝,状态码和报错原文由服务商决定;任务提交后才发现的问题以失败任务的形式返回,见上文「查询任务」。完整列表见错误码与请求标识。
常见问题
提示短边必须是 480 或 768,怎么办?
答: MiniMax 的分辨率是离散档位,不是任意尺寸。直接写档位名(如 "768P"、"2K"),或使用短边正好为 480 / 768 的尺寸(如 1366x768)。2K 只能写档位名。
H3-Max 能做视频升清或上下文增强吗?
答: 不能。这两个接口只支持 minimax/minimax-h3。目前用 H3-Max 调用时网关不会直接拒绝:调视频升清会被受理并建出任务;调上下文增强返回服务商透传的 400(invalid params, model MiniMax-H3-Max does not support resolution 2K, …,没有 error.code)。H3-Max 也不支持 2K 和 4 秒时长。另外,H3-Max 已被服务商下线,目前连普通视频生成也不可用(调用返回 HTTP 200,但任务对象为空、没有任务 ID),请改用 minimax/minimax-h3。
升清后的视频效果不理想,怎么办?
答: 确认三件事:源视频是 H3 生成的 768P 产物;prompt 是生成源视频时实际送入模型的最终提示词(用过上下文增强的,填增强之后的那份);参考素材与生成时一致。这些不一致时网关和服务商都不会报错,只是效果不达预期。
上下文增强完成了,为什么下载不到视频?
答: 上下文增强只产出文本,结果在任务对象的 output_text 中,没有视频可下载;目前对它调用 /content 会返回 HTTP 500。把 output_text 作为 prompt 提交给 POST /v1/videos 才会生成视频。
传了参考视频,为什么计费秒数比视频时长多?
答: MiniMax 的计费秒数是输入加输出:参考视频的秒数也计入 usage.duration_seconds。参考音频不收费,参考图前 5 张免费、超出部分按张计费。
传了参考视频,任务失败并提示 aspect ratio "adaptive" is not supported,怎么办?
答: 完整报错是 h3submit: aspect ratio "adaptive" is not supported for task ref2va。传参考视频(input_reference)时,MiniMax 要求明确的宽高比,而 size 写成档位名(如 480P)时网关发出的是自适应比例。把 size 改成 宽x高,短边为 480 或 768,例如 854x480、1366x768,再重新提交。这类失败不收费。
视频地址过期了,还能重新下载吗?
答: 不能。视频地址在任务完成时确定,再次调用 /content 拿到的仍是同一个地址,过期后需要重新提交任务。请在任务完成后立即下载或转存。
查询结果一直是 in_progress,怎么办?
答: 视频生成通常需要几分钟。提交 24 小时后仍未完成的任务不会再有结果,也不收费,可以停止轮询,并在控制台 多媒体生成 页面按任务 ID 查看任务状态。不要在等待期间重复提交同样的请求,每次提交都会生成新任务并单独计费。