媒體 API
POST
/omni/media/v1/images/generations/tasks圖像生成
圖像生成分兩個步驟:先建立任務(回 202 + task id),再輪詢到終態、下載簽章 URL。把 client 指向媒體 base URL https://api.atptoken.ai/omni/media/v1,用專案 atp- key 驗證。gateway 會把你的 unified model 路由到圖像 provider(例如 gpt-image-2);名稱用 GET /v1/models 確認。流程與影片生成一致。
- 輸出寫入物件儲存、以帶簽章的邊緣 URL(
https://media-<env>.atptoken.ai/v/...)回傳,TTL 30 分鐘——不會內嵌 base64。請盡快取用。 - 當 project 餘額 ≤ 0,請求會以
402 insufficient_quota拒絕。
先用同一把 key 確認模型
媒體模型依環境與 project 開放。請先呼叫 GET https://api.atptoken.ai/v1/models;未出現在回應中的模型,代表這把 key 目前不能使用。
建立任務
curl https://api.atptoken.ai/omni/media/v1/images/generations/tasks \
-H "Authorization: Bearer atp-..." -H "Content-Type: application/json" \
-H "Idempotency-Key: img-job-001" \
-d '{ "model": "gpt-image-2", "prompt": "a watercolor cat", "size": "1024x1024", "quality": "high", "n": 1 }'
# → 202 { "id": "img_..." }| Field | Type | Description |
|---|---|---|
| model | string · 必填 | unified 圖像模型(`image` 池) |
| prompt | string · 必填 | 文字提示 |
| size | string | 依模型而異;OpenAI 圖像常用 `1024x1024` |
| quality | string | 轉發給 OpenAI 方言上游(如 `high`/`medium`) |
| n | integer | 張數 1–4(預設 `1`) |
網路失敗重試建立時沿用同一個 Idempotency-Key;真正的新任務用新 key。
輪詢至終態
每 3–8 秒輪詢一次:
curl https://api.atptoken.ai/omni/media/v1/images/generations/tasks/img_... \
-H "Authorization: Bearer atp-..."
# → { "status": "succeeded", "data": [ { "url": "https://media-prod.atptoken.ai/v/image/...png?exp=...&sig=..." } ], "usage": { "prompt_tokens": 37, "completion_tokens": 7024, "total_tokens": 7061 } }status流轉:queued→running→succeeded/failed/cancelled/expired。- 成功任務的
data[].url是 30 分鐘時效的簽章 URL;過期後任務仍顯示succeeded但expired: true、url為 null——請立即下載(要重拿只能重新生成)。 usage回報 token 用量供帳務核對;failed任務帶結構化error物件。
| Method | Path | 動作 |
|---|---|---|
| POST | /omni/media/v1/images/generations/tasks | 建立 |
| GET | /omni/media/v1/images/generations/tasks/{id} | 輪詢 |
| GET | /omni/media/v1/images/generations/tasks | 列表 |
| DELETE | /omni/media/v1/images/generations/tasks/{id} | 取消 |
Python 範例
最小的建立+輪詢流程:
import os, time, requests
BASE = "https://api.atptoken.ai/omni/media/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['ATP_API_KEY']}",
"Content-Type": "application/json",
}
resp = requests.post(
f"{BASE}/images/generations/tasks",
headers={**HEADERS, "Idempotency-Key": "img-job-001"},
json={
"model": "gpt-image-2",
"prompt": "a watercolor cat",
"size": "1024x1024",
"quality": "high",
"n": 1,
},
timeout=60,
)
resp.raise_for_status()
task_id = resp.json()["id"]
while True:
task = requests.get(
f"{BASE}/images/generations/tasks/{task_id}", headers=HEADERS, timeout=60
).json()
if task["status"] in ("succeeded", "failed", "cancelled", "expired"):
break
time.sleep(5)
if task["status"] == "succeeded":
for i, item in enumerate(task["data"]):
image = requests.get(item["url"], timeout=120).content # signed URL, 30-min TTL
with open(f"result_{i}.png", "wb") as f:
f.write(image)
else:
raise RuntimeError(task.get("error"))錯誤
400
缺 `model` 或 `prompt`。
402
`insufficient_quota`:project 餘額 ≤ 0;儲值後再送(不要重試轟炸)。
404
任務不存在或不屬於此 project(輪詢時)。
422
該模型沒有圖像 provider。
502
上游生成失敗。