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日に読んでまとめたものです。この記事は、実際に使って確かめた記録ではありません。手順は「公式の手順を順に並べたもの」で、コード・コマンドは、公式の例を写したものと、この記事で組んだ例(動作は確かめていません)を、そのつど区別して書きます。取得した要約でコマンドの行が欠けて見えた所は、この記事で補ったと明記します。実行の前に、公式ページの原文と見比べてください。

先に結論

前提:用語をそろえる

1. 基本の流れ:依頼、状態の確認、取り出し

1-1. 公式のクイックスタートの順

  1. 依頼: POST https://agents.lumalabs.ai/v1/generations。認証は、Authorization: Bearer に、環境変数 LUMA_AGENTS_API_KEY のキーを入れる(05)。
  2. 状態: GET https://agents.lumalabs.ai/v1/generations/{generation_id} を、completed か failed になるまで繰り返す。
  3. 取り出し: completed なら、output[0].url(動画も同じ形)の署名つきURLからダウンロードする。

  4. 受け付けられると HTTP 201 で、状態は queued です。状態は queued、processing、completed、failed です。

  5. 応答の output は配列で、各要素に type と署名つきの url が入ります。failed のときは failure_reason と failure_code が付き、output は空です。
  6. user_id(任意):エンドユーザーを示す、個人情報を含まない固定のID(256字まで)を渡せます。クイックスタートは、パートナー連携で使うように書いています。
  7. 動画の生成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"
  }'

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")

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 のときは指定しない

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" }
  }'

2-3. レイヤー分け:type: "layering"(画像のレイヤーのページ)

公式の例(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"},
)

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

公式の例(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" }
}

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枚。対で指定

公式の例(本体の写し)

{
  "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)。省略すると中央に収める

公式の例(本体の写し)

{
  "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

気をつけること

出典