Endpoints
Create a generation job. Use mode="text-to-image" for prompt-only renders or mode="image-to-image" with reference image URLs.
Poll a generation job. The endpoint returns 202 while pending or running, then 200 with either generated image URLs or a failure error.
Never put a GPTImage2.ai API key in browser code. Call these endpoints from your backend or a server route handler, then expose only your own scoped UI response to the browser.
Authentication and credits
Keys created on the Keys page authenticate with Authorization: Bearer $GPTIMAGE2_API_KEY. Every generated image spends 10credits from the key owner’s account. Failed upstream jobs are refunded by the same generation pipeline used by Studio.
Request interface
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The image brief. Put the subject first, then style, light, frame, and text. |
mode | string | No | text-to-image for prompt-only renders, or image-to-image when sending reference URLs. |
ratio | string | No | Aspect ratio such as 1:1, 16:9, 9:16, 4:3, or 3:4. |
count | number | No | Number of images to generate. Values are capped between 1 and 4. |
imageUrls | string[] | No | Reference image URLs for image-to-image jobs. Required when mode is image-to-image. |
style | string | No | Optional style preset slug, such as editorial-photo, studio-product, or cinematic. |
lighting | string | No | Optional lighting hint appended to the final prompt. |
camera | string | No | Optional camera or framing hint appended to the final prompt. |
negative | string | No | Optional avoid list appended to the final prompt. |
export interface GptImage2GenerateRequest {
prompt: string;
mode?: "text-to-image" | "image-to-image";
ratio?: "1:1" | "16:9" | "9:16" | "4:3" | "3:4";
count?: 1 | 2 | 3 | 4;
imageUrls?: string[];
style?: string;
lighting?: string;
camera?: string;
negative?: string;
}
export type GptImage2JobResponse =
| {
jobId: string;
status: "pending" | "running";
balance?: {
paidCredits: number;
totalImages: number;
};
}
| {
jobId: string;
status: "succeeded";
results: Array<{
imageUrl: string;
finalPrompt: string;
seed: string;
}>;
balance?: {
paidCredits: number;
totalImages: number;
};
}
| {
jobId: string;
status: "failed";
error: string;
balance?: {
paidCredits: number;
totalImages: number;
};
};Response interface
| Field | Type | Required | Description |
|---|---|---|---|
jobId | string | Yes | Generation job id returned by the create call and used for polling. |
status | string | Yes | running, pending, succeeded, or failed. |
results[].imageUrl | string | No | Generated image URL, present after the polling response succeeds. |
balance | object | No | Remaining credit balance for the API key owner. |
error | string | No | Machine-readable error code when the request or job fails. |
{
"jobId": "8b93b17d-6ec7-4bd7-96a2-b06f69e8b862",
"status": "running",
"balance": {
"paidCredits": 490,
"freeImagesRemaining": 0,
"totalImages": 49,
"freeImagesPerDay": 0
}
}
// Poll success
{
"jobId": "8b93b17d-6ec7-4bd7-96a2-b06f69e8b862",
"status": "succeeded",
"results": [
{
"imageUrl": "https://file.gptimage2.ai/generated/demo.png",
"seed": "1",
"finalPrompt": "A clean studio product photo of a ceramic espresso cup"
}
],
"balance": {
"paidCredits": 490,
"freeImagesRemaining": 0,
"totalImages": 49,
"freeImagesPerDay": 0
}
}Demo 1: Generate with cURL
The create call returns a jobId and the remaining balance after credits are reserved.
curl https://gptimage2.ai/api/generate \
-H "Authorization: Bearer $GPTIMAGE2_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "text-to-image",
"prompt": "A clean studio product photo of a ceramic espresso cup",
"ratio": "1:1",
"count": 1,
"style": "studio-product"
}'Poll the job with the same API key:
curl https://gptimage2.ai/api/generate/{jobId} \
-H "Authorization: Bearer $GPTIMAGE2_API_KEY"Demo 2: Image-to-image with reference URLs
Send image URLs for multi-reference jobs. Each URL should have one purpose: subject, palette, composition, or material reference.
curl https://gptimage2.ai/api/generate \
-H "Authorization: Bearer $GPTIMAGE2_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "image-to-image",
"prompt": "Keep the product from ref 1, use the color palette from ref 2.",
"imageUrls": [
"https://cdn.example.com/subject.png",
"https://cdn.example.com/palette.png"
],
"ratio": "1:1",
"count": 1
}'Demo 3: Node.js job polling
This demo uses native fetch in Node 18+ and prints the first image URL after the job succeeds.
const create = await fetch("https://gptimage2.ai/api/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GPTIMAGE2_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
mode: "text-to-image",
prompt: "An editorial product photo of a matte black camera on red lacquer",
ratio: "1:1",
count: 1,
}),
});
const job = await create.json();
if (!create.ok) throw new Error(job.error ?? `HTTP ${create.status}`);
let result = job;
while (result.status === "pending" || result.status === "running") {
await new Promise((resolve) => setTimeout(resolve, 2500));
const poll = await fetch(`https://gptimage2.ai/api/generate/${job.jobId}`, {
headers: { Authorization: `Bearer ${process.env.GPTIMAGE2_API_KEY}` },
});
result = await poll.json();
}
console.log(result.results?.[0]?.imageUrl ?? result.error);Demo 4: Python requests
Install the HTTP client with pip install requests, set GPTIMAGE2_API_KEY, then run the script.
import os
import time
import requests
headers = {
"Authorization": f"Bearer {os.environ['GPTIMAGE2_API_KEY']}",
"Content-Type": "application/json",
}
job = requests.post(
"https://gptimage2.ai/api/generate",
headers=headers,
json={
"mode": "text-to-image",
"prompt": "A warm studio portrait of a ceramic bottle on folded linen",
"ratio": "1:1",
"count": 1,
},
)
job.raise_for_status()
data = job.json()
while data["status"] in ("pending", "running"):
time.sleep(2.5)
poll = requests.get(
f"https://gptimage2.ai/api/generate/{data['jobId']}",
headers=headers,
)
poll.raise_for_status()
data = poll.json()
print(data.get("results", [{}])[0].get("imageUrl") or data.get("error"))Demo 5: Next.js route handler proxy
Use a route handler when your app needs extra authorization, rate limits, or request shaping before calling GPTImage2.ai.
// app/api/render/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { prompt } = (await req.json()) as { prompt?: string };
if (!prompt?.trim()) {
return NextResponse.json({ error: "prompt_required" }, { status: 400 });
}
try {
const upstream = await fetch("https://gptimage2.ai/api/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GPTIMAGE2_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
mode: "text-to-image",
prompt,
ratio: "1:1",
count: 1,
}),
});
const result = await upstream.json();
return NextResponse.json(
result,
{
status: upstream.status,
headers: { "Cache-Control": "no-store" },
},
);
} catch (err) {
return NextResponse.json({ error: "image_generation_failed" }, { status: 500 });
}
}Operational checklist
Validation
Trim prompts, reject empty input, cap count, validate ratios, and verify reference image URLs before spending credits.
Cost control
Start with count: 1, show remaining credits after each job, and only request multiple candidates when the workflow needs comparison.
Reliability
Retry 429/5xx responses with backoff, add idempotency keys for paid jobs, and store the original prompt, ratio, count, and returned job id.
Security
Keep provider keys on the server, scope customer access through your own auth, and log enough metadata to audit expensive or abusive requests.
Migration: dall-e-3 to gpt-image-2
- POST https://old-provider.example/images/generations
+ POST https://gptimage2.ai/api/generate
- Authorization: Bearer $OLD_PROVIDER_KEY
+ Authorization: Bearer $GPTIMAGE2_API_KEY
- { "prompt": "...", "width": 1024, "height": 1024, "count": 1 }
+ { "mode": "text-to-image", "prompt": "...", "ratio": "1:1", "count": 1 }Test three differences in staging: payloads are larger, quoted in-image text is followed more literally, and image URLs are returned after asynchronous job polling instead of inside the create response. Full side-by-side breakdown on GPT Image 2 vs DALL-E 3.
Pricing detail on the pricing page; full walkthrough on how to use GPT Image 2.