ドキュメント

ドキュメント

画像生成

テキストから画像を生成するエンドポイントと、画像を編集する / 画像から画像を生成するエンドポイントがあります。どちらも永続的な結果 URL を返します。Kunavo はすべての画像を独自の CDN にアーカイブします。

Kunavo は /v1/images/generations(テキストから画像を生成)と /v1/images/edits(画像から画像を生成 / 編集)を提供します。どちらもデフォルトでは同期処理で、上流処理が完了するまで呼び出しを待機させた後、結果 URL を返します。または、"async": true か webhook_url を使って 非同期 で実行できます。

テキストから画像を生成

エンドポイント:POST /v1/images/generations。OpenAI SDK の images.generate メソッドを使用するか、curl で直接呼び出してください。

img = client.images.generate(
    model="nano-banana-pro",
    prompt="a red origami crane on a white desk, soft window light",
    size="1024x1024",
)
print(img.data[0].url)

一般的なパラメーター

パラメーター種類注記
modelstring/v1/models にある任意の画像モデルのスラッグ。
promptstringテキストプロンプト。必須です。
sizestringOpenAI 形式の「1024x1024」。上流のアスペクト比に変換されます。
qualitystandard|hd対応している場合(gpt-image)。
resolution1K|2K|4Kティア制モデルの解像度ティア — 下記のResolution tiersを参照。ティアに基づいて課金されます。
nint画像の数。ほとんどのモデルは、指定にかかわらず 1 枚を返します。
inputobject代替手段 — 下記のRaw inputを参照。
結果URLは永続的なfiles.kunavo.comリンクです。Kunavoがすべての画像を独自CDNにアーカイブするため、これらのURLは上流から直接返されるURLと異なり、期限切れになりません。画像をアーカイブできなかった場合、そのURLは別のホストにある上流の一時的なURLです。その画像はダウンロードして再ホストしてください。

解像度の段階

複数の画像モデルでは、出力解像度に応じて段階的な料金が設定されています。resolution を渡して段階を指定できます。省略すると既定の段階が使われます。請求は実際に生成された段階に基づきます。

モデル(およびその -edit バリアント)段階 — 各段階の料金デフォルト
nano-banana-21K $0.0469 · 2K $0.0707 · 4K $0.10571K
nano-banana-pro1K / 2K $0.067 · 4K $0.122K
gpt-image-21K / 2K / 4K — $0.0633(一律)1K

veo-3 ファミリーも解像度に応じて段階的に料金が設定されています。段階ごとの料金は、各モデルの /models ページをご覧ください。

GPT-Image-2 は、アスペクト比 1:1(正方形)では 4K を生成できません。正方形サイズで resolution = 4K を指定すると、呼び出しは自動的に 2K に下げられ、2K の料金が請求されます。

画像編集 / 画像から画像を生成

エンドポイント:POST /v1/images/edits。単一画像の編集では image、複数画像の参照では image_urls を使い、ソース画像を URL(HTTPS または data: base64)として渡します。

# Image edit / image-to-image: pass the source image URL
import requests

resp = requests.post(
    "https://api.kunavo.com/v1/images/edits",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "gpt-image-2-edit",
        "prompt": "recolor the crane to bright blue, keep composition",
        "image": "https://your-cdn.com/source.png",
    },
)
print(resp.json()["data"][0]["url"])

複数画像の参照

一部のモデル(Nano Banana Edit、GPT-Image-2 Edit)は、複数の参照画像に対応しています。

# nano-banana-edit accepts multiple reference images
resp = requests.post(
    "https://api.kunavo.com/v1/images/edits",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "nano-banana-edit",
        "prompt": "merge subject from img1 with background from img2",
        "image_urls": [
            "https://your-cdn.com/subject.png",
            "https://your-cdn.com/background.png",
        ],
    },
)

対応する編集モデル

  • nano-banana-edit — Google Nano Banana 編集モデル
  • gpt-image-2-edit — OpenAI の画像から画像を生成するモデル

ソース画像の指定方法

画像編集と画像から動画を生成する処理では、モデルが取得できるソース画像が必要です。アプリに合った方法を 3 つから選べます。

  • 公開 URL がすでにある — そのまま image(動画の場合は image_url)として渡せば完了です。
  • ローカルファイルがある — POST /v1/files で一度アップロードし、返された永続 URL を再利用します。
  • コード内に生のバイト列がある — data: base64 URI としてインラインで指定します。Kunavo が透過的にホストします。

方法 A — POST /v1/files でアップロード

multipart/form-data を file フィールド(または JSON の { "file": "data:..." })とともに送信します。最大 25 MB のファイルについて、永続的な files.kunavo.com URL が返されます。

# Upload a local file → get a permanent Kunavo URL
import requests

with open("source.png", "rb") as f:
    up = requests.post(
        "https://api.kunavo.com/v1/files",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files={"file": f},
    ).json()

# up["url"] is now a permanent https://files.kunavo.com/... URL
edit = requests.post(
    "https://api.kunavo.com/v1/images/edits",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "gpt-image-2-edit",
        "prompt": "recolor the crane to bright blue",
        "image": up["url"],
    },
).json()
print(edit["data"][0]["url"])

方法 B — base64 をインラインで指定

別途アップロードする必要はありません。image / image_url フィールドに data: URI を指定します。Kunavo がデコードして CDN でホストし、ホスト済み URL をモデルに渡します。

# Or skip the upload step — pass base64 inline, we host it for you.
import base64, requests

