3行でいうと
- 流れは3段です。
POST /v1/generationsで依頼し、GET /v1/generations/{generation_id}で状態を聞き、completedになったらoutputの署名つきURLから取り出します。URLは1時間で期限切れです。 - 1つの入口に、
type(image、image_edit、layering、video、video_edit、video_reframe)で、画像と動画の仕事を頼み分けます。モデルは画像が uni-1 と uni-1-max、動画が ray-3.2 です。 - 状態を聞く間隔と待ち時間、元の動画の長さ、動画の解像度の数字は、公式のページ同士で違います(本文の表に並べました)。
- 公式のPython SDKは、依頼、再試行、タイムアウト、エラー型の書き方がREADMEにあります。
- ファイルAPI、上限(429)、エラー、生成の削除、Admin API、LLM Inferenceは09にあります。
この記事は、公式の資料を2026年10月25日に読んでまとめたものです。この記事は、実際に使って確かめた記録ではありません。手順は「公式の手順を順に並べたもの」で、コード・コマンドは、公式の例を写したものと、この記事で組んだ例(動作は確かめていません)を、そのつど区別して書きます。取得した要約でコマンドの行が欠けて見えた所は、この記事で補ったと明記します。実行の前に、公式ページの原文と見比べてください。
先に結論
- コードを書く側の判断材料。 非同期(依頼→待つ→取り出す)の形で、待ち時間とURLの期限が仕様に入っています。
- 公式が recommended と書くもの。 状態の確認は、レート制限のページが「2〜5秒おきが recommended」、エラーのページが「2〜5秒」と書きます。FAQとクイックスタートは別の数字です(本文)。
- 無料枠はなく、残高が必要。 FAQは、従量課金で無料枠・最低利用額なし、と書いています(05)。
- 「Luma Agents API」の資料と、古い「Dream Machine API」(docs.lumalabs.ai)は別の世代です。 移行の案内は03にあります。
前提:用語をそろえる
- 生成(generation):1回の依頼と、その結果のまとまりです。IDで追えます。
- 署名つきURL(presigned URL):期限つきで、ログイン不要で取り出せるURLです。
- ポーリング:結果ができたか、一定間隔で聞きに行くことです。
- JSON/curl:JSONは、データの書き方の1つ。curlは、ターミナルからWebに依頼を出すコマンドです。
- base64:画像などを文字列に直す書き方です。埋め込みで素材を渡すときに使います。
1. 基本の流れ:依頼、状態の確認、取り出し
1-1. 公式のクイックスタートの順
- 依頼:
POST https://agents.lumalabs.ai/v1/generations。認証は、Authorization: Bearerに、環境変数 LUMA_AGENTS_API_KEY のキーを入れる(05)。 - 状態:
GET https://agents.lumalabs.ai/v1/generations/{generation_id}を、completedかfailedになるまで繰り返す。 -
取り出し:
completedなら、output[0].url(動画も同じ形)の署名つきURLからダウンロードする。 -
受け付けられると HTTP 201 で、状態は
queuedです。状態はqueued、processing、completed、failedです。 - 応答の
outputは配列で、各要素にtypeと署名つきのurlが入ります。failedのときはfailure_reasonとfailure_codeが付き、outputは空です。 user_id(任意):エンドユーザーを示す、個人情報を含まない固定のID(256字まで)を渡せます。クイックスタートは、パートナー連携で使うように書いています。- 動画の生成IDは期限切れにならず、あとの編集・延長・リフレームに使えます(動画生成のページ)。
1-2. 最小の呼び出し(この記事で組んだ例。動作は確かめていません)
curl -X POST https://agents.lumalabs.ai/v1/generations \
-H "Authorization: Bearer $LUMA_AGENTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A glass of iced coffee on a marble countertop, morning light streaming through a window",
"aspect_ratio": "16:9",
"model": "uni-1"
}'
- プロンプトと比率、モデルの指定は、公式のPython SDKのREADMEの例と同じ組み合わせです。
typeは省略するとimageです(画像生成のページ)。
1-3. 状態を聞いて取り出す(この記事で組んだ例。動作は確かめていません)
Python SDK のREADMEから取得できた範囲には、依頼(client.generations.create)の例しかなく、状態を聞く呼び出しの名前は出ていませんでした。次は、公式のREST(HTTP)の形に合わせて、requests で組んだ例です。
import os
import time
import requests
BASE = "https://agents.lumalabs.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['LUMA_AGENTS_API_KEY']}"}
def wait_for(generation_id, first_wait=20, interval=2, deadline=120):
time.sleep(first_wait)
start = time.time()
while time.time() - start < deadline:
r = requests.get(f"{BASE}/generations/{generation_id}", headers=HEADERS)
r.raise_for_status()
body = r.json()
if body["state"] == "completed":
return body["output"]
if body["state"] == "failed":
raise RuntimeError(f'{body["failure_code"]}: {body["failure_reason"]}')
time.sleep(interval)
raise TimeoutError("deadline exceeded")
- 数字(初回の待ち20秒、間隔2秒、上限2分)は、公式のクイックスタートの画像の例に合わせた値です。動画では、次の表のとおり別の数字になります。
1-4. 待ち方の数字:公式のページ同士で違います
| ページ | 初回の待ち | 間隔 | 上限・目安 |
|---|---|---|---|
| クイックスタート(画像) | 約20秒(uni-1は通常約30秒) | 2秒 | 2分で打ち切り |
| クイックスタート(動画) | 30秒 | 書かれていない | 10分 |
| 動画生成のページ | 30秒 | 5秒 | 10分。5秒・720pは通常2分以内、10秒・1080pのHDRは数倍かかることがある |
| レート制限のページ | 書かれていない | 1〜5秒(2〜5秒が recommended) | 状態の確認は、生成の分あたり上限の対象外 |
| エラーのページ | 書かれていない | 2〜5秒 | 完了を決めつけない |
| FAQ | 書かれていない | 2〜3秒 | 約2分。画像は通常30〜60秒、動画はより長い |
- どれかに決めつけず、並べました。コードに入れる前に、それぞれのページを見直してください。
2. 画像(uni-1、uni-1-max)
2-1. 画像の生成:type: "image"(画像生成のページ)
| パラメータ | 内容 |
|---|---|
prompt |
必須。1〜6,000字 |
model |
uni-1(既定)、uni-1-max(高品質、1枚の単価も高い) |
aspect_ratio |
3:1、2:1、16:9、3:2、1:1、2:3、9:16、1:2、1:3。省略するとモデルが選ぶ |
style |
auto(既定)、manga。manga は縦長の比率(2:3、9:16、1:2、1:3)か、比率の省略だけ。ほかは422 |
output_format |
png(可逆)、jpeg。省略するとモデルが選ぶ |
web_search |
true/false(既定false)。FAQは、ウェブの画像で結果を支え、少し遅くなる、と書く |
image_ref |
参照画像、最大9。スタイルや内容の手がかりで、元のピクセルは保たない |
source |
image のときは指定しない |
- 参照画像・素材の渡し方は、次のうちちょうど1つです。
url(公開URL)、data(base64。media_typeが必須)、file_id(ファイルAPI、09の5)。1枚50 MB、1辺8,000 pxまで。埋め込みのdataは、小さいファイルだけにするように書かれています。 - 1回の依頼で、画像は1枚です(FAQ)。出力のピクセル寸法は、画像生成のページに書かれていません。
- FAQは、ネガティブプロンプトの指定、公開のシード、依頼の取り消しの入口はない、と書いています。英語に最適化され、描き込む文字は引用符で囲む、とあります。
2-2. 画像の編集:type: "image_edit"(画像編集のページ)
| パラメータ | 内容 |
|---|---|
source |
必須。url、data+media_type、generation_id(同じクライアントの完了した画像生成のID)、file_id(ready 状態のもの)のうち1つ |
prompt |
必須。1〜6,000字。変える点と、残す点を具体的に |
image_ref |
最大8。複数のときは、各参照の役割をプロンプトに書く |
aspect_ratio |
無視される。出力の寸法は元の画像から決まる |
style |
manga など。縦長だけの制約は編集には当てはまらない |
この記事で組んだ例(動作は確かめていません)
curl -X POST https://agents.lumalabs.ai/v1/generations \
-H "Authorization: Bearer $LUMA_AGENTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "image_edit",
"prompt": "Change the sky to a dramatic sunset",
"source": { "url": "https://example.com/photo.jpg" }
}'
- マスクの指定はなく、編集はプロンプトで行います(FAQ)。複雑な編集は、順番に分けて行うほうが、結果が読みやすくなる、と画像編集のページに書かれています。
- 画像編集のページのエラー:400(
sourceがない、urlとdataの両方)、413(50 MB超)、422(URLに届かない、base64の不正)。
2-3. レイヤー分け:type: "layering"(画像のレイヤーのページ)
- 既存の画像を、最大10枚の透過PNG(RGBA)のレイヤーに分けます。最後のレイヤーは不透明な背景です。画像を変える機能ではなく、分ける機能です。
modelはuni-1か省略。uni-1-maxは拒否されます。promptは空でもよく、500字まで。sourceは必須。layering.resolutionは1k(既定)か2k。image_ref、web_search、videoは拒否されます。
公式の例(Python、取得ページ上の表示の写し。layering.resolution の指定は、この例には入っていません。上の表のとおり、省略すると 1k です)
generation = client.generations.create(
type="layering",
model="uni-1",
prompt="separate the subject from the background",
source={"url": "https://example.com/product-shot.jpg"},
)
- 出力は前から後ろの順で、各レイヤーに
layer(index、label、description、alpha_hint、bounds、contains_textとtext)が付きます。位置はboundsで、元の大きさに戻すには、canvas_widthと元の幅の比を掛ける、と書かれています。 - 1つでも失敗すると全体が失敗し、課金されません。料金は、公式の料金のページに載っておらず、導入期の値で、大量に使う前に support に確認するよう、そのページに書かれています。
3. 動画(ray-3.2)
3-1. 動画の生成:type: "video"(動画生成のページ)
| パラメータ | 内容 |
|---|---|
model |
ray-3.2(必須) |
prompt |
必須。1〜6,000字 |
aspect_ratio |
9:16、3:4、1:1、4:3、16:9、21:9。省略するとモデルが選ぶ |
video.resolution |
360p(SDRのみ)、540p(HDRと併用不可)、720p(既定)、1080p |
video.duration |
5s(既定)、10s |
video.loop |
生成のみ。10s、hdr、end_frame、keyframes とは併用不可。前向きの延長だけ |
video.hdr |
720p か 1080p が必要。10s と loop とは併用不可 |
video.exr_export |
hdr: true が必要。色空間は AP0(ACES2065-1) |
video.start_frame/end_frame |
最初・最後のフレームの手がかり。10s とは併用不可。keyframes とは排他 |
video.keyframes/keyframe_indexes |
1〜64枚の手がかり。2つは必ず対で。5s は0〜120、10s は0〜240 |
- 画像参照(ImageRef)の形:
url、data+media_type、file_id、generation_idのうち1つ。urlとdataは50 MB・1辺8,000 pxまで。 - 動画の音声については、動画生成のページに記述がありません。
- Models ページは、解像度を「540p、720p、1080p」と書き、動画生成のページには
360pもあります。併記します。
公式の例(JSONの本体。取得ページ上の表示の写し)
{
"model": "ray-3.2",
"type": "video",
"prompt": "A slow dolly shot through a misty greenhouse at sunrise",
"aspect_ratio": "16:9",
"video": { "resolution": "720p", "duration": "5s" }
}
- 送り方は、1-2の curl の
-dに、この本体を入れる形です(この記事の補い。動作は確かめていません)。公式の動画生成のページは、依頼の curl の URL の行が取得結果に出ていませんでした。 - 延長:
video.start_frame: { "generation_id": "<id>" }で前向き、video.end_frameで後ろ向きに延長します。延長は標準の明るさ範囲(SDR)のみで、hdrとexr_exportは拒否されます。 - 出力は MP4 で、署名つきURLの期限は1時間です。
3-2. 動画の編集:type: "video_edit"(動画編集のページ)
| パラメータ | 内容 |
|---|---|
source |
必須。generation_id、url(+media_type、200 MBまで)、data(200 MBまで)、file_id のうち1つ |
prompt |
必須。1〜6,000字 |
video.resolution |
360p〜1080p、既定720p |
video.edit.strength |
9段階。adhere_1〜3(元の動き・構図を保つ)、flex_1〜3、reimagine_1〜3(プロンプト主導)。数字が大きいほど強い |
video.edit.auto_controls |
公式が「recommended default」と書く。controls とは併用不可 |
video.edit.controls |
pose、depth、normals、trajectory、face の信号ごとの設定 |
video.edit.keyframes/keyframe_indexes |
最大64枚。対で指定 |
- 元の動画は18秒以下。
aspect_ratioは無視され、出力は元に合わせます。image_ref、loop、end_frameは拒否されます。 - 動画編集のページの例は、次の本体を持つ curl です(取得ページでは URL の行が見えなかったため、1-2の形にこの記事で補っています。リフレームの節も同じです)。
公式の例(本体の写し)
{
"model": "ray-3.2",
"type": "video_edit",
"prompt": "Transform the scene into moonlit 35mm film footage",
"source": { "generation_id": "d290f1ee-6c54-4b01-90e6-d701748f0851" },
"video": {
"resolution": "720p",
"edit": { "auto_controls": true }
}
}
3-3. 縦横比の変更:type: "video_reframe"(リフレームのページ)
| パラメータ | 内容 |
|---|---|
aspect_ratio |
必須。9:16、3:4、1:1、4:3、16:9、21:9 |
prompt |
必須。新しく増える領域を、どう埋めるか |
source |
必須。編集と同じ形 |
video.duration |
5s(既定)か 10s |
video.resolution |
360p〜1080p、既定720p。縦長(9:16、3:4)では1080pは使えない |
video.source_position |
出力の枠の中の元の位置。x_norm、y_norm(−2.0〜2.0)、w_norm、h_norm(0超〜2.0)。省略すると中央に収める |
- 元の動画は10秒以下で、出力も10秒が上限です。標準の明るさ範囲のみ。
video.hdr、exr_export、loop、edit、start_frame、end_frameは拒否されます。
公式の例(本体の写し)
{
"model": "ray-3.2",
"type": "video_reframe",
"prompt": "Extend the scene into cinematic widescreen",
"aspect_ratio": "21:9",
"source": { "generation_id": "d290f1ee-6c54-4b01-90e6-d701748f0851" },
"video": { "resolution": "720p" }
}
3-4. 元の動画の長さ:ページ同士で違います
| 資料 | 書かれていること |
|---|---|
| 動画編集のページ | 元の動画は18秒以下 |
| リフレームのページ | 元の動画は10秒以下 |
| FAQ | リフレーム10秒、編集18秒、延長30秒。ファイルは200 MBまで |
| エラーのページ | 413:埋め込みの元の動画が30秒超 |
| 元の動画の大きさ | FAQ、動画編集、リフレームのページは200 MBまで。エラーのページは、入力の画像・動画(埋め込みの動画を含む)は1つ50 MBが上限、と書く |
4. 公式のPython SDKの使い方(READMEの記載)
| 項目 | 内容 |
|---|---|
| クライアント | from luma_agents import Luma。非同期は AsyncLuma(await で使う)。aiohttpを使うときは、http_client=DefaultAioHttpClient() |
| 認証 | auth_token(省略すると環境変数 LUMA_AGENTS_API_KEY) |
| 型 | 入れ子のパラメータは TypedDict、応答は Pydantic のモデル(to_json()、to_dict()) |
| エラー | 接続の失敗は APIConnectionError。4xx/5xxは APIStatusError(status_code、response)。すべて APIError を継ぐ |
| 再試行 | 既定で2回、短い指数的な間隔。接続エラー、408、409、429、500番台が対象。max_retries で変更 |
| タイムアウト | 既定1分。timeout で変更。タイムアウトは APITimeoutError で、既定で2回再試行 |
| 生の応答 | .with_raw_response. で、ヘッダーを読める |
| 未対応の入口 | client.get、client.post などで、cast_to= を付けて呼べる |
| 後始末 | .close()、または with Luma() as client: |
| HTTP | SDKのエラー型 |
|---|---|
| 400 | BadRequestError |
| 401 | AuthenticationError |
| 403 | PermissionDeniedError |
| 404 | NotFoundError |
| 422 | UnprocessableEntityError |
| 429 | RateLimitError |
| 500以上 | InternalServerError |
- READMEの取得結果に、ファイルのアップロード、ポーリングの補助、ページ送りの記述は出ていませんでした。ファイルAPIのPython版(09の5)は、ファイルのページに
client.files.create(file=..., purpose=...)とclient.files.list(cursor=...)として出ています。 - バージョンは SemVer に従う、と書かれています。
気をつけること
- この記事は、実際に使って確かめた記録ではありません。公式のドキュメントとGitHubを読んだ範囲です。
- 読めなかったページ。 開発者ダッシュボード(platform.lumalabs.ai)は、取得を拒まれて読めませんでした。キーの作成・失効・自動チャージ・上限の確認の画面は、FAQの記述の範囲です。TypeScript版SDKとCLIの導入コマンドは、取得結果に出ていませんでした。
- ページ同士の食い違い。 ポーリングの数字(1-4)、元の動画の長さと大きさ(3-4)、動画の解像度(360pの有無)。どれかに決めていません。動画編集とリフレームのページは、ソースの節に
file_idが書かれ、検証の表にはない、という違いもあります。 - 取得要約の限界。 コード・コマンドは、取得した要約で行が欠けて見えた所があります(動画生成、動画編集、リフレーム、画像編集のcurl)。URLの行は、この記事で補いました。実行の前に、公式ページの原文と見比べてください。
- Luma Agents APIの資料に、ベータや実験的という表示は、読んだ範囲では見つかりませんでした。
- 公式の記事の数字や評価は、会社自身の説明です。独立した検証は、読んだ範囲では見つかっていません。
- 今回取得した公式ページの要約に、AIアシスタントへの指示のような文は見つかりませんでした。
- 契約や規約の解釈は、必要なら公式や専門家に確認してください。この記事は法律の助言ではありません。
出典
- Quickstart(Luma Agents API、Luma AI、確認日 2026-10-25)
- Models(Luma Agents API、Luma AI、確認日 2026-10-25)
- Image generation(Luma Agents API、Luma AI、確認日 2026-10-25)
- Image editing(Luma Agents API、Luma AI、確認日 2026-10-25)
- Image layering(Luma Agents API、Luma AI、確認日 2026-10-25)
- Video generation(Luma Agents API、Luma AI、確認日 2026-10-25)
- Video editing(Luma Agents API、Luma AI、確認日 2026-10-25)
- Video reframing(Luma Agents API、Luma AI、確認日 2026-10-25)
- Rate limits and headers(Luma Agents API、Luma AI、確認日 2026-10-25)
- Error handling(Luma Agents API、Luma AI、確認日 2026-10-25)
- FAQ(Luma Agents API、Luma AI、確認日 2026-10-25)
- luma-agents-python(Luma AI の公式GitHub、確認日 2026-10-25)