DEV Community

Cover image for A Practical Guide to Editing Images with GPT-Image-2 over an OpenAI-Compatible API
Germey
Germey

Posted on • Originally published at platform.acedata.cloud

A Practical Guide to Editing Images with GPT-Image-2 over an OpenAI-Compatible API

If you are building an app that edits product photos, regenerates UI mockups, or converts assets into a new visual style, the hard part is usually not the prompt. It is getting reliable inputs and outputs into a repeatable API workflow.

This guide walks through a practical image-editing pipeline using gpt-image-2 through Ace Data Cloud's OpenAI-compatible Images Edits API. The goal is simple: send one or more reference images, describe the edit, and receive a generated image URL that your app can store, show, or pass into the next step.

What you can do

The Images Edits endpoint accepts an existing image plus an instruction. With gpt-image-2, the docs highlight a few useful behaviors for production workflows:

  • Keep the original layout and composition more stable while changing colors, backgrounds, or style.
  • Preserve text more accurately in assets such as posters, menus, and infographics.
  • Pass image URLs directly in JSON, so your server does not need to download and re-upload every input first.
  • Pass base64 image data when you do not want to host a local image before editing.
  • Request output sizes using auto or a WIDTHxHEIGHT string such as 1024x1536.

The key endpoint is:

Base URL: https://api.acedata.cloud/openai
Endpoint: POST /openai/images/edits
Authorization: Bearer {token}
Content-Type: application/json
Enter fullscreen mode Exit fullscreen mode

The most important fields are model, image, prompt, and optionally size. For gpt-image-2, image can be a URL string, an array of image URLs, or base64 image data.

How it works

A minimal JSON request looks like this:

curl -X POST "https://api.acedata.cloud/openai/images/edits" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "image": "https://platform.cdn.acedata.cloud/gpt-image/5c9fa635-8794-4c6d-88f8-584d7f4716c6_0.png",
    "prompt": "Convert this infographic to dark mode: dark navy background, light cream text, deep gray rounded module cards with soft shadows. Keep all layout, structure, and module arrangement identical - only invert the color scheme.",
    "size": "1024x1536"
  }'
Enter fullscreen mode Exit fullscreen mode

A successful response returns a task identifier, trace identifier, and an output image URL:

{
  "success": true,
  "task_id": "cb104e35-af1f-45be-9fac-b62e2b256753",
  "trace_id": "3e5c77c6-6c2e-4bba-a42d-98ea049b58a8",
  "created": 1777048863,
  "data": [
    {
      "revised_prompt": "Convert this infographic to dark mode: dark navy background, light cream text, deep gray rounded module cards with soft shadows. Keep all layout, structure, and module arrangement identical - only invert the color scheme.",
      "url": "https://platform.cdn.acedata.cloud/gpt-image/cb104e35-af1f-45be-9fac-b62e2b256753_0.png"
    }
  ],
  "elapsed": 83.859
}
Enter fullscreen mode Exit fullscreen mode

In a real app, I would usually store task_id, trace_id, the original request payload, and data[0].url. That makes it much easier to debug edits later, especially when users ask why a particular image changed in a certain way.

Use case 1: restyle an existing asset without rebuilding it

A common builder workflow is taking a working asset and changing the visual system around it. For example, you may already have an infographic that is correct, but you need a dark-mode version for a dashboard, landing page, or blog post.

The prompt should be explicit about what must stay fixed:

{
  "model": "gpt-image-2",
  "image": "https://platform.cdn.acedata.cloud/gpt-image/5c9fa635-8794-4c6d-88f8-584d7f4716c6_0.png",
  "prompt": "Convert this infographic to dark mode: dark navy background, light cream text, deep gray rounded module cards with soft shadows. Keep all layout, structure, and module arrangement identical - only invert the color scheme.",
  "size": "1024x1536"
}
Enter fullscreen mode Exit fullscreen mode

The important detail is not just "make it dark". It is the constraint: keep the layout, structure, and module arrangement identical. When editing production assets, constraints are often more important than style words.

Use case 2: combine multiple reference images

gpt-image-2 also supports multiple reference images by passing an array in the image field. The docs note that up to 16 reference images can be passed at the same time.

payload = {
    "model": "gpt-image-2",
    "image": [
        "https://example.com/item1.png",
        "https://example.com/item2.png",
        "https://example.com/item3.png"
    ],
    "prompt": "Combine all the items above into a single 'Relax & Unwind' gift basket on a clean white background, photorealistic, soft natural lighting.",
    "size": "1024x1024"
}
Enter fullscreen mode Exit fullscreen mode

This pattern is useful for ecommerce bundles, social creatives, campaign mockups, or any feature where users upload separate references and expect one composed result.

Use case 3: run edits through the OpenAI Python SDK

If your code already uses the OpenAI Python SDK, you can point it at the Ace Data Cloud OpenAI-compatible base URL:

export OPENAI_BASE_URL=https://api.acedata.cloud/openai
export OPENAI_API_KEY={token}
Enter fullscreen mode Exit fullscreen mode

Then call images.edit with gpt-image-2:

import base64
from openai import OpenAI

client = OpenAI()

result = client.images.edit(
    model="gpt-image-2",
    image=[open("test.png", "rb")],
    prompt="Convert this image to dark mode while keeping the layout intact."
)

image_base64 = result.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

with open("edited.png", "wb") as f:
    f.write(image_bytes)
Enter fullscreen mode Exit fullscreen mode

That is a good fit when you already have local files and want to keep the calling style close to existing OpenAI examples. For server-side pipelines that already have public or signed image URLs, the JSON URL method is often cleaner.

Notes before you ship

There are a few constraints worth designing around:

  • size must be auto, empty, or a WIDTHxHEIGHT string for gpt-image-2.
  • Custom sizes must use width and height that are multiples of 16, with long side no more than 3840 and total pixels no more than 8,294,400.
  • The default gpt-image-2 editing route returns one image per request; if you want multiple candidates, run multiple requests concurrently.
  • The API can return errors such as 401 invalid_token, 429 too_many_requests, or 500 api_error, so keep trace_id in your logs.
  • For longer edits, you can pass callback_url and handle the result asynchronously when the task completes.

A simple builder checklist

For a production feature, I would start with this flow:

  1. Store the user's original image URL or base64 input.
  2. Build a prompt that separates the desired change from the preservation constraints.
  3. Send model, image, prompt, and size to POST /openai/images/edits.
  4. Save task_id, trace_id, request payload, and output data[0].url.
  5. Add retries or async callbacks for slower jobs.

That is enough to turn image editing from a one-off prompt experiment into a feature your product can actually run. The full API reference and examples are in the OpenAI Images Edits API Integration Guide.

Top comments (0)