with open("source.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

resp = requests.post(
    "https://api.kunavo.com/v1/images/edits",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "gpt-image-2-edit",
        "prompt": "recolor the crane to bright blue",
        "image": f"data:image/png;base64,{b64}",
    },
)
同じ方法は POST /v1/video/generations にも適用されます。Veo などの画像から動画を生成するモデルでは、image_url に https URL または data: base64 URI を指定できます。

レスポンスの形式

どちらのエンドポイントも、OpenAI 標準の画像レスポンスを返します。

{
  "created": 1779360636,
  "data": [
    { "url": "https://files.kunavo.com/image/.../result.png" }
  ]
}

レイテンシとタイムアウト

画像生成には、モデルに応じて通常 5–60 秒かかります。デフォルトの同期モードでは、Kunavo は接続を維持し、上流を最大 540 秒間ポーリングしてから 504 を返します。クライアント側のタイムアウトを適切に設定してください。または、非同期 API を使うと数秒で送信し、任意のタイミングでポーリングできます。

  • Nano Banana / Nano Banana 2:通常 10 秒未満。
  • Nano Banana Pro / GPT-Image-2:15–60 秒。
  • 複数画像の参照 + プレミアム段階:最大約 2 分。

非同期 API(送信 + ポーリング / webhook)

どちらの画像エンドポイントも、デフォルトでは同期処理で、上流が画像を生成するまで接続を維持し、その後 OpenAI 標準の画像レスポンスを返します。バッチ処理、時間のかかるプレミアム段階、長時間リクエストを維持できないサーバーレス呼び出し元では、/v1/images/generations または /v1/images/edits に "async": true(または webhook_url)を追加してください。

送信するとすぐに img_* ID が返されます。status が completed または failed になるまで GET /v1/images/{id} をポーリングしてください。または、webhook を登録すればポーリングを省略できます。

# Async: add "async": true (or a webhook_url) to either image endpoint.
# The call returns instantly with an img_ id instead of holding the connection.
import requests, time

API = "https://api.kunavo.com/v1"
H = {"Authorization": f"Bearer {API_KEY}"}

submit = requests.post(
    f"{API}/images/generations",
    headers=H,
    json={"model": "gpt-image-2", "prompt": "a red panda", "async": True},
).json()

task_id = submit["id"]        # "img_abc..."
status  = submit["status"]    # "queued"

# Poll GET /v1/images/{id} until terminal — or skip polling and use a webhook.
while status not in ("completed", "failed"):
    time.sleep(3)
    r = requests.get(f"{API}/images/{task_id}", headers=H).json()
    status = r["status"]

if status == "completed":
    print(r["output"]["url"])
else:
    print("failed:", r["error"])

タスクオブジェクト

フィールド種類注記
idstringimg_* タスクID — GET /v1/images/{id} に渡します。
statusstringqueued | in_progress | completed | failed。
outputobject|null完了時: { url, urls, archived }。画像をアーカイブできず、その URL が上流の一時的な URL である場合、archived は false になります。
errorobject|null失敗時: { code, message }。
expires_atint|nullUnix秒。送信から30日後の時刻で、少なくともそれまではタスクをポーリングできます。結果のURLに有効期限はありません。
GET /v1/images/{id} は所有者ごとに分離されています。自分が所有していない ID を問い合わせると、発行されなかった ID と区別できない 404 が返されます。推奨されるポーリング間隔は 3 秒で、指数バックオフにより最大約 30 秒まで延ばします。

Webhook

送信時に webhook_url(https)を指定すると、タスク終了時に Kunavo が署名付きの image.completed / image.failed イベントを POST します。動画や音楽の webhook と同じエンベロープと署名形式です。

  • X-Kunavo-Webhook-Id — 安定したイベント ID。再試行しても同じ ID が使われます(重複排除に使用してください)。
  • X-Kunavo-Webhook-Timestamp — 署名の計算時刻を表す Unix 秒。
  • X-Kunavo-Webhook-Signature — {timestamp}.{rawBody} に対する sha256= HMAC-SHA256。署名には webhook シークレットを使用します。
約 9 時間にわたり、バックオフを挟んで配信を再試行します。非同期の行はその間もポーリング可能なため、webhook を受信し損ねても GET でいつでも復旧できます。

生入力の直接指定

Kunavo がマッピングしていないモデル固有のパラメーター(seed、ネガティブプロンプト、出力形式)を使うには、input を渡してください。その内容は、Kunavo のアダプターが本来構築する入力の代わりに、記述どおりに上流へ送信されます。

モデルの料金段階を選択するフィールドは例外です。resolution、Ideogram では rendering_speed です。段階があるモデルでは、このフィールドは常にそのモデルの段階のいずれかとして送信され、その段階に基づいて課金されます。input でこのフィールドが省略された場合、またはモデルのいずれの段階にも該当しない値が指定された場合は、既定の段階が送信され、その段階に基づいて課金されます。input が設定されている場合、リクエストのトップレベルにある同じフィールドは読み取られません。

# Raw upstream 'input': sent as written, in place of what our adapter builds.
# "resolution" sets the billed tier: 2K here, the default tier when left out.
resp = client.images.generate(
    model="nano-banana-2",
    prompt="",  # ignored when input is set
    extra_body={"input": {
        "prompt": "a futuristic cyberpunk skyline at dusk",
        "aspect_ratio": "16:9",
        "resolution": "2K",
        "output_format": "png",
    }},
)
input を渡すと、Kunavo による検証は行われません。上流がフィールドを拒否した場合は、Kunavo から 422 が返されます。エラーのドキュメントとモデルの上流ドキュメントを確認してください。

次に確認する項目