Seedream 5.0 Pro API:用 Python 生成图片
一个 POST、model 填 Dola-Seedream-5.0-pro 就建好出图任务。下面是能直接抄的请求代码、尺寸和标签的实际表现,以及我们 2026 年 10 月 29 日跑出来的两张图。
本页内容
发一个 POST 到 https://api.omniakey.com/v1/media/tasks,model 填 Dola-Seedream-5.0-pro,operation 填 generate,拿到任务 id 就轮询。状态变成 succeeded,再下载 assets[0].url。默认出图在角落带一个「AI generated」标签。2026 年 10 月 29 日,我们用同一份请求生成一张、改一张。尺寸都写 1024x1024,两个文件量出来都是 1024×1024 PNG。
下面依次是 id 和两种操作、一行没改的请求代码、请求尺寸和文件像素的对照列表、标签和关掉它的设置(这项还没跑过),以及会让建任务失败的两个报错。两张图都是那天我们自己跑出来的。
用哪个模型 id、能做什么
用 Dola-Seedream-5.0-pro,这就是 Seedream 5.0 Pro 模型页(2026 年 10 月 29 日核对)上示例请求里的 id。页面写了两种操作:文生图和改图。生成和改图按同一个价格算,选的尺寸、附带的参考图都不额外收费。当前费率看 价格页。
请求的形状由下面几个字段决定,提示词另放:
model:Dola-Seedream-5.0-prooperation:generate或editparameters.size:1K、1.5K、2K,或widthxheight中间写一个小写xoutput_format:png或jpeg,默认是jpeg
parameters.size 和 output_format 都放在 parameters 里。尺寸最高到 2K,模型页(2026 年 10 月 29 日核对)没有 4K。Seedream 的宽高之间写小写 x,Qwen 和 Wan 写星号,同一个客户端调两家时别弄混。我们两次都写 widthxheight 形式的 1024x1024、用 PNG,1K、1.5K、2K 这三档没跑过。
ByteDance 在 BytePlus ModelArk 上卖同一个模型,id 是 dola-seedream-5-0-pro-260628。那是 BytePlus 的 id,调 OmniaKey 要用上面那个。
请求代码
下面这份脚本就是 2026 年 10 月 29 日跑的那份,一行没改:两个辅助函数,一次生成调用,一次改图调用。只用 Python 标准库,key 从 OMNIAKEY_API_KEY 读,图片写进你运行脚本的文件夹。图片接口文档 写的是同样三步。生成和改图只差两处:源图字段和 operation 的取值,其余字段一样。
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid
API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "Dola-Seedream-5.0-pro"
def request(method, url, body=None, extra_headers=None):
headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
data = None
if body is not None:
headers["Content-Type"] = "application/json"
data = json.dumps(body).encode()
headers.update(extra_headers or {})
req = urllib.request.Request(url, data=data, headers=headers, method=method)
with urllib.request.urlopen(req, timeout=120) as resp:
return json.load(resp)
def poll(url, attempts=5):
for attempt in range(attempts):
try:
return request("GET", url)
except urllib.error.HTTPError as err:
if err.code < 500 or attempt == attempts - 1:
raise
except urllib.error.URLError:
if attempt == attempts - 1:
raise
time.sleep(5 * (attempt + 1))
def run_task(body, out_path):
task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
print("task", task, flush=True)
for _ in range(150):
time.sleep(4)
state = poll(f"{API}/{task}")
if state["status"] not in ("queued", "processing"):
break
if state["status"] != "succeeded":
raise RuntimeError(state.get("error") or state["status"])
asset_url = state["assets"][0]["url"] # signed link: short-lived, so download now
req = urllib.request.Request(asset_url, headers={"User-Agent": "omniakey-example/1"})
with urllib.request.urlopen(req, timeout=120) as resp, open(out_path, "wb") as f:
f.write(resp.read())
return task
def generate_image(prompt, out_path, size="1024x1024"):
body = {
"model": MODEL,
"type": "image",
"operation": "generate",
"input": {"prompt": prompt},
"parameters": {"size": size, "output_format": "png"},
}
return run_task(body, out_path)
def edit_image(source_path, prompt, out_path, size="1024x1024"):
with open(source_path, "rb") as f:
image = base64.b64encode(f.read()).decode()
body = {
"model": MODEL,
"type": "image",
"operation": "edit",
"input": {"prompt": prompt, "image": {"data": image, "mime_type": "image/jpeg"}},
"parameters": {"size": size, "output_format": "png"},
}
return run_task(body, out_path)
if __name__ == "__main__":
task = generate_image(
"A glass bottle of cold-pressed orange juice on a pale stone counter, morning light from the left, "
"a single orange slice beside it, shallow depth of field, no text, no logos.",
"juice-bottle.png",
)
print("generate task", task)
task = edit_image(
"cafe-base.jpg",
"Change the red bicycle to matte black. Keep everything else exactly the same: "
"the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos.",
"cafe-edited.png",
)
print("edit task", task)
三步都在 run_task 里。先用一个新幂等键建任务,轮询到状态离开 queued 和 processing,再下载第一个产物的地址。建任务返回 HTTP 202,id 以 task_ 开头。状态一开始是 queued,文档里一共四种:queued、processing、succeeded、failed(2026 年 10 月 29 日核对)。状态落到 failed 时,脚本把返回里的错误抛出来,原因直接打在终端。
我们跑的尺寸和格式,拿回什么文件
两次请求的尺寸和格式一样,两个文件都是 1024×1024 PNG。
- 生成 — 请求的尺寸:
1024x1024; 文件里的像素: 1024×1024; 格式: PNG; 日期: 2026-10-29 - 改图 — 请求的尺寸:
1024x1024; 文件里的像素: 1024×1024; 格式: PNG; 日期: 2026-10-29
像素要去下载下来的文件里读。尺寸是你请求的,文件才是你拿到的,拿去排版的也是文件里的数字。每个 PNG 我们都打开量了宽高,也对照提示词看过画面。
改图那次更值得看。我们发了一张 1024×683 的咖啡馆照片,加一句要求,返回的是正方形。自行车变成深色,桌子、杯子和绿植都还在画面里;因为输出是正方形,窗户和桌沿的取景跟原图不一样。
Change the red bicycle to matte black. Keep everything else exactly the same: the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos.

