Claude Opus 5.5 is live on SeedRouter

GPT Image 2 API in Python: a complete example

A complete GPT Image 2 API example in Python: submit a request, poll the task, download the images to disk, edit with references and handle errors safely.

Read as Markdown

To use the GPT Image 2 API from Python, POST your request to https://api.seedrouter.ai/v1/images/generations with the requests library, keep the task id it returns, poll /v1/tasks/{id} until the task is completed, and download the image URLs it lists. The script below does all four steps in about 40 lines and saves the images to disk.

It runs as-is once SEEDROUTER_API_KEY is set. If you do not have a key yet, get one first.

What does a complete GPT Image 2 script look like?

import os
import time
import requests

API = "https://api.seedrouter.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"}


def submit(body):
    response = requests.post(f"{API}/images/generations", headers=HEADERS, json=body, timeout=60)
    if response.status_code >= 400:
        error = response.json()["error"]
        raise RuntimeError(f"{response.status_code} {error['code']}: {error['message']}")
    return response.json()["id"]


def wait(task_id, limit_seconds=600):
    deadline = time.monotonic() + limit_seconds
    while time.monotonic() < deadline:
        task = requests.get(f"{API}/tasks/{task_id}", headers=HEADERS, timeout=30).json()
        if task["status"] == "completed":
            return [image["url"] for image in task["output"]["data"]]
        if task["status"] == "failed":
            raise RuntimeError(f"{task['error']['code']}: {task['error']['message']}")
        time.sleep(3)
    raise TimeoutError(f"Still running. Resume polling task {task_id}.")


def download(urls, prefix):
    paths = []
    for index, url in enumerate(urls):
        path = f"{prefix}-{index}.png"
        with open(path, "wb") as file:
            file.write(requests.get(url, timeout=60).content)
        paths.append(path)
    return paths


task_id = submit({
    "model": "gpt-image-2",
    "prompt": "A matte ceramic vase on a sunlit table, soft shadows",
    "size": "1024x1024",
    "quality": "low",
    "n": 2,
})
print("task", task_id)
print(download(wait(task_id), "vase"))

Run it with python example.py. It prints the task ID first, then the paths of two PNG files, vase-0.png and vase-1.png.

What does each function do?

submit sends the request and returns the task ID. An error response always carries an error object with a numeric code and a message, so the exception tells you what to fix. A 400 with code 20001 and the message "Check the size parameter against the API documentation.", for instance, means the size broke one of the rules in the parameter guide.

wait polls every three seconds until the task finishes. A deadline on your side stops the loop, not the task: the render keeps going, and you can resume polling the same ID later. A task that ends failed raises with its error code and is not charged.

download fetches every URL the task returned and writes it to disk. Result URLs are a delivery handoff, not permanent storage, so save what you want to keep. The example uses requests for downloads as well as API calls; keep one HTTP client throughout rather than mixing in the standard library's urllib.

How do you change the image settings?

Everything is in the request body. The fields most people change first:

FieldExampleEffect
size"1536x1024"Output dimensions; auto lets the model choose
quality"medium"low, medium, high or auto
n4Number of images, 1 to 10
output_format"jpeg"png or jpeg
background"transparent"Needs png

If you change output_format, change the .png extension in download to match. The full list of fields and limits is in the GPT Image 2 API reference.

How do you edit an image from Python?

Pass reference images as URLs in the same call. There is no separate edit endpoint; adding images makes the request an edit, and a mask limits the change to one region:

task_id = submit({
    "model": "gpt-image-2",
    "prompt": "Make the vase deep blue. Keep the table and the light unchanged.",
    "images": [{"image_url": "https://example.com/vase.png"}],
})

The URLs must be public HTTPS links to PNG, JPEG or WebP files. You can send up to 16. Local files and base64 strings are rejected, so upload the image to your own storage first and pass its URL.

What should the script do when submission times out?

Do not submit again straight away. A timeout on the POST does not prove the request was rejected; the task may already be running and charged. Check your recent tasks, or retry the request only after confirming no task was created. The task guide explains how to tell the two apart.

Polling is different: a timeout while polling is harmless. Call wait again with the same ID.

Frequently asked questions

Can I use the OpenAI Python SDK instead?

Not directly. This API delivers results asynchronously through a task ID, while the SDK's image call expects the finished image in the response. A few lines of requests, as above, cover the whole flow.

How do I run several prompts?

Submit each prompt, store all the task IDs, then poll them. The batch guide shows a version that survives restarts without paying twice.

Does gpt-image-2-official need different code?

No. Change the model string and nothing else. The two IDs accept the same fields and return the same task response; only billing differs.

Keep the task ID, and the rest is plumbing

Submit, store the ID, poll with a deadline, and download what comes back. That pattern is the whole integration. Try a prompt without code in the GPT Image 2 Playground before you script it.

Related guides