TL;DR
Bolt はアプリケーションのインターフェイスを生成し、CometAPI は動画生成の API を提供します。CometAPI キーはサーバーに保持し、POST /v1/videos で Vidu タスクを送信、返却されたタスク ID をポーリングし、完了した動画は認証済みのプレビューおよびダウンロードルートで公開します。必要なのは Bolt プロジェクト、選択したモデルにアクセスできる残高のある CometAPI アカウント、そしてサーバーファンクションの実行環境です。以下の例は統合のコアを解説するものであり、認証、クォータ、所有権チェック、永続的なジョブ記録は公開前に実装する必要があります。
Key Takeaways
• Bolt は自然言語のアプリ仕様からレスポンシブな動画スタジオ UI を生成します。
• CometAPI は、保護されたサーバーサイドの API キーを用いて、対応する生成モデルによる動画推論を提供します。
• まずはテキストから動画(text-to-video)で開始し、ジョブライフサイクルを検証後に画像から動画(image-to-video)へ拡張します。
• 本番運用には、認証、クォータ、タスクの所有権チェック、リトライ、耐久的な出力ストレージが必要です。
• 完了率、待ち時間、承認クリップのコスト、プロンプト遵守度で実価値を測定します。
What Are Bolt and CometAPI for AI Video Generation?
Bolt はインターフェイス、アプリケーションロジック、公開ワークフローを構築します。Bolt Cloud はデータベース、ホスティング、認証、ストレージ、サーバーファンクションなどのプロジェクトサービスを提供します。CometAPI は、対応する動画モデルと推論エンドポイントを含むモデル API アクセスを提供します。課金される推論は認証済みのサーバーファンクションの背後に配置し、永続的なジョブ記録、所有権チェック、課金制御を備えましょう。
Is CometAPI OpenAI-Compatible?
CometAPI は、対応するテキストおよびチャットモデルに対して OpenAI 互換のインターフェイスを提供します。ただし、使用する SDK とルートに応じてエンドポイントとモデルを設定してください。互換性があることは、すべてのモデルが同じリクエストスキーマを受け付けることを意味しません。
Vidu の動画 API は OpenAI 互換のチャットインターフェイスとは別です。動画作成は multipart/form-data を使う POST /v1/videos を使用するため、アプリケーションは保護されたサーバーサイドファンクションから動画エンドポイントを直接呼び出す必要があります。
How Does the CometAPI Vidu Video API Work?
Create a video task
multipart/form-data を用いた POST /v1/videos でタスクを作成します。本チュートリアルでは viduq3 を使用しますが、viduq3-turbo もドキュメントに記載されたオプションです。API キーでモデルへのアクセス権を確認し、返却されたタスク ID を保持してください。作成 API 仕様はこちらのリファレンスを参照してください。
POST /v1/videos parameters
以下の表は作成時の入力です。スカラーのフォームフィールドは文字列として送信します。seconds には "1" から "16" の整数値文字列を使用します。アプリケーション側でシリアライズ前に数値の長さを検証できます。本チュートリアルの 2,000 文字のプロンプト制限はアプリケーションポリシーです。
| Parameter | Type | Example | Purpose |
|---|---|---|---|
| model | String | viduq3 | 生成モデル |
| prompt | String | Cinematic product shot | テキストによる指示 |
| seconds | String | 1 | クリップの長さ:整数値の文字列、1–16 秒 |
| size | String | 1280x720 | 出力サイズ |
| input_reference | File | product.png | 任意の画像リファレンス |
サーバーはタスク識別子として id を返します。これは作成パラメータではありません。リクエストしたユーザーのジョブ記録とともに保存し、後続のステータス取得やコンテンツ取得に使用します。上の取り消し線付きの id 行は削除を示すためにのみ残しています。
- 540p tier: 実験には API の size 値 960x528 を使用します。
- 720p tier: Web プレビューには 1280x720 を使用します。
- 1080p tier: より高品質な配信には 1920x1080 を使用します。
サーバーサイドの検証でサポート外の組み合わせを拒否し、ユーザーが無制限の課金生成を要求できないようにしてください。
Poll the task status
ジョブ所有権を検証したうえで、バックエンドから GET /v1/videos/{task_id} を確認します。タスクが終端状態に到達するまで継続し、ページリフレッシュやブラウザのタイムアウト後でも同じジョブを再開できるようにタスク ID を保持します。
Download the completed video
完了後、バックエンドから GET /v1/videos/{task_id}/content をリクエストし、結果をストリーム配信するか管理下のストレージに保存します。以下の実装ガイドでは、これらの操作を Bolt に接続する方法を示します。
How to Build an AI Video Generator Using Bolt + CometAPI
Step 1: Create the project in Bolt
Bolt を開き、React + TypeScript プロジェクトを作成するよう依頼します。次の仕様をプロンプト欄に貼り付け、課金生成の接続前に生成されたインターフェイスを確認してください。
Build a responsive AI Video Studio using React, TypeScript, and Tailwind CSS.
Use a dark-themed layout with prompt editing, example prompts, 5/10/15-second
choices, 540p/720p/1080p options, Generate Video button, job status,
video preview and download, and a recent-generations section.
Use Bolt Cloud authentication, database, and server functions.
Require sign-in before video creation. Store COMETAPI_KEY only in server secrets.
Create authenticated generate-video and video-status server endpoints.
Connect to real CometAPI tasks; poll status every 10 seconds.
Do not use mock videos in the production path.