「AI generated」标签怎么关掉
按模型页(2026 年 10 月 29 日核对)的说法,每个输出的角落都带「AI generated」标签。要把标签去掉,在 parameters 里把 watermark 设成 false。页面写的位置是右下角,下面这张默认出图的标签就在右下角:很淡、很小。请求里不写 watermark,出来的就是带标签的图。
A glass bottle of cold-pressed orange juice on a pale stone counter, morning light from the left, a single orange slice beside it, shallow depth of field, no text, no logos.
这张就是用默认设置出的图:

水印关掉的那一版我们没跑。博客工具的每次运行花费上限在请求发出之前就拦下了,所以还没有见过不带标签的 Seedream 出图。
报错和限制
建任务能不能过,看两个请求头:Bearer token 和 Idempotency-Key。
| 你发的内容 | 返回什么 |
|---|---|
| 建任务不带幂等键 | 400 missing_idempotency_key |
| 同一个键、同一份 body,再发一次 | 200,返回原任务,不重复扣费 |
| 同一个键、改了 body | 409 idempotency_key_reused |
同一个键配同一份 body 才是安全的重复发送:拿回原来的任务,不会多扣一次费。同一个键改了提示词或尺寸就返回 409,所以每次新请求都换一个新键。键最长 255 个字符(文档,2026 年 10 月 29 日核对)。
请求体控制在 1 MiB 以内,Base64 的图也算在里面,源图大就先压小再发。重试时把原来那份 body 一起带上,幂等键才有意义。任务成功后,返回里的下载地址是签名链接,文档说有效期大约一小时。链接过期后文件不会自己保存下来,所以马上把文件拉下来,或者再轮询一次换新链接。
2026 年 10 月 29 日还有一个请求头让我们意外。用 Python 默认的 urllib User-Agent 发 POST,返回 HTTP 403。返回内容是 Cloudflare 的 error code: 1010。换我们自己的 User-Agent 请求头就到达了接口,也没有扣费。
User-Agent 请求头,例如 omniakey-example/1。2026 年 10 月 29 日 Python 默认的那个就被挡在上面那个 403 上。做 API 该选 Seedream 还是 GPT Image 2.5
看活是什么。这次改图,Seedream 5.0 Pro 改掉的是我们点名的那辆自行车,大部分场景还在,但画面换成了正方形,窗框和桌沿的位置和原图不一样。产品图我们没有测过。请求只是一个 body,operation 填 generate 或 edit。源图可以给公开 URL,也可以内联 Base64(文档,2026 年 10 月 29 日核对)。
想先看同一句提示词下它和 GPT Image 2 的差别?Seedream 5.0 Pro 对比 GPT Image 2 把两边的输出放在一起。想在另一个模型上照同样的「生成加改图」写法走一遍,GPT Image 2.5 API 教程 有它的请求和尺寸。换之前先用你自己最难的那句提示词跑一次,再按费率决定。
FAQ
调接口时 model 该填什么?
填 Dola-Seedream-5.0-pro,这是模型页示例请求里的 id(2026 年 10 月 29 日核对)。ByteDance 自己的 dola-seedream-5-0-pro-260628 属于 BytePlus ModelArk,OmniaKey 要的不是它。
为什么我的图上有「AI generated」标签?
模型页(2026 年 10 月 29 日核对)写着每个输出都带这个标签,除非把 watermark 设成 false。我们 10 月 29 日用默认设置出的那张,标签就在右下角。
接口支持哪些尺寸?
尺寸有 1K、1.5K、2K 三档,也可以写 widthxheight、中间用小写 x(模型页,2026 年 10 月 29 日核对)。最高到 2K,我们两次都要的 1024x1024。
能要 PNG 不要 JPEG 吗?
可以。output_format 填 png 或 jpeg,默认是 JPEG(文档,2026 年 10 月 29 日核对)。我们两次都用 PNG,拿回来的也是 PNG。
能用 Seedream 改已有图片吗?
可以:operation 填 edit,带上提示词和源图,源图可以是内联 Base64 加 mime 类型,也可以是一个公开 URL。上面尺寸那节的咖啡馆改图就是一次完整的例子。
文中提到的模型
相关文章
Seedream 5.0 Pro vs GPT Image 2:同一提示词实测对比与价格
六项任务、同一组提示词,三个模型各自的图和价格。
GPT Image 2.5 API:用 Python 生成和编辑图片
一个 POST 建任务,一个 GET 取结果。下面是能直接抄的请求代码、我们 2026 年 10 月 29 日跑出来的尺寸,和一组改图前后对比。
Kling 3.0 API:文生视频的请求代码和实测片段
一次 POST、模型填 kling-3.0,就是一条文生视频任务。下面是请求代码、请求体里的字段,以及我们 2026 年 10 月 29 日实跑并测量过的两条 5 秒片段。