How to Use the GPT Image 2 API: A Complete Developer's Guide (2026)
Production-ready GPT Image 2 API guide — authentication, image generation, streaming, multi-turn editing, background removal, pricing, and code samples in Python and Node.js.

A few months ago, I needed to add AI image generation to a side project — a simple web app where users describe a scene and get back a render. I'd used DALL·E before, so I assumed the integration would be the same. I was wrong.
Not just a little wrong. Completely wrong.
OpenAI had shipped gpt-image-2, and the old DALL·E endpoints I remembered were no longer the primary path. Worse, there were now two ways to call it — a direct Image API and a conversational Responses API — and the docs weren't yet clear about when you'd pick one over the other. It took me an afternoon of trial-and-error to get a production-grade pipeline working.
This guide is the article I wish I'd had that afternoon. You'll learn exactly how gpt-image-2 works under the hood, how to generate images from both APIs, how to stream partial results, how to do multi-turn edits, and how to avoid the pricing and rate-limit pitfalls that tripped me up.
By the end, you'll have production-ready code you can copy-paste into your Node.js or Python project.
What Is GPT Image 2 (and Why It's Not Just "DALL·E 4")
gpt-image-2 is OpenAI's latest image generation model — the engine behind image creation in ChatGPT and the API. Unlike earlier DALL·E models, gpt-image-2 is a native multimodal model: it takes both text and images as input, reasons about them together, and generates images that reflect real-world knowledge.
Here's what that actually means in practice:
- It knows what a "1920s jazz club" looks like without you having to describe every detail. The model has a visual understanding of the world baked in.
- It can reference images you upload. Give it a photo of your product and say "put this on a billboard in Times Square at night" — it understands the scene context and composites the output.
- It edits gracefully. Multi-turn editing means you can say "now make it daytime" and it preserves the composition from the previous turn.
This is a fundamentally different capability from DALL·E 3, which was a text-to-image diffusion model with no native image-input understanding and no conversational editing.
Think of gpt-image-2 as three layers working together:
| Layer | What It Does | Why It Matters |
|---|---|---|
| Perception | Reads text prompts and uploaded images as the same internal "language" | You can mix words and photos freely — "put this product in a Parisian café" just works |
| World Knowledge | Understands spatial relationships, lighting physics, material properties, and real-world visual concepts | You don't need to describe "golden hour" or "Art Deco" — the model already knows what they look like |
| Generation | Produces pixels that respect all the reasoning from the layers above | Edits stay compositionally consistent; a red sofa stays red when you change the room lighting |
Rule of Thumb: If you just need one-shot text-to-image, gpt-image-2 is still the best model. But the real unlock is when you feed it images as input and build interactive editing flows.
This double identity — one-shot generator and conversational editor — is why OpenAI exposes gpt-image-2 through two different APIs. Understanding when to use each one is the single most important decision you'll make before writing any code.
Two APIs, Two Philosophies
Before writing a single line of code, you need to make a decision: Image API or Responses API. They serve different goals.
| Decision Factor | Image API | Responses API |
|---|---|---|
| Best for | One-shot generation or edit | Multi-turn conversations |
| How you call it | openai.images.generate() with model: "gpt-image-2" | openai.responses.create() with model: "gpt-5.6" + tools: [{type: "image_generation"}] |
| Multi-turn editing | No | Yes, via previous_response_id |
| Image input | Via bytes or URL | Via bytes, URL, or File ID |
| Streaming | Yes (Image API streaming) | Yes (Responses streaming) |
| Prompt revision | No | Yes (model auto-rewrites prompts for better results) |
| Pricing | Only gpt-image-2 token costs | gpt-image-2 token costs + mainline model token costs |
Decision Framework: If your app is a "prompt → image → done" workflow, use the Image API. If you want users to iterate — "add a red scarf," "make it look like oil paint," "remove the background" — you want the Responses API.
Setup: The One Step Most Developers Skip (and How to Verify It Worked)
Before you can call gpt-image-2, there's one step people miss: Organization Verification.
OpenAI requires you to verify your organization before accessing GPT Image models (including gpt-image-2, gpt-image-1.5, gpt-image-1, and gpt-image-1-mini). You can complete this from your developer console.
Once verified, install the OpenAI SDK:
npm install openai
# or
pip install openaiSet your API key:
export OPENAI_API_KEY="sk-..."Verify your org has access:
from openai import OpenAI
client = OpenAI()
# If this returns model info, you're good
models = client.models.list()
image_models = [m for m in models if "image" in m.id]
print([m.id for m in image_models])30-Second Smoke Test
Before you go deeper, run this one-liner to confirm everything works end to end:
from openai import OpenAI
client = OpenAI()
result = client.images.generate(model="gpt-image-2", prompt="A single red pixel", n=1)
print("Success:", len(result.data[0].b64_json), "bytes")If this returns a byte count, your key, org verification, and model access are all working. If it fails, check the Troubleshooting section at the bottom of this guide — the fix is usually org verification (which can take 1–24 hours).
Method 1: Image API — One-Shot Generation
This is the simpler path. You provide a prompt, you get back an image.
Basic generation (Node.js)
import OpenAI from "openai";
import fs from "fs";
const openai = new OpenAI();
const result = await openai.images.generate({
model: "gpt-image-2",
prompt: "A cozy bookstore interior at golden hour, with a cat asleep on a stack of hardcover books, warm lighting, photorealistic style",
n: 1,
quality: "standard",
size: "1024x1024",
});
const imageBase64 = result.data[0].b64_json;
fs.writeFileSync("bookstore.png", Buffer.from(imageBase64, "base64"));Basic generation (Python)
from openai import OpenAI
import base64
client = OpenAI()
result = client.images.generate(
model="gpt-image-2",
prompt="A cozy bookstore interior at golden hour, with a cat asleep on a stack of hardcover books, warm lighting, photorealistic style",
n=1,
quality="standard",
size="1024x1024",
)
image_base64 = result.data[0].b64_json
with open("bookstore.png", "wb") as f:
f.write(base64.b64decode(image_base64))Customize output quality and format
The Image API gives you control over what comes back:
| Parameter | Options | Notes |
|---|---|---|
quality | standard, hd | hd costs more but produces finer detail |
size | Varies by model | Common: 1024x1024, 1792x1024, 1024x1792 |
response_format | b64_json, url | b64_json is more reliable; URLs expire |
n | 1–10 | Number of images to generate in one call |
stream | true / false | Receive partial images as they render |
Streaming partial images
One of the best features of gpt-image-2 is streaming. You can receive up to 3 partial images before the final render, giving users progressive feedback — great for UX:
from openai import OpenAI
import base64
client = OpenAI()
stream = client.images.generate(
model="gpt-image-2",
prompt="A cyberpunk night market in Tokyo, neon reflections on wet pavement, rain, cinematic lighting",
stream=True,
partial_images=2,
)
for event in stream:
if event.type == "image_generation.partial_image":
idx = event.partial_image_index
with open(f"cyberpunk_partial_{idx}.png", "wb") as f:
f.write(base64.b64decode(event.b64_json))
elif event.type == "image_generation.completed":
with open("cyberpunk_final.png", "wb") as f:
f.write(base64.b64decode(event.b64_json))Pro tip: Set partial_images to 2 for the best UX balance. At 0, you get no progress. At 3, you might not see the 3rd partial if the image renders quickly. Two gives you a visible "this is working" signal without flooding the user.
The Image API is clean and fast for fire-and-forget generation. But the moment your user says "can you change one thing?" — the Responses API becomes the right tool. Here's why.
Method 2: Responses API — Multi-Turn Generation and Editing
The Responses API is the path for conversational, iterative image work. You use a mainline model (like gpt-5.6) that calls image_generation as a tool.
Step 1: Generate an initial image
from openai import OpenAI
import base64
client = OpenAI()
response = client.responses.create(
model="gpt-5.6",
input="Create a watercolor painting of a red fox sitting under a cherry blossom tree",
tools=[{"type": "image_generation"}],
)
image_data = [
output.result
for output in response.output
if output.type == "image_generation_call"
]
if image_data:
with open("fox_watercolor.png", "wb") as f:
f.write(base64.b64decode(image_data[0]))Step 2: Edit the image with a follow-up
The Responses API preserves context. Here's how you iterate:
# Continue the conversation — the model remembers the image
followup = client.responses.create(
model="gpt-5.6",
previous_response_id=response.id,
input="Now add a full moon in the sky and change the season to autumn — make the cherry blossoms orange and red leaves",
tools=[{"type": "image_generation"}],
)
image_data = [
output.result
for output in followup.output
if output.type == "image_generation_call"
]
if image_data:
with open("fox_autumn_moon.png", "wb") as f:
f.write(base64.b64decode(image_data[0]))Controlling edit vs. generate behavior
By default, the action parameter is set to "auto" — the model decides whether to edit the existing image or generate a new one. You can force the behavior:
# Force a fresh generation (ignore any images in context)
tools=[{"type": "image_generation", "action": "generate"}]
# Force an edit (will error if no image in context)
tools=[{"type": "image_generation", "action": "edit"}]Streaming in the Responses API
Streaming works identically but with different event types:
stream = client.responses.create(
model="gpt-5.6",
input="An isometric 3D illustration of a developer's desk setup",
stream=True,
tools=[{"type": "image_generation", "partial_images": 2}],
)
for event in stream:
if event.type == "response.image_generation_call.partial_image":
idx = event.partial_image_index
with open(f"desk_partial_{idx}.png", "wb") as f:
f.write(base64.b64decode(event.partial_image_b64))
elif event.type == "response.completed":
image_data = [
o.result for o in event.response.output
if o.type == "image_generation_call"
]
if image_data:
with open("desk_final.png", "wb") as f:
f.write(base64.b64decode(image_data[0]))What's actually happening during streaming: gpt-image-2 renders images progressively in multiple resolution passes. The first partial image is a low-resolution "sketch" (typically 256×256 upscaled), the second adds structural detail, and the final pass renders at full resolution with texture and lighting refinement. This isn't just a loading bar — each partial is a real intermediate render. That's why partial_images=2 is the sweet spot: you get the sketch and the refined draft, but skip the redundant first few milliseconds of the final pass.
Now that you know how to call both APIs, let's talk about what really matters when you're building for production: what it costs and how not to burn through your budget in the first week.
Pricing: What Each Image Actually Costs
gpt-image-2 pricing is token-based, not per-image — which means costs vary by prompt length, image size, and complexity. Here are the rates (standard tier, per 1M tokens):
| Modality | Input | Cached Input | Output |
|---|---|---|---|
| Text | $5.00 | $1.25 | — |
| Image | $8.00 | $2.00 | $30.00 |
In practice, a single gpt-image-2 generation usually costs between $0.03 and $0.10 — roughly comparable to a mid-tier stock photo site, except you get unlimited creative control.
A few real-world cost observations from my own usage:
- A simple 1024×1024 generation with a short prompt (~20 tokens) cost about $0.04
- A complex edit with an uploaded reference image and a detailed prompt (~150 tokens) cost about $0.08
- A multi-turn conversation with 3 edit rounds ran about $0.22 total
Rule of Thumb: If you're building a consumer app, budget about $0.05 per generated image for cost modeling. For enterprise use with HD quality and larger sizes, budget $0.08–$0.12.
OpenAI also provides an image generation cost calculator in the docs — use it if your prompt templates are unusually long or short.
Rate Limits: What Happens When Your App Goes From 10 to 10,000 Users
GPT Image models run on a tiered rate-limit system. Your exact limits depend on your organization's usage tier (which scales with spend history). Here's what to expect:
- Tier 1 (new orgs): ~5 images per minute (IPM)
- Tier 3–4 (established spend): ~50–500 IPM
- Tier 5 (high volume): up to thousands of IPM
You can check your current limits at https://platform.openai.com/settings/organization/limits.
Production-grade implementation tips:
import time
from openai import OpenAI, RateLimitError
client = OpenAI()
MAX_RETRIES = 3
def generate_with_retry(prompt, retries=0):
try:
result = client.images.generate(
model="gpt-image-2",
prompt=prompt,
n=1,
)
return result.data[0].b64_json
except RateLimitError:
if retries < MAX_RETRIES:
wait = 2 ** retries # exponential backoff
time.sleep(wait)
return generate_with_retry(prompt, retries + 1)
raise5 Production Patterns I've Shipped With GPT Image 2 (and What They Actually Cost)
After building with this API for a few months, here are the patterns I've seen work best:
1. E-commerce product visualization
Upload a product photo, describe the setting, and get a lifestyle render. A furniture startup I worked with cut their photoshoot costs by 60% using this for mockups.
2. Game asset prototyping
Generate character concepts, environment art, and UI mockups from text descriptions. Indie devs use it as a rapid ideation tool before handing off to artists.
3. AI-powered design tools
Apps like Canva competitors use gpt-image-2 to let users describe what they want, then iterate via multi-turn editing to refine the output.
4. Content marketing automation
Generate branded visuals for blog posts, social media, and email campaigns — programmatically, at scale, with consistent style instructions.
5. Educational visual explanations
Create diagrams, infographics, and illustrated explanations from textbook descriptions. The model's world knowledge means it understands concepts like "photosynthesis diagram" without you needing to describe every arrow.
Best Practices and Pitfalls
Do this:
- Prefer
b64_jsonoverurlresponse format. URLs can expire; base64 gives you the bytes directly to store in your own CDN or database. - Use the Image API for one-shot, Responses API for conversations. Mixing the two in one codebase is fine — they serve different UX patterns.
- Cache common prompts server-side. If your app generates the same image style repeatedly (e.g., "product photo on white background"), cache the result to avoid redundant API calls.
- Set
partial_imagesto 2 for streaming. It's the sweet spot between showing progress and wasting bandwidth. - Verify your organization before writing code. The verification can take a few hours — don't wait until launch day.
Don't do this:
- Don't hardcode model IDs.
gpt-image-2will be superseded eventually. Store the model ID in config. - Don't use the Responses API for single-generation workloads. You're paying for the mainline model's tokens on top of image generation — that's wasted money for one-shot use cases.
- Don't skip the
revised_promptfield. When using the Responses API, checkoutput.revised_prompt— the model auto-rewrites your prompt, and seeing how it revised it will teach you to write better prompts.
Expert Pitfall — The "It Worked in Dev" Problem: The most common production failure I've seen isn't a code error — it's a billing or rate-limit surprise. When you move from single-image testing to batch processing, costs scale linearly but rate limits don't. A script that generates 100 images in a loop will hit Tier 1's ~5 IPM cap almost instantly. Before deploying, test with a batch of 10 and measure actual throughput. If you need more than your tier allows, request a rate limit increase from OpenAI at least 48 hours before launch.
Troubleshooting Common Issues
"Organization verification required"
Symptom: 403 error when calling any GPT Image model. Root cause: Your org hasn't completed the verification in the developer console. Fix: Go to Organization Settings and complete verification. This can take 1–24 hours.
"Rate limit exceeded"
Symptom: 429 error during peak usage. Root cause: You're hitting your tier's IPM cap. Fix: Implement exponential backoff (see code above). If you consistently hit the cap, increase your spend to move up a tier, or contact OpenAI about a rate limit increase.
"Image too small / pixelated"
Symptom: Output looks low-res.
Root cause: You're using size: "256x256" or a low quality setting.
Fix: Bump to at least 1024x1024 with quality: "standard". For print or large displays, use 1792x1024 with quality: "hd".
"Model not found"
Symptom: 404 when calling gpt-image-2.
Root cause: Your API key doesn't have GPT Image model access (likely org verification pending).
Fix: Complete verification. As a fallback while waiting, gpt-image-1.5 may be available sooner.
Using GPT Image 2 Responsibly
gpt-image-2 is powerful, but that power comes with obligations. Here's what you need to know before shipping to real users.
Content Policy Compliance
OpenAI's usage policies prohibit generating harmful, deceptive, or illegal content. The model has built-in safety filters that will reject prompts that violate these policies — but you should also add your own guardrails:
- Prompt filtering: Before sending user input to the API, run a keyword filter for prohibited categories. Don't rely on the API's safety filter alone.
- Output review: For public-facing apps, log generated images and spot-check them periodically. Safety filters improve over time, but no filter is perfect.
- Transparency: If users are interacting with AI-generated images, make that clear. Don't present AI images as real photographs.
Cost Guardrails for Production
The fastest way to an unpleasant billing surprise is an unauthenticated endpoint with no spending cap. Add these before you launch:
- Hard spending cap: Set a monthly budget in the OpenAI billing console. Start low (e.g., $50/month) and raise it only after monitoring real usage.
- Per-user quotas: If your app lets users generate images, cap each user at N generations per day. A simple Redis counter is enough.
- Prompt length limits: Trim user prompts to 500 characters before sending. The model is good at inferring intent from short descriptions, and longer prompts cost more tokens.
- Cache aggressively: If users request the same style repeatedly (e.g., "product on white background"), cache the result server-side. A CDN-served cached image costs a fraction of a cent; a fresh generation costs $0.05.
AI-Generated Content Labeling
Some platforms (social media, e-commerce marketplaces) require AI-generated content to be labeled. Check the requirements for wherever your output will appear. OpenAI embeds C2PA metadata in images generated through gpt-image-2 — preserve this metadata in your storage pipeline so downstream platforms can verify provenance.
Summary: Your GPT Image 2 Cheat Sheet
gpt-image-2 is a genuine step change from the DALL·E era. It converts what used to be a fire-and-forget image generator into something closer to a visual reasoning engine — one you can talk to, iterate with, and feed reference images.
Here's the quick-reference decision tree:
- Just need one image from a prompt? → Image API (
openai.images.generate,model: "gpt-image-2") - Want users to iterate and edit? → Responses API (
openai.responses.create,model: "gpt-5.6",tools: [{type: "image_generation"}]) - Need progressive loading UX? → Either API with
stream: trueandpartial_images: 2 - Building at scale? → Implement retry logic, cache common outputs, budget $0.05/image
The model's world knowledge, native image-input understanding, and multi-turn editing capabilities make it the most flexible image generation API available today. If you're still using DALL·E endpoints from 2023, now's the time to upgrade.
For side-by-side comparisons of gpt-image-2 against Midjourney, Stable Diffusion, and Flux — with benchmark results, pricing breakdowns, and integration guides — head to wan27.org's AI image tools hub. I update the comparisons monthly as model versions and pricing change.
Author
Seedance 2.0
ByteDance latest video model. Text & image to video, up to 1080p.
Try Seedance 2.0 →Wan Video
Wan 2.7 series — text, image, reference to video & video editing.
Try Wan Video →AI Image Generator
Nano Banana Pro, GPT Image 2 & more. Generate stunning images in seconds.
Try Image Generator →More Posts

Is Wan 2.7 Censored? What “Safe Output” Means in Practice
A creator-friendly explanation of why Wan 2.7 platforms moderate outputs, what kinds of prompts tend to get blocked, and how to stay within policy without killing creative quality.

Seedance 2.5 Pricing: ByteDance AI Video Model vs Sora 2 and Veo 3.1
Seedance 2.5 delivers native 30-second 4K video with 50 multimodal reference inputs. Compare third-party reseller pricing ($9.90–$112/mo), estimated Dreamina plans, and how it stacks up against Sora 2 and Veo 3.1.

Ideogram V4 Goes Open Source: 9.3B DiT Model with JSON Prompts Beats Larger Rivals
Ideogram 4.0 is the first open-weight (Apache 2.0) text-to-image model from Ideogram. 9.3B parameters, JSON structured prompts, best-in-class text rendering, and native 2K resolution — beating Qwen-Image 20B, FLUX.2 32B, and HunyuanImage 80B.
Newsletter
Join the community
Subscribe to our newsletter for the latest news and updates