Step 2: Configure the CometAPI API key
CometAPI で API キーを作成し、バックエンドのシークレットに COMETAPI_KEY という名前で追加します。フロントエンドのソースファイルに保存したり、ブラウザコードに露出させたり、VITE_ 接頭辞の環境変数を使用したりしないでください。
Bolt プロジェクトの設定で、プロジェクトのサーバーサイドシークレット管理インターフェイスを通じて COMETAPI_KEY を追加します。フロントエンドのソースコードに配置したり、ブラウザの JavaScript に露出させないでください。次の行は名前付けの例であり、フロントエンドの .env ファイルではありません。

COMETAPI_KEY=your_actual_cometapi_api_key
Step 3: Submit a video-generation task
以下の Deno スタイルの関数は、プロバイダへのリクエストのコアを示します。実際にデプロイする前に、実セッションの検証、クォータ、ユーザー所有のジョブ記録でラップする必要があります。
この例は Supabase スタイルの Deno エッジファンクションのレイアウトを使用します。Bolt に、プロジェクトで実際に構成されているサーバーランタイムに配置するよう依頼してください。認証と永続化に関するコメントは統合ポイントであり、実装済みの保護ではありません。このスケルトンを公開の課金エンドポイントとしてデプロイしないでください。
// supabase/functions/generate-video/index.ts
import { serve } from "https://deno.land/std/http/server.ts";
serve(async (req: Request) => {
if (req.method !== "POST") return Response.json({error:"Method not allowed"},{status:405});
try {
// Verify the signed-in user and enforce quotas here.
const {prompt, seconds, size} = await req.json();
const sizes = ["960x528", "1280x720", "1920x1080"];
if (typeof prompt !== "string" || !prompt.trim() || prompt.length > 2000 ||
!Number.isInteger(seconds) || seconds < 1 || seconds > 16 ||
!sizes.includes(size)) {
return Response.json({error:"Invalid options"},{status:400});
}
const key = Deno.env.get("COMETAPI_KEY");
if (!key) throw new Error("Missing API key");
const form = new FormData();
form.append("model", "viduq3");
form.append("prompt", prompt.trim());
form.append("seconds", String(seconds));
form.append("size", size);
const response = await fetch("https://api.cometapi.com/v1/videos", {
method: "POST", headers: {Authorization: `Bearer ${key}`}, body: form,
signal: AbortSignal.timeout(60000)
});
if (!response.ok) throw new Error(`Provider status ${response.status}`);
const result = await response.json();
const taskId = result.id ?? result.task_id;
if (!taskId) throw new Error("Task ID missing");
// Persist taskId and owner ID in application database here.
return Response.json({taskId, status: result.status ?? "queued"});
} catch (e) {
console.error(e);
return Response.json({error:"Unable to create video"},{status:500});
}
});
Step 4: Retrieve generation status
送信は非同期のジョブ ID を返します。サーバーエンドポイントを介して GET /v1/videos/{task_id} を確認する際は、リクエストしているユーザーがそのジョブを所有していることを検証してください。

