You've seen the demos. Photorealistic product shots, pixel-perfect text rendering, images that actually follow complex instructions. Now you want GPT Image 2 in your app. The good news: you can make your first API call in under five minutes. This guide walks you through everything from setup to production-ready code.
What You Need Before Starting
Before writing any code, you need three things:
An OpenAI API key with the images:write scope. Head to platform.openai.com and create a project-scoped key (not a user-scoped one -- project keys are easier to rotate and audit).
Organization verification. OpenAI gates the GPT Image family behind API organization verification. If you haven't done this yet, go to your developer console and complete the verification process. It usually takes a few minutes.
A working Python or Node.js environment. Python 3.9+ or Node.js 18+ will work.
Set your API key as an environment variable. Never hardcode it:
export OPENAI_API_KEY="sk-proj-your-key-here"
Your First API Call in 5 Minutes
Python -- Text to Image
from openai import OpenAI
import base64
client = OpenAI()
response = client.images.generate(
model="gpt-image-2",
prompt="A flat vector logo of a mountain with a sunrise behind it, minimal style, white background",
size="1024x1024",
quality="medium",
)
# GPT Image 2 returns base64 data, not URLs
image_bytes = base64.b64decode(response.data[0].b64_json)
with open("logo.png", "wb") as f:
f.write(image_bytes)
print("Image saved to logo.png")
Node.js -- Text to Image
import OpenAI from "openai";
import { writeFile } from "node:fs/promises";
const client = new OpenAI();
const response = await client.images.generate({
model: "gpt-image-2",
prompt:
"A flat vector logo of a mountain with a sunrise behind it, minimal style, white background",
size: "1024x1024",
quality: "medium",
});
const imageBuffer = Buffer.from(response.data[0].b64_json, "base64");
await writeFile("logo.png", imageBuffer);
console.log("Image saved to logo.png");
One critical thing to know: GPT Image 2 returns base64-encoded image data in data[].b64_json, not temporary URLs like DALL-E 3. This is actually better for production -- no race to download before a URL expires.
Full Parameter Reference
Here is every parameter the images.generate endpoint accepts for gpt-image-2:
Parameter
Type
Required
Values
Default
model
string
Yes
"gpt-image-2"
--
prompt
string
Yes
Your image description
--
n
integer
No
1--10
1
size
string
No
"1024x1024", "1536x1024", "1024x1536", or custom WxH
"1024x1024"
quality
string
No
"low", "medium", "high"
"medium"
output_format
string
No
"png", "webp", "jpeg"
"png"
output_compression
integer
No
0--100 (jpeg/webp only)
--
background
string
No
"opaque", "auto"
"auto"
moderation
string
No
"auto", "low"
"auto"
Size: Custom Resolutions
Unlike DALL-E 3, GPT Image 2 supports custom resolutions beyond the standard presets. Both dimensions must be divisible by 16 and the aspect ratio must stay between 1:3 and 3:1. Some examples:
# Standard sizes
size="1024x1024" # Square
size="1536x1024" # Landscape
size="1024x1536" # Portrait
# Custom sizes (both dimensions divisible by 16)
size="1920x1080" # Full HD landscape
size="1280x720" # 720p
size="1536x864" # 16:9 widescreen
Resolutions above 2560x1440 are experimental. Stick to 2K or below for reliable results.
Quality: Speed vs. Fidelity
The quality parameter controls the tradeoff between generation speed and output fidelity:
low -- Fastest. Good for drafts, thumbnails, quick iteration. Around $0.006 per 1024x1024 image.
medium -- Balanced. The default. Suitable for most production use cases. Around $0.05 per 1024x1024 image.
high -- Highest fidelity. Use for final assets, hero images, print. Around $0.20 per 1024x1024 image.
Tip: Start every project on low. Only move to medium or high once your prompts are dialed in. You will burn through budget fast if you iterate on high.
Image Editing with the Edit Endpoint
The images.edit endpoint lets you modify existing images. Pass a source image, an optional mask, and a prompt describing what to change.
Python -- Edit an Image
from openai import OpenAI
import base64
client = OpenAI()
response = client.images.edit(
model="gpt-image-2",
image=open("product-photo.png", "rb"),
prompt="Change the background to a clean white studio backdrop",
size="1024x1024",
)
image_bytes = base64.b64decode(response.data[0].b64_json)
with open("product-edited.png", "wb") as f:
f.write(image_bytes)
Python -- Inpainting with a Mask
Use a mask to specify exactly which region to modify. The mask should be a PNG where transparent areas are the regions to regenerate and solid areas are preserved:
response = client.images.edit(
model="gpt-image-2",
image=open("room-photo.png", "rb"),
mask=open("mask.png", "rb"),
prompt="Replace the masked area with a modern leather sofa",
size="1024x1024",
)
Node.js -- Edit an Image
import OpenAI from "openai";
import { createReadStream } from "node:fs";
import { writeFile } from "node:fs/promises";
const client = new OpenAI();
const response = await client.images.edit({
model: "gpt-image-2",
image: createReadStream("product-photo.png"),
prompt: "Change the background to a clean white studio backdrop",
size: "1024x1024",
});
const imageBuffer = Buffer.from(response.data[0].b64_json, "base64");
await writeFile("product-edited.png", imageBuffer);
Multi-Image Editing
GPT Image 2 can also combine multiple source images. Pass several images to merge subjects, styles, or references into one output:
response = client.images.edit(
model="gpt-image-2",
image=[
open("character-sketch.png", "rb"),
open("background-reference.png", "rb"),
],
prompt="Place the character from the first image into the scene from the second image, maintaining consistent lighting",
size="1536x1024",
)
Batch Generation
Need multiple variations or a full set of images? Use the n parameter to generate up to 10 images per request:
response = client.images.generate(
model="gpt-image-2",
prompt="App store screenshot for a weather app, showing a 7-day forecast with clean UI",
size="1024x1536",
quality="medium",
n=4,
)
for i, image_data in enumerate(response.data):
image_bytes = base64.b64decode(image_data.b64_json)
with open(f"screenshot_{i+1}.png", "wb") as f:
f.write(image_bytes)
print(f"Saved screenshot_{i+1}.png")
Node.js -- Batch with Concurrency Control
When generating multiple images in Node.js, control your concurrency to avoid rate limits:
import OpenAI from "openai";
import { writeFile } from "node:fs/promises";
const client = new OpenAI();
const prompts = [
"App icon: a blue gradient circle with a white checkmark",
"App icon: a green gradient circle with a white leaf",
"App icon: a purple gradient circle with a white star",
"App icon: an orange gradient circle with a white flame",
];
// Process 2 at a time to stay within rate limits
const concurrency = 2;
for (let i = 0; i < prompts.length; i += concurrency) {
const batch = prompts.slice(i, i + concurrency);
const results = await Promise.all(
batch.map((prompt) =>
client.images.generate({
model: "gpt-image-2",
prompt,
size: "1024x1024",
quality: "medium",
})
)
);
for (let j = 0; j < results.length; j++) {
const buf = Buffer.from(results[j].data[0].b64_json, "base64");
await writeFile(`icon_${i + j + 1}.png`, buf);
}
}
For high-volume jobs, use OpenAI's Batch API to cut costs by 50%. You trade real-time responses for asynchronous processing, typically completing within 24 hours:
import json
# Prepare batch requests as JSONL
requests = []
for i in range(50):
requests.append({
"custom_id": f"product-{i}",
"method": "POST",
"url": "/v1/images/generations",
"body": {
"model": "gpt-image-2",
"prompt": f"Product photo variant {i+1}: wireless headphones on marble surface, soft lighting",
"size": "1024x1024",
"quality": "high",
}
})
# Write to JSONL file
with open("batch_requests.jsonl", "w") as f:
for req in requests:
f.write(json.dumps(req) + "\n")
# Upload and submit batch
batch_file = client.files.create(
file=open("batch_requests.jsonl", "rb"),
purpose="batch"
)
batch = client.batches.create(
input_file_id=batch_file.id,
endpoint="/v1/images/generations",
completion_window="24h"
)
print(f"Batch submitted: {batch.id}")
Cost Optimization Tips
GPT Image 2 uses token-based pricing, not flat per-image rates. Current OpenAI API pricing:
Token Type
Cost
Image input tokens
$8.00 / 1M tokens
Image output tokens
$30.00 / 1M tokens
Text input tokens
$5.00 / 1M tokens
Cached image input
$2.00 / 1M tokens
Here is how that translates to real costs per image at 1024x1024:
Quality
Approx. Cost per Image
Low
~$0.006
Medium
~$0.05
High
~$0.20
Higher resolutions and complex prompts push costs up. Here are practical ways to keep them down:
1. Iterate on Low, Ship on Medium
Use quality="low" during prompt development. Switch to "medium" or "high" only for your final renders. This alone can cut your development costs by 10x.
2. Use WebP Output
PNG files are large. Switch to WebP for smaller payloads with no visible quality loss:
Don't generate 2K images if you only need 512px thumbnails. Match your output size to its actual display context.
4. Batch API for Volume
As mentioned above, the Batch API delivers a flat 50% discount on all token costs. If latency is not critical, this is the single biggest cost lever.
5. Cache Input Images
When editing the same base image repeatedly (e.g., trying different backgrounds), OpenAI's cached image input rate is $2/M tokens vs. $8/M tokens. Structure your workflow to reuse inputs.
Or Skip the Token Math Entirely
If you would rather not manage OpenAI token buckets, rate limits, and per-call cost estimation, aigptimage.com wraps GPT Image 2 behind a simpler credit-based system:
Resolution
Credits per Image
1K (1024px)
3 credits
2K (2048px)
5 credits
4K (4096px)
8 credits
All paid plans include API access, starting at $11.90/month (Basic) with 180 req/min, up to $59.90+/month (Pro) with 1200 req/min. No token math, no surprise bills. See pricing.
Error Handling and Rate Limits
Common Error Codes
HTTP Code
Meaning
What to Do
400
Bad request or content policy violation
Check your prompt and parameters. Do not retry.
401
Invalid API key
Verify your key and scopes.
429
Rate limit exceeded
Back off and retry with exponential delay.
500
Server error
Retry with backoff. Usually transient.
Rate Limits
OpenAI rate limits for image generation are separate from text model limits and are based on your API tier. Tier 1 accounts start at roughly 50 requests per minute. Higher tiers scale up from there.
Key gotcha: Image rate limits bite at lower concurrency than you might expect. A key that handles 500 RPM for text generation might start getting 429s at just 10 concurrent image calls.
Production-Grade Error Handling (Python)
import time
import base64
from openai import OpenAI, RateLimitError, APIError, BadRequestError
client = OpenAI()
def generate_image(prompt, retries=3, **kwargs):
"""Generate an image with retry logic for transient errors."""
for attempt in range(retries):
try:
response = client.images.generate(
model="gpt-image-2",
prompt=prompt,
**kwargs,
)
return base64.b64decode(response.data[0].b64_json)
except BadRequestError as e:
# Content policy or invalid params -- don't retry
print(f"Bad request: {e.message}")
raise
except RateLimitError:
wait = 2 ** attempt # 1s, 2s, 4s
print(f"Rate limited. Waiting {wait}s...")
time.sleep(wait)
except APIError as e:
if attempt == retries - 1:
raise
wait = 2 ** attempt
print(f"API error ({e.status_code}). Retrying in {wait}s...")
time.sleep(wait)
raise RuntimeError("Max retries exceeded")
Every response includes headers that tell you exactly where you stand:
# After any API call, check the raw response headers
response = client.images.with_raw_response.generate(
model="gpt-image-2",
prompt="A test image",
size="1024x1024",
quality="low",
)
print(f"Remaining requests: {response.headers['x-ratelimit-remaining-requests']}")
print(f"Remaining tokens: {response.headers['x-ratelimit-remaining-tokens']}")
print(f"Reset in: {response.headers['x-ratelimit-reset-requests']}")
Throttle before you hit the limit. If x-ratelimit-remaining-requests drops below 5, slow down.
Quick Reference: Generation vs. Editing
Feature
images.generate
images.edit
Input
Text prompt only
Image(s) + prompt + optional mask
Use case
Create from scratch
Modify existing images
Multi-image
Via n param (variations)
Via multiple input images (compositing)
Mask support
No
Yes (PNG with transparency)
Max n
10
10
Prompt Engineering for the API
Writing prompts for the API is different from chatting with ChatGPT. There is no conversational back-and-forth -- your prompt needs to be complete and self-contained on the first call.
Be Specific About Style and Composition
Vague prompts produce unpredictable results. Compare these two:
# Vague -- you'll get something, but not what you need
prompt = "a cat"
# Specific -- predictable, usable output
prompt = "A tabby cat sitting on a windowsill, golden hour sunlight streaming in from the left, shallow depth of field, shot on 85mm lens, warm color palette"
Structure Complex Prompts
For detailed images, break your prompt into layers: subject, setting, style, and technical specs:
prompt = """
Subject: A ceramic coffee mug with a hand-painted floral pattern
Setting: On a rustic wooden table, morning kitchen scene
Style: Product photography, clean and editorial
Technical: Soft directional lighting from upper left, shallow depth of field, neutral background slightly blurred
"""
Text Rendering
GPT Image 2 is significantly better at rendering text in images than previous models. For best results, put the exact text in quotes within your prompt:
response = client.images.generate(
model="gpt-image-2",
prompt='A minimalist poster with the text "LAUNCH DAY" in bold sans-serif type, centered on a gradient background from deep navy to electric blue',
size="1024x1536",
quality="high",
)
For long or complex text, keep it under 30 words and specify the font style explicitly. GPT Image 2 handles short headlines and labels reliably, but accuracy drops with paragraph-length text.
Common Gotchas
A few things that will save you debugging time:
No transparent backgrounds. GPT Image 2 does not support background: "transparent". If you need transparency, use a separate background removal tool or an earlier model.
Base64, not URLs. Unlike DALL-E 3, responses come as b64_json. There are no temporary URLs to download from -- and no 1-hour expiry to race against.
Dimensions must be divisible by 16. Custom sizes like 1000x1000 will fail. Use 1008x1008 or 1024x1024 instead.
Org verification is required. If you get a permissions error on your first call, complete the organization verification in your OpenAI developer console.
Image rate limits are separate from text limits. Don't assume your text API capacity applies to image calls.
Mask precision is approximate. GPT Image 2 uses the mask as guidance, not a pixel-exact boundary. For surgical edits, provide a generous mask around the target area.
Building against the OpenAI API directly gives you maximum control, but it also means managing API keys, token budgets, rate limit logic, and billing surprises.
If you want GPT Image 2 without the infrastructure overhead, aigptimage.com provides:
Simple credit pricing -- 3 credits for 1K, 5 for 2K, 8 for 4K. No token math.
API access on all paid plans -- starting at $11.90/month with 180 req/min.
Built-in rate limiting and queuing -- no 429 handling on your end.
Multiple AI models -- switch between GPT Image 2, Nano Banana, Seedream, and more from one interface.
GPT Image 2 is the most capable image generation API available today. You can go from zero to a working integration in five minutes with the code examples above. Start with quality="low" to iterate fast, use the edit endpoint for precision work, and lean on the Batch API when volume matters.
The parameter reference and error handling patterns in this guide should cover the majority of production use cases. For the full API spec, check the official OpenAI documentation.