BeatAPI では、3つの動画モデルを同じエンドポイント POST /v1/videos/tasks、同じ API キーで呼べます。
では、model の名前を変えるだけで動くのか。答えは「一部だけ」です。エンドポイントと状態確認の流れは共通ですが、尺・解像度・比率の許容値はモデルごとに違います。そのまま送ると 400 になるか、思っていたのと違う尺で課金されます。
この記事では、値が違う項目を表にまとめ、送る前に止めるチェック関数を書きます。
8秒あたりの料金
| モデル | 720p(H3 Normal は 768p) | 1080p | 4K |
|---|---|---|---|
| Veo 3.1 Lite(音声つき) | $0.15 | $0.25 | $0.75 |
| Veo 3.1 Fast(音声つき) | $0.30 | $0.40 | $0.90 |
| Gemini Omni 1.1 Flash | $0.48 | $0.72 | $1.44 |
| MiniMax H3 Normal | 768p $0.16 | $0.20 | — |
MiniMax H3 Normal には 480p($0.14)もあります。768p は 720p と同じ仕様ではないので、比べるときは表記どおりに扱ってください。
料金は 2026年11月5日時点の beatapi.io の表示価格です。まとめて生成する前に料金ページで再確認してください。
値が違う項目
公開 OpenAPI(openapi.json)のリクエスト定義から、テキスト・開始フレーム入力の場合をまとめました。
| 項目 | veo-3.1 |
minimax-h3-normal |
gemini-omni-1.1-flash |
|---|---|---|---|
duration |
送らない(8秒固定) | 5〜15秒、省略時 5 | 3〜10秒、省略時 5 |
resolution |
720p / 1080p / 4k
|
480p / 768p / 1080p
|
720p / 1080p / 4k
|
aspect_ratio |
16:9 / 9:16 / auto
|
16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9
|
16:9 / 9:16
|
| 品質の指定 |
quality: Quality / Fast / Lite(省略時 Quality) |
なし | なし |
images(開始・終了フレーム) |
1〜2枚 | 1〜2枚 | 1〜2枚 |
| 参照画像 |
reference_images 1〜3枚(quality は Fast / Lite) |
reference_images 最大4枚 |
reference_images 1〜10枚 |
| 音声 | 付く | 付く(オフにする指定なし) | 付く(オフにする指定なし) |
特に気をつけたいのは3つです。
-
Veo 3.1 に
durationを付けると通らない:8秒固定で、余分なプロパティは受け付けません。 -
qualityを省略すると Veo 3.1 はQualityになる:上の表の Lite / Fast の料金で見積もっているなら、qualityを必ず明示します。 -
H3 Normal と Omni は
durationを省略すると5秒:8秒で見積もっているなら明示します。
送信前チェック関数
前回の記事の validate を、この3モデル用に広げます。
// validate.ts
type Spec = {
duration: { min: number; max: number; fixed?: boolean };
resolutions: string[];
aspects: string[];
qualities?: string[];
maxReferenceImages: number;
};
const SPECS: Record<string, Spec> = {
"veo-3.1": {
duration: { min: 8, max: 8, fixed: true },
resolutions: ["720p", "1080p", "4k", "4K"],
aspects: ["16:9", "9:16", "auto"],
qualities: ["Quality", "Fast", "Lite"],
maxReferenceImages: 3,
},
"minimax-h3-normal": {
duration: { min: 5, max: 15 },
resolutions: ["480p", "768p", "1080p"],
aspects: ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"],
maxReferenceImages: 4,
},
"gemini-omni-1.1-flash": {
duration: { min: 3, max: 10 },
resolutions: ["720p", "1080p", "4k", "4K"],
aspects: ["16:9", "9:16"],
maxReferenceImages: 10,
},
};
export type VideoReq = {
model: string;
prompt: string;
duration?: number;
resolution?: string;
aspect_ratio?: string;
quality?: string;
images?: string[];
reference_images?: string[];
};
export function validate(req: VideoReq): string[] {
const spec = SPECS[req.model];
if (!spec) return [`unknown model: ${req.model}`];
const errors: string[] = [];
if (spec.duration.fixed) {
if (req.duration !== undefined)
errors.push(`${req.model} は尺が固定です。duration を送らないでください`);
} else if (req.duration === undefined) {
errors.push(`${req.model} は duration を省略すると既定値になります。秒数を明示してください`);
} else if (!Number.isInteger(req.duration) || req.duration < spec.duration.min || req.duration > spec.duration.max) {
errors.push(`${req.model} の duration は ${spec.duration.min}〜${spec.duration.max} 秒です`);
}
if (req.resolution && !spec.resolutions.includes(req.resolution))
errors.push(`${req.model} は解像度 ${req.resolution} に対応していません(${spec.resolutions.join(" / ")})`);
if (req.aspect_ratio && !spec.aspects.includes(req.aspect_ratio))
errors.push(`${req.model} は比率 ${req.aspect_ratio} を受け付けません`);
if (spec.qualities) {
if (!req.quality) errors.push(`${req.model} は quality を明示してください(省略すると最上位の料金になります)`);
else if (!spec.qualities.includes(req.quality)) errors.push(`${req.model} の quality は ${spec.qualities.join(" / ")} です`);
if (req.reference_images?.length && req.quality === "Quality")
errors.push(`${req.model} は reference_images と Quality を併用できません`);
} else if (req.quality) {
errors.push(`${req.model} に quality はありません`);
}
if (req.images?.length && req.reference_images?.length)
errors.push("images(開始・終了フレーム)と reference_images は同時に使えません");
if (req.images && req.images.length > 2) errors.push("images は2枚までです");
if (req.reference_images && req.reference_images.length > spec.maxReferenceImages)
errors.push(`${req.model} の reference_images は ${spec.maxReferenceImages} 枚までです`);
return errors;
}
使い方はこうです。同じプロンプトを3モデルに送る前に、全部チェックします。
import { validate, type VideoReq } from "./validate";
const prompt = "A glass water bottle on a wooden table. Slow orbit, soft window light, no text overlay.";
const reqs: VideoReq[] = [
{ model: "veo-3.1", prompt, quality: "Lite", resolution: "720p", aspect_ratio: "16:9" },
{ model: "minimax-h3-normal", prompt, duration: 8, resolution: "768p", aspect_ratio: "16:9" },
{ model: "gemini-omni-1.1-flash", prompt, duration: 8, resolution: "720p", aspect_ratio: "16:9" },
// わざと間違えた例
{ model: "veo-3.1", prompt, duration: 8, resolution: "768p" },
];
for (const r of reqs) {
const errs = validate(r);
console.log(r.model, errs.length ? errs : "OK");
}
// 最後の行は、尺固定・解像度・quality 未指定の3つのエラーになる
チェックを通ったものだけを、前回までの submit → waitForTask に渡します。
// validate.ts に追記
const base = "https://api.beatapi.io/v1";
const headers = {
Authorization: `Bearer ${process.env.BEATAPI_API_KEY}`,
"Content-Type": "application/json",
};
export async function submitChecked(req: VideoReq, key: string): Promise<string> {
const errs = validate(req);
if (errs.length) throw new Error(errs.join("\n"));
const res = await fetch(`${base}/videos/tasks`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": key },
body: JSON.stringify(req),
});
if (!res.ok) throw new Error(`submit failed: ${res.status} ${await res.text()}`);
const { data } = await res.json();
return data.id; // まず保存する
}
自動で読み替えない理由
720p を 768p に、duration: 8 を「Veo なら削除」に、と自動で読み替える実装も考えられます。でも私はおすすめしません。
- 解像度や尺が変わると料金が変わる(8秒で H3 Normal の 768p は USD 0.16、Omni の 720p は USD 0.48)
- 出力の大きさや長さも変わり、後工程(編集・配信)の前提が崩れる
黙って置き換えるより、送る前にはっきりエラーにして、呼び出し側に選ばせる方が安全です。
比べるときは条件を固定する
3つのモデルを比べるなら、プロンプト・尺・比率は同じにして、解像度は各モデルの近い値(720p と 768p)にそろえます。品質や処理時間はモデルごとに違うので、自分の用途で1本ずつ測ってから使い分けを決めます。
この表は 2026年11月5日時点の公開定義です。モデルが更新されると許容値も変わることがあるので、SPECS は公開 OpenAPI から定期的に作り直してください。
出典・確認日
- BeatAPI 公開 API ドキュメント(openapi.json の Veo31VideoRequest / MinimaxH3NormalVideoRequest / GeminiOmni11FlashVideoRequest):2026年11月5日確認
- 料金:api.beatapi.io/v1/pricing と beatapi.io 料金ページ(8秒):2026年11月5日確認
モデルの仕様と料金:https://beatapi.io/pricing