// Server-only helper
async function getVideoStatus(taskId: string) {
const key = Deno.env.get("COMETAPI_KEY");
if (!key) throw new Error("Missing API key");
const response = await fetch(
`https://api.cometapi.com/v1/videos/${encodeURIComponent(taskId)}`,
{headers: {Authorization: `Bearer ${key}`}, signal: AbortSignal.timeout(60000)}
);
if (!response.ok) throw new Error(`Status ${response.status}`);
const task = await response.json();
return {taskId, status: task.status, progress: task.progress ?? null};
}
タスクは queued で開始し、in_progress に進む場合があり、最終的に completed、failed、または error で終了します。completed 以外ではプレビューやダウンロードを有効化しないでください。終端の失敗状態ではエラーを表示し、新しいリクエストを許可します。
Step 5: Connect the Bolt frontend
type VideoTask = {taskId: string; status: string; progress?: number | null};
async function startVideo(prompt: string, seconds: number, size: string): Promise<VideoTask> {
const res = await fetch("/api/generate-video", {
method: "POST", headers: {"Content-Type":"application/json"},
body: JSON.stringify({prompt, seconds, size})
});
if (!res.ok) throw new Error("Generation request failed");
return res.json();
}
async function checkVideo(taskId: string): Promise<VideoTask> {
const res = await fetch(`/api/video-status?id=${encodeURIComponent(taskId)}`);
if (!res.ok) throw new Error("Status request failed");
return res.json();
}
async function waitForVideo(taskId: string, onUpdate: (task: VideoTask) => void) {
const deadline = Date.now() + 20 * 60 * 1000;
while (Date.now() < deadline) {
const task = await checkVideo(taskId);
onUpdate(task);
if (task.status === "completed") return task;
if (["failed", "error"].includes(task.status)) throw new Error("Render failed");
await new Promise(resolve => setTimeout(resolve, 10000));
}
throw new Error("Polling paused; resume this task ID before submitting again");
}
/api/ のパスはアプリケーションのルートとして設定する必要があります。Bolt Cloud のサーバーファンクションを利用する場合は、生成されたバックエンドクライアントと認証済みのエンドポイント URL を使用してください。コンポーネントのアンマウント時にポーリングを中止し、429/5xx 応答には制限付きのバックオフを使用します。ブラウザ側のポーリング期限が尽きてもプロバイダの失敗を示す証拠にはなりません。タスク ID を保持し、新たな課金タスクを作成する前にステータスの再チェックを再開してください。
Step 6: Preview and download the result
ジョブが完了したら、バックエンドで GET /v1/videos/{task_id}/content を取得します。データを認証済みのジョブ所有者へストリーム配信するか、管理されたオブジェクトストレージに保存して認可済み URL を提供します。CometAPI のベアラーキーをブラウザに公開してはいけません。
アプリケーションはプレビューコンポーネントのために、ユーザー所有のコンテンツルートまたは認可されたストレージ URL を公開するべきです。署名付き URL は有効期限までそれを保持する誰もがアクセスできます。寿命を短く保ってください。信頼できるダウンロードには、同一オリジンのルートで適切な Content-Disposition ヘッダーを使用してください。ブラウザはクロスオリジン URL に対して download 属性を無視する場合があります。
type VideoPreviewProps = {videoUrl: string};
export function VideoPreview({videoUrl}: VideoPreviewProps) {
return <div className="rounded-xl p-4">
<video controls playsInline className="w-full rounded-lg" src={videoUrl}/>
<a href={videoUrl} download="ai-generated-video.mp4">Download Video</a>
</div>;
}
Step 7: Test and publish
まずは 540p の 5 秒リクエストでテストします: “A cinematic close-up of a silver smartwatch on a dark desk. The camera slowly moves left to right. Soft morning light reflects from the metal.” 一つのリクエストが一つのタスクを作成していること、ステータスが進むこと、結果が再生できること、ダウンロードが成功することを確認します。公開前に、無効なプロンプト、期限切れセッション、レート制限、タスク所有権、プロバイダの失敗もテストしてください。
完了チェック: 二人目のユーザーでサインインし、最初のユーザーのジョブが読み取りもダウンロードもできないことを確認します。レンダリング中にページをリフレッシュして保存されたタスクが復元できることを確認します。ブラウザのリクエストとビルド済みアセットを検査し、キーが誤って露出していないことを確認します。再生とダウンロードに加えてこれら三つのチェックすべてを通過した場合にのみ公開してください。
How Can You Add Image-to-Video Generation?
画像から動画を行うには、input_reference として検証済みの画像ファイルを multipart 本文に 1 つ追加します。現在のルートは画像 1 枚あたり最大 20 MB をドキュメント化しています。必要に応じてアプリケーション側でより小さな制限を設け、サーバーでコンテンツタイプと実際のファイル内容を検証してください。画像は認証済みのバックエンドを経由させ、ブラウザのアップロードとともに CometAPI キーを送らないでください。
const form = new FormData();
form.append("model", "viduq3");
form.append("prompt", prompt);
form.append("seconds", "5");
form.append("size", "1280x720");
form.append("input_reference", imageFile);
const response = await fetch("https://api.cometapi.com/v1/videos", {
method: "POST", headers: {Authorization: `Bearer ${apiKey}`}, body: form
});
if (!response.ok) throw new Error(`API ${response.status}`);
const result = await response.json();
console.log(result.id ?? result.task_id);
画像入力の場合、シーンの繰り返しではなく、望ましい動きやカメラアクションを記述してください: “The character turns toward the window. Curtains move gently in the breeze. Preserve face, clothing, and lighting. Use a subtle forward camera motion.”
Vidu Q3 vs Other AI Video Models: What Should You Measure?
同じプロンプト、長さ、解像度、受け入れ基準でモデルを比較します。本節は比較方法を定義するものであり、検証済みの勝者を主張するものではありません。公開する結果には、モデルバージョン、ルート、テスト日、サンプル数を記録してください。
- 完了率: 送信したジョブに対する成功ジョブの割合で信頼性を測定します。
- レイテンシ: 典型的な体験と遅いリクエストを把握するために P50 と P95 の処理時間を追跡します。
- プロンプト遵守度: リクエストにどれだけ忠実かを人手レビューまたは標準化された評価で測定します。
- 時間的整合性: フレーム間の連続性を確認して視覚の安定性を評価します。
- 音声同期: タイミングと可聴性を確認してセリフや音声を評価します。
- 受理クリップあたりのコスト: 承認された出力に対する総支出を割って運用経済性を把握します。
How Much Does the CometAPI Video Generation API Cost?
以下の表は CometAPI の Vidu Q3 および Vidu Q3 Turbo API に関する参考価格です。実際の費用はモデル、解像度、生成設定によって異なる場合があります。動画生成予算を見積もる前に、CometAPI アカウントで最新の価格とモデルの提供状況を確認してください。
| CometAPI model | Resolution | Historical USD / second | Illustrative USD / 5-second task |
|---|---|---|---|
| Vidu Q3 | 540p | $0.056 | $0.280 |
| Vidu Q3 | 720p | $0.1232 | $0.616 |
| Vidu Q3 | 1080p | $0.1232 | $0.616 |
| Vidu Q3 Turbo | 540p | $0.028 | $0.140 |
| Vidu Q3 Turbo | 720p | $0.0616 | $0.308 |
| Vidu Q3 Turbo | 1080p | $0.0616 | $0.308 |
CometAPI の Vidu Q3 Turbo API は 1 秒あたり $0.028 から利用可能です。価格は解像度、生成モード、モデルバージョンにより変動する場合があります。動画生成前に、最新料金を CometAPI アカウントで確認してください。
上記の価格例は標準的なテキストから動画および画像から動画の生成に適用されます。他の生成モードや参照画像の構成では異なる料金となる場合があります。税金、ストレージ、帯域幅、繰り返し生成の試行などの追加費用は含まれていません。
参考レートに基づくと、5 秒の 720p 動画は Vidu Q3 で約 $0.616、Vidu Q3 Turbo で約 $0.308 です。540p ではそれぞれ $0.280 と $0.140 です。これらの数値は概算であり、料金を保証するものではありません。正確な予算立案には、推定コストと実際の API 利用および請求記録を比較してください。
How Can You Migrate an Existing Video Generator to Bolt + CometAPI?
| Component | Migration action |
|---|---|
| Frontend | Bolt でアプリを再構築/インポート |
| Credentials | サーバーサイドのシークレットへ移行 |
| Generation | CometAPI アダプターを実装 |
| Parameters | サポートされるモデルフィールドへ対応 |
| Job IDs | タスク識別子を正規化 |
| Status | 終端状態とリトライを処理 |
| Downloads | 管理されたコンテンツエンドポイントを使用 |
| Storage | 完了結果を永続化 |
| Billing | クォータと予算を再計算 |
プロバイダアダプターの背後で段階的に移行します。リクエストと出力の挙動を検証し、まずはユーザーの一部で開始、成功率とレイテンシを比較し、性能が十分になるまでロールバックルートを維持します。
FAQ
How can I make an approved visual style repeatable across a series?
承認済みのクリップを再現可能なクリエイティブ仕様として扱います。正確なプロンプト、モデルとルート、長さ、解像度、参照アセットのバージョン、出力識別子を保存します。少数の参照画像と、ライティング、レンズ、パレット、被写体の詳細を一貫して記述します。何が有効だったかを特定できるよう、1 回の反復で大きな変数は 1 つだけ変更します。プロンプトを繰り返しても同じ出力は保証されません。ルートがシードを公開している場合はそれを記録しますが、シーケンスとしての連続性のために各クリップを必ずレビューしてください。
How should a multi-shot story stay coherent when each generation is a short clip?
脚本を、明確なアクションと定義された導入・終わりの構図を持つショットに分割します。キャラクターの外見、衣装、小道具、照明、カメラ方向に関するコンティニュイティシートを維持します。可能な場合は、文章だけに頼らず、承認済みのフレームを次のショットへ参照画像として渡します。編集は別パスで行い、組み立て、トリミング、音声のバランス調整をします。シーケンスとして遷移をレビューします。単独では良く見えるクリップでも、並べるとコンティニュイティを崩すことがあります。
What should happen if the browser times out after a paid submission?
保存済みのプロバイダタスクと照合されるまでは不確実な結果として扱います。ローカルなアプリケーションのリクエスト識別子とプロバイダのタスク ID を保持し、ユーザーがそのジョブを再開してステータス確認を続行できるようにします。ID の返却前に送信自体がタイムアウトした場合は、別の試行を提案する前に、利用可能なリクエストログと使用状況記録を確認してください。HTTP タイムアウトが課金されなかったことを意味すると約束しないでください。新たな課金試行は明示的に行い、ダブルクリック送信を防ぐためにアプリケーションレベルのリクエストロックを使用します。
What should I review before accepting private customer reference images?
アプリケーションが受け付けるアセット、アップローダーがそれらを使用する許可を持つか、下流のどのサービスに転送されるかを決めます。機密性を約束する前に、現行のプロバイダの保持、ログ、削除、許容用途に関する規約を確認してください。共有デモでは個人情報や機密性の高い参照素材を避けます。保存は最小限に抑え、プライベートなオブジェクトはユーザーごとに分離し、アップロードと生成ファイルの両方に有効期限と削除ワークフローを定義します。プライベートなアプリケーションストレージバケットだけでは、モデルプロバイダの保持ポリシーを説明しません。
How can I keep the project portable if my backend or video provider changes?
インターフェイスはアプリ所有のジョブスキーマに依存させ、プロバイダ固有のリクエストフィールドとステータスマッピングは別のアダプター内に置きます。内部ジョブ ID とプロバイダのタスク ID の両方を保存し、リクエストを再生成するために必要なアセット参照を保持します。Bolt が生成したアプリコードと構成はバージョン管理下に置きます。バックエンドを置き換える場合は、ユーザーとジョブ記録を移行し、アクセス境界、署名付き URL、過去のダウンロードをテストしてからトラフィックを切り替えます。コードのエクスポートだけでは、稼働中のデータベースや保存されている動画ファイルは移行されません。
Conclusion
Bolt + CometAPI は動画生成アプリケーションにとって実用的な基盤です。Bolt は Web アプリ作成を加速し、CometAPI は対応する動画モデルへのアクセスを提供します。まずは安全なテキストから動画のワークフローで開始し、ジョブライフサイクルと課金制御の機能を証明した後に、画像参照、生成履歴、モデル選択、高度なクリエイティブツールを追加してください。フロントエンドの操作と課金サーバーサイド推論を分離することは、安全で信頼できるプロダクトに不可欠です。
