{"slug": "a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible", "title": "A Practical Guide to Editing Images with GPT-Image-2 over an OpenAI-Compatible API", "summary": "Ace Data Cloud's OpenAI-compatible Images Edits API now supports gpt-image-2 for production image-editing workflows. The endpoint accepts one or more reference images and an instruction, returning a generated image URL. Developers can specify constraints like layout preservation and use up to 16 reference images in a single request.", "body_md": "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.\n\nThis guide walks through a practical image-editing pipeline using `gpt-image-2`\n\nthrough 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.\n\nThe Images Edits endpoint accepts an existing image plus an instruction. With `gpt-image-2`\n\n, the docs highlight a few useful behaviors for production workflows:\n\n`auto`\n\nor a `WIDTHxHEIGHT`\n\nstring such as `1024x1536`\n\n.The key endpoint is:\n\n```\nBase URL: https://api.acedata.cloud/openai\nEndpoint: POST /openai/images/edits\nAuthorization: Bearer {token}\nContent-Type: application/json\n```\n\nThe most important fields are `model`\n\n, `image`\n\n, `prompt`\n\n, and optionally `size`\n\n. For `gpt-image-2`\n\n, `image`\n\ncan be a URL string, an array of image URLs, or base64 image data.\n\nA minimal JSON request looks like this:\n\n```\ncurl -X POST \"https://api.acedata.cloud/openai/images/edits\" \\\n  -H \"Authorization: Bearer {token}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gpt-image-2\",\n    \"image\": \"https://platform.cdn.acedata.cloud/gpt-image/5c9fa635-8794-4c6d-88f8-584d7f4716c6_0.png\",\n    \"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.\",\n    \"size\": \"1024x1536\"\n  }'\n```\n\nA successful response returns a task identifier, trace identifier, and an output image URL:\n\n```\n{\n  \"success\": true,\n  \"task_id\": \"cb104e35-af1f-45be-9fac-b62e2b256753\",\n  \"trace_id\": \"3e5c77c6-6c2e-4bba-a42d-98ea049b58a8\",\n  \"created\": 1777048863,\n  \"data\": [\n    {\n      \"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.\",\n      \"url\": \"https://platform.cdn.acedata.cloud/gpt-image/cb104e35-af1f-45be-9fac-b62e2b256753_0.png\"\n    }\n  ],\n  \"elapsed\": 83.859\n}\n```\n\nIn a real app, I would usually store `task_id`\n\n, `trace_id`\n\n, the original request payload, and `data[0].url`\n\n. That makes it much easier to debug edits later, especially when users ask why a particular image changed in a certain way.\n\nA 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.\n\nThe prompt should be explicit about what must stay fixed:\n\n```\n{\n  \"model\": \"gpt-image-2\",\n  \"image\": \"https://platform.cdn.acedata.cloud/gpt-image/5c9fa635-8794-4c6d-88f8-584d7f4716c6_0.png\",\n  \"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.\",\n  \"size\": \"1024x1536\"\n}\n```\n\nThe 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.\n\n`gpt-image-2`\n\nalso supports multiple reference images by passing an array in the `image`\n\nfield. The docs note that up to 16 reference images can be passed at the same time.\n\n```\npayload = {\n    \"model\": \"gpt-image-2\",\n    \"image\": [\n        \"https://example.com/item1.png\",\n        \"https://example.com/item2.png\",\n        \"https://example.com/item3.png\"\n    ],\n    \"prompt\": \"Combine all the items above into a single 'Relax & Unwind' gift basket on a clean white background, photorealistic, soft natural lighting.\",\n    \"size\": \"1024x1024\"\n}\n```\n\nThis pattern is useful for ecommerce bundles, social creatives, campaign mockups, or any feature where users upload separate references and expect one composed result.\n\nIf your code already uses the OpenAI Python SDK, you can point it at the Ace Data Cloud OpenAI-compatible base URL:\n\n```\nexport OPENAI_BASE_URL=https://api.acedata.cloud/openai\nexport OPENAI_API_KEY={token}\n```\n\nThen call `images.edit`\n\nwith `gpt-image-2`\n\n:\n\n``` python\nimport base64\nfrom openai import OpenAI\n\nclient = OpenAI()\n\nresult = client.images.edit(\n    model=\"gpt-image-2\",\n    image=[open(\"test.png\", \"rb\")],\n    prompt=\"Convert this image to dark mode while keeping the layout intact.\"\n)\n\nimage_base64 = result.data[0].b64_json\nimage_bytes = base64.b64decode(image_base64)\n\nwith open(\"edited.png\", \"wb\") as f:\n    f.write(image_bytes)\n```\n\nThat 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.\n\nThere are a few constraints worth designing around:\n\n`size`\n\nmust be `auto`\n\n, empty, or a `WIDTHxHEIGHT`\n\nstring for `gpt-image-2`\n\n.`gpt-image-2`\n\nediting route returns one image per request; if you want multiple candidates, run multiple requests concurrently.`401 invalid_token`\n\n, `429 too_many_requests`\n\n, or `500 api_error`\n\n, so keep `trace_id`\n\nin your logs.`callback_url`\n\nand handle the result asynchronously when the task completes.For a production feature, I would start with this flow:\n\n`model`\n\n, `image`\n\n, `prompt`\n\n, and `size`\n\nto `POST /openai/images/edits`\n\n.`task_id`\n\n, `trace_id`\n\n, request payload, and output `data[0].url`\n\n.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](https://platform.acedata.cloud/documents/openai-images-edits-integration).", "url": "https://wpnews.pro/news/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible", "canonical_source": "https://dev.to/germey/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible-api-508a", "published_at": "2026-07-15 05:12:00+00:00", "updated_at": "2026-07-15 05:26:48.559200+00:00", "lang": "en", "topics": ["artificial-intelligence", "generative-ai", "developer-tools", "ai-tools", "computer-vision"], "entities": ["Ace Data Cloud", "gpt-image-2", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible", "markdown": "https://wpnews.pro/news/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible.md", "text": "https://wpnews.pro/news/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible.txt", "jsonld": "https://wpnews.pro/news/a-practical-guide-to-editing-images-with-gpt-image-2-over-an-openai-compatible.jsonld"}}