GPT-6 Sol y Claude Opus 5.5 ya disponiblesGPT-6 Sol por la mitad del precio de 5.6 Sol

Seedream 5.0 Pro API: generar imágenes con Python

Un POST con model Dola-Seedream-5.0-pro crea la tarea de imagen. Aquí tienes el código de la petición, el comportamiento de tamaños y etiqueta que vimos, y las dos imágenes que generamos el 29 de octubre de 2026.

Kiki, OmniaKey COO7 min de lectura
En esta página

Envía un POST a https://api.omniakey.com/v1/media/tasks con model en Dola-Seedream-5.0-pro y la operación generate, y después consulta el id de la tarea hasta que el estado sea succeeded para descargar assets[0].url. Por defecto, la imagen lleva una etiqueta "AI generated" en una esquina. El 29 de octubre de 2026 ejecutamos esa petición y una edición a 1024x1024, y ambos archivos llegaron como PNG de 1024×1024.

A continuación vienen el id y las dos operaciones, el código de la petición tal como lo ejecutamos, una lista con los tamaños que pedimos junto a los píxeles que leímos en cada archivo, la etiqueta, el ajuste que la desactiva (que no se ha ejecutado) y los dos errores que detienen una llamada de creación. Las dos imágenes son las que hicimos ese día.

Qué id de modelo y qué operaciones usar

Usa Dola-Seedream-5.0-pro, el id de la página del modelo Seedream 5.0 Pro (revisada el 29 de octubre de 2026). La página lista dos operaciones: texto a imagen y edición de imagen. También indica que generar y editar comparten una misma tarifa, y que ni el tamaño que eliges ni las imágenes de referencia que adjuntas la aumentan. Las tarifas actuales están en la página de precios.

Estos son los campos que dan forma a una petición, antes de llegar al prompt.

  • model: Dola-Seedream-5.0-pro
  • operation: generate o edit
  • parameters.size: 1K, 1.5K, 2K, o widthxheight con una x
  • output_format: png o jpeg, y jpeg es el valor por defecto

Los campos de tamaño y formato van dentro de parameters. La salida llega hasta 2K: la página del modelo (revisada el 29 de octubre de 2026) no lista ningún tamaño 4K. Seedream usa una x minúscula entre los lados, mientras que Qwen y Wan usan un asterisco, así que conviene no mezclar las dos formas en un cliente que llama a ambos. Nuestras ejecuciones usaron la forma widthxheight con 1024x1024 y PNG, y los tres niveles quedaron fuera.

ByteDance vende el mismo modelo en BytePlus ModelArk con otro id, dola-seedream-5-0-pro-260628. Ese pertenece a BytePlus, así que una petición a OmniaKey necesita el id de arriba.

El código de la petición

El script es el que ejecutamos el 29 de octubre de 2026, sin cambios: dos funciones auxiliares, una llamada de generación, una llamada de edición y solo la biblioteca estándar de Python. Lee tu clave de OMNIAKEY_API_KEY y escribe cada PNG en la carpeta desde la que lo ejecutas. La documentación de la API de imagen describe los mismos tres pasos.

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

Los tres pasos están dentro de run_task: crea la tarea con una clave de idempotencia nueva, consulta la URL de la tarea hasta que el estado salga de queued y processing, y luego descarga la URL del primer asset. La llamada de creación responde HTTP 202 con un id que empieza por task_, y el estado empieza en queued (documentación, revisada el 29 de octubre de 2026). Una tarea que termina en failed lanza el error de la respuesta, así que el motivo aparece en tu terminal.

Los tamaños y formatos que ejecutamos, y qué volvió

Las dos ejecuciones pidieron la misma cadena de tamaño y el mismo formato, y ambos archivos volvieron como PNG de 1024×1024.

  • Generación — Tamaño pedido: 1024x1024; Píxeles del archivo: 1024×1024; Formato: PNG; Fecha: 2026-10-29
  • Edición — Tamaño pedido: 1024x1024; Píxeles del archivo: 1024×1024; Formato: PNG; Fecha: 2026-10-29

Lee el tamaño en píxeles del archivo que descargaste. La cadena de tamaño es lo que pediste; el archivo es lo que obtuviste. Abrimos cada PNG, medimos su ancho y su alto y lo miramos junto al prompt que lo generó.

La edición es la ejecución más interesante. Enviamos un JPEG de 1024×683 de una ventana de café con una sola instrucción, y volvió una imagen cuadrada. La bicicleta ahora es oscura, la mesa, la taza y la planta siguen en la imagen y, como la salida es cuadrada, la ventana y el borde de la mesa quedan encuadrados de otra forma respecto al original.

prompt
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.
Izquierda: una ventana de café con una bicicleta roja fuera. Derecha: la misma ventana tras la edición, con la bicicleta ahora oscura, en un encuadre cuadrado.
Izquierda: la foto original que enviamos, 1024×683. Derecha: la salida de una edición el 29 de octubre de 2026, tamaño 1024x1024. La bicicleta ahora es oscura. La salida es cuadrada, así que la ventana y el borde de la mesa quedan encuadrados de otra forma respecto al original.

La etiqueta, y cómo desactivarla

Según la página del modelo (revisada el 29 de octubre de 2026), toda salida lleva una etiqueta "AI generated" en una esquina a menos que pongas watermark en false en parameters. La página sitúa la etiqueta en la esquina inferior derecha, y ahí está en la salida por defecto de abajo: tenue y pequeña. Si dejas watermark fuera de la petición, obtienes la etiqueta.

prompt
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.

Aquí está esa salida, hecha con los ajustes por defecto.

Una botella de vidrio de zumo de naranja con una rodaja de naranja sobre un mostrador de piedra clara, con una etiqueta AI generated tenue en la esquina.
Generada con Seedream 5.0 Pro a través de la API de OmniaKey el 29 de octubre de 2026, tamaño 1024x1024, ajustes por defecto. La etiqueta tenue 'AI generated' está en la esquina inferior derecha.

El ajuste que pone el watermark en false no se ejecutó: el límite de gasto por ejecución de la herramienta del blog detuvo esa llamada antes de enviarla.

Errores y límites

Dos cabeceras deciden si una llamada de creación pasa: el token bearer y una Idempotency-Key.

Qué envíasQué vuelve
Llamada de creación sin clave de idempotencia400 missing_idempotency_key
La misma clave y el mismo cuerpo, otra vez200 con la tarea existente, sin cargo nuevo
La misma clave con el cuerpo cambiado409 idempotency_key_reused

La misma clave con el mismo cuerpo es el reintento que quieres: vuelve la tarea existente y no se cobra nada nuevo. La misma clave con un prompt o un tamaño editado devuelve 409, así que crea una clave nueva para cada petición. La clave puede tener hasta 255 caracteres (documentación, revisada el 29 de octubre de 2026).

Mantén el cuerpo de la petición por debajo de 1 MiB, con la imagen en Base64 incluida, y reduce una foto de origen grande antes de enviarla. Cuando una tarea termina bien, la URL de descarga de la respuesta es un enlace firmado que dura alrededor de una hora, según la documentación, así que descarga el archivo de inmediato o vuelve a consultar la tarea para obtener un enlace nuevo.

Una cabecera nos sorprendió el 29 de octubre de 2026. Un POST enviado con el User-Agent por defecto de urllib de Python devolvió HTTP 403 con el cuerpo error code: 1010 de Cloudflare. Nuestra propia cabecera User-Agent llegó a la API y no se cobró nada.

Envía una cabecera User-Agent propia, por ejemplo omniakey-example/1. La de Python por defecto recibió el 403 de arriba el 29 de octubre de 2026.

¿Seedream o GPT Image 2.5 para trabajar con la API?

Lo decide el trabajo. En nuestra edición, Seedream 5.0 Pro cambió el único objeto que nombramos, la bicicleta, y mantuvo la mayor parte de la escena, aunque el encuadre cambió. Las fotos de producto no se han probado aquí. La llamada es un cuerpo con operation en generate o edit, y el origen puede ser una URL pública o Base64 en línea (documentación, revisada el 29 de octubre de 2026).

Para ver un resultado con el mismo prompt junto a GPT Image 2, la comparativa de Seedream 5.0 Pro y GPT Image 2 muestra las dos salidas de un mismo prompt. Para la misma forma de generar y editar en otro modelo, el tutorial de la API de GPT Image 2.5 repasa su petición y sus tamaños. Ejecuta tu prompt más difícil en el candidato antes de mover un flujo de trabajo y luego revisa las tarifas.

FAQ

¿Qué id de modelo paso a la API?

Dola-Seedream-5.0-pro, el id de la petición de ejemplo de la página del modelo (revisada el 29 de octubre de 2026). El dola-seedream-5-0-pro-260628 de ByteDance pertenece a BytePlus ModelArk, y OmniaKey usa el id de arriba.

¿Por qué mi imagen lleva una etiqueta "AI generated"?

Toda salida de Seedream 5.0 Pro lleva la etiqueta en la esquina inferior derecha a menos que pongas watermark en false, según la página del modelo (revisada el 29 de octubre de 2026). Nuestra ejecución con los ajustes por defecto del 29 de octubre de 2026 la llevaba.

¿Qué tamaños acepta la API?

Los niveles 1K, 1.5K y 2K, o la forma widthxheight con una x minúscula entre los lados (página del modelo, revisada el 29 de octubre de 2026). La salida llega hasta 2K, y nuestras dos ejecuciones pidieron 1024x1024.

¿Puedo obtener PNG en lugar de JPEG?

Sí. output_format acepta png o jpeg, y JPEG es el valor por defecto (documentación, revisada el 29 de octubre de 2026). En las dos ejecuciones usamos PNG y recibimos PNG.

¿Puedo editar una imagen existente con Seedream?

Sí: envía operation en edit con el prompt y la imagen de origen, ya sea en Base64 en línea con su tipo mime o como una URL pública. La edición de la ventana del café está en la sección de tamaños.

Modelos de este artículo

Seedream 5.0 ProAPI de imagenPythontexto a imagenAPI

Artículos relacionados

Artículos recientes