文件
影像生成
兩種端點:文字生成圖像,以及圖像編輯/圖像轉圖像。兩者都會傳回永久有效的結果 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)常用參數
| 參數 | 類型 | 備註 |
|---|---|---|
model | string | 可使用 /v1/models 中任何圖像模型的 slug。 |
prompt | string | 文字提示。必填。 |
size | string | OpenAI 格式的「1024x1024」。會對應至上游的長寬比。 |
quality | standard|hd | 支援的模型(gpt-image)。 |
resolution | 1K|2K|4K | 分層模型的解析度級別 — 請參閱下方的 Resolution tiers。依級別計費。 |
n | int | 圖像數量。大多數模型無論指定多少都只會傳回 1 張。 |
input | object | 緊急替代方案 — 請參閱下方的 Raw input。 |
files.kunavo.com 連結:Kunavo 會將每張圖像封存至自己的 CDN,因此不同於原始上游 URL,這些連結永不過期。若某張圖像未能封存,它的 URL 就是上游的暫時性 URL,位於其他網域:請下載該圖像並重新託管。解析度級距
部分圖像模型會依輸出解析度採用分級計價。傳入 resolution 可選擇級距;若省略,則使用預設級距。實際費用依生成結果所屬的級距計算。
| 模型(及其 -edit 變體) | 級距 — 各級價格 | 預設值 |
|---|---|---|
| nano-banana-2 | 1K $0.0469 · 2K $0.0707 · 4K $0.1057 | 1K |
| nano-banana-pro | 1K / 2K $0.067 · 4K $0.12 | 2K |
| gpt-image-2 | 1K / 2K / 4K — $0.0633(固定) | 1K |
veo-3 系列也依解析度分級計價——各級價格請參閱每個模型的 /models 頁面。
resolution = 4K,呼叫會自動降至 2K,並按 2K 費率計費。圖像編輯/圖像轉圖像
端點:POST /v1/images/edits。單張圖像編輯時,透過 image 傳入 HTTPS URL 或 data: base64 格式的來源圖像;多張參考圖像則使用 image_urls。
# 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 圖像轉圖像
提供來源圖像
圖像編輯和圖像轉影片都需要可供模型擷取的來源圖像。你有三種選擇,可依照應用程式需求挑選:
- 你已有公開 URL — 直接將它作為
image傳入(影片則使用image_url)。完成。 - 你有本機檔案 — 透過
POST /v1/files上傳一次,之後重複使用傳回的永久 URL。 - 程式碼中已有原始位元組 — 將它們內嵌為
data:base64 URI;Kunavo 會自動代為託管。
選項 A — 透過 POST /v1/files 上傳
使用 multipart/form-data 傳送含有 file 欄位的請求(或使用 JSON { "file": "data:..." })。你會取得永久 files.kunavo.com URL——檔案大小上限為 25 MB。
# 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
完全略過個別上傳步驟:將 data: URI 放入 image/image_url 欄位。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 標準的 images 回應:
{
"created": 1779360636,
"data": [
{ "url": "https://files.kunavo.com/image/.../result.png" }
]
}延遲與逾時
圖像生成通常需要 5–60 秒,視模型而定。在預設同步模式中,Kunavo 會保持連線並輪詢上游,最長等待 540 seconds,之後傳回 504。請相應設定用戶端逾時時間,或使用 非同步 API,在幾秒內提交工作,並依照自己的排程輪詢:
- Nano Banana/Nano Banana 2:通常不到 10 秒。
- Nano Banana Pro/GPT-Image-2:15–60 秒。
- 多張參考圖像 + 進階級距:最長約 2 分鐘。
非同步 API(提交 + 輪詢/Webhook)
兩種圖像端點預設皆為同步——呼叫會保持連線,直到上游完成生成,然後傳回標準的 OpenAI images 回應。批次工作、速度較慢的高級級距,或無法維持長時間請求的無伺服器用戶端,可在 /v1/images/generations 或 /v1/images/edits 加上 "async": true(或 webhook_url)。
提交後會立即傳回 img_* ID;你可以輪詢 GET /v1/images/{id},直到 status 變為 completed 或 failed,也可以註冊 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"])任務物件
| 欄位 | 類型 | 備註 |
|---|---|---|
id | string | img_* 任務 ID — 傳給 GET /v1/ |
status | string | queued | in_progress | completed | failed。 |
output | object|null | 完成時:{ url, urls, archived }。若某張圖像未能封存,其 URL 就是上游的暫時性 URL,此時 archived 為 false。 |
error | object|null | 失敗時:{ code, message }。 |
expires_at | int|null | 提交後滿 30 天時的 Unix 秒數:至少在此之前都可以輪詢該任務。其結果 URL 不會過期。 |
GET /v1/images/{id} 依擁有者隔離:查詢不屬於你的 ID 時會傳回 404,且無法與從未建立過的 ID 區分。建議每 3 秒輪詢一次,並採用指數退避,最長約 30 秒。Webhook
提交時傳入 webhook_url(https),任務結束時 Kunavo 會 POST 簽署的 image.completed/image.failed 事件——信封格式和簽章與影片和音樂 Webhook 相同:
X-Kunavo-Webhook-Id— 穩定的事件 ID,重試時不變(可用於去重)。X-Kunavo-Webhook-Timestamp— 簽章計算時的 Unix 秒數。X-Kunavo-Webhook-Signature— 對{timestamp}.{rawBody}計算的sha256=HMAC-SHA256,以你的 Webhook 密鑰為金鑰。
原始輸入的替代方式
若需使用 Kunavo 未對應的模型專屬參數(seed、負面提示詞、輸出格式),請傳入 input。它會原樣傳送至上游,取代我們的轉接器原本會建立的輸入。
用來選擇模型價格級距的欄位是例外: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 的驗證。如果上游拒絕你的欄位,我們會傳回 422——請參閱錯誤說明文件和模型的上游說明文件。