GPT Image 2 Image Generation
Generate and edit images with GPT Image 2 quality and resolution controls.
High-control image generation and editing with independent quality and resolution controls.
Provider
OpenAIModel ID
gpt-image-2Endpoint
POST /api-platform/v1/generationsAuthentication
Base URL: https://aihub-admin.aimix.pro. Send Authorization: Bearer <PIXMIND_API_KEY> on both creation and polling requests, and Content-Type: application/json when submitting JSON. Keep your key in a server environment variable.
Model notes
- Omit referenceImages for text-to-image generation; supply image URLs for editing. Use resolution for the output tier and aspectRatio for its shape.
- quality defaults to medium, resolution to 2K, aspectRatio to 1:1, and sampleCount to 1. Set aspectRatio to auto explicitly for automatic framing.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Stable PixMind model ID. Use `gpt-image-2`. Allowed values: |
prompt | string | Yes | Natural-language generation or editing instructions. |
quality | string | No | Generation quality tier. Allowed values: Default: |
resolution | string | No | Output resolution tier. Allowed values: Default: |
aspectRatio | string | No | Requested output aspect ratio. Allowed values: Default: |
sampleCount | integer | No | Number of output images per task, from 1 to 4. Allowed values: Default: |
referenceImages | string[] (URI) | No | Up to 16 reference image URLs (JPEG, PNG, WebP), up to 10 MB each. URLs must be accessible to the service; omit for text-to-image generation. |
Request example
curl --request POST 'https://aihub-admin.aimix.pro/api-platform/v1/generations' \
-H "Authorization: Bearer $PIXMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "Create a skincare product campaign image on a warm beige background",
"quality": "medium",
"resolution": "2K",
"aspectRatio": "1:1",
"sampleCount": 1
}'// Node.js 20+. Keep the API key on your server.
const apiKey = process.env.PIXMIND_API_KEY;
if (!apiKey) throw new Error("PIXMIND_API_KEY is required");
const response = await fetch("https://aihub-admin.aimix.pro/api-platform/v1/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"model": "gpt-image-2",
"prompt": "Create a skincare product campaign image on a warm beige background",
"quality": "medium",
"resolution": "2K",
"aspectRatio": "1:1",
"sampleCount": 1
}),
signal: AbortSignal.timeout(30_000)
});
const task = await response.json();
if (!response.ok || task.code !== 1000) {
throw new Error(task.message ?? task.error?.message ?? `HTTP ${response.status}`);
}
console.log(task);Accepted task response
Generation is asynchronous. Save taskId and poll GET /api-platform/v1/tasks/{taskId} until status is ready or failed.
{
"code": 1000,
"data": {
"id": "img_44160",
"taskId": 44160,
"type": "image",
"model": "gpt-image-2",
"status": "processing"
}
}Query the task and retrieve results
Replace 44160 with data.taskId from the accepted response, using a key belonging to the same user. pending and processing are non-terminal; ready and failed are terminal. On ready, read images (images) or videoUrl (videos); on failed, read errorMessage. The example stops after 60 queries. If it times out, save taskId and query again later instead of creating a duplicate task. Example result URLs are placeholders.
curl 'https://aihub-admin.aimix.pro/api-platform/v1/tasks/44160' \
-H "Authorization: Bearer $PIXMIND_API_KEY"// Continue after the request example above.
const taskId = task.data?.taskId;
if (!Number.isInteger(taskId)) throw new Error("Missing numeric taskId");
async function waitForTask(taskId) {
for (let attempt = 0; attempt < 60; attempt++) {
await new Promise(resolve => setTimeout(resolve, Math.min(2000 * 1.5 ** attempt, 10000)));
const response = await fetch(`https://aihub-admin.aimix.pro/api-platform/v1/tasks/${taskId}`, {
headers: { Authorization: `Bearer ${apiKey}` },
signal: AbortSignal.timeout(30_000)
});
const result = await response.json();
if (!response.ok || result.code !== 1000) {
throw new Error(result.message ?? `HTTP ${response.status}`);
}
const data = result.data;
if (data.status === "ready") return data;
if (data.status === "failed") {
throw new Error(data.errorMessage ?? "Generation failed");
}
if (!["pending", "processing"].includes(data.status)) {
throw new Error(`Unexpected task status: ${data.status}`);
}
}
throw new Error(`Polling timed out; save taskId ${taskId} to query again later`);
}
const result = await waitForTask(taskId);
console.log(result.images);{
"code": 1000,
"data": {
"taskId": 44160,
"type": "image",
"model": "gpt-image-2",
"status": "ready",
"progress": 100,
"images": [
"https://example.com/result.png"
]
}
}Edit an existing image
Add referenceImages and describe what to preserve and change in prompt. Replace the example URL below with an accessible image URL; local file paths are not supported here.
{
"model": "gpt-image-2",
"prompt": "Preserve the packaging and brand text, and replace the background with a warm beige studio scene",
"quality": "medium",
"resolution": "2K",
"aspectRatio": "1:1",
"sampleCount": 1,
"referenceImages": ["https://example.com/package.png"]
}For local files, follow temporary media upload first and use the returned URL. Use camelCase request fields; send the resolution tier as resolution, for example 2K.
Errors and retries
Acceptance requires both a successful HTTP response and business code: 1000; acceptance does not mean generation has finished. A failed generation returns status: "failed" and errorMessage when polled.
- Invalid parameters: check the model ID, enums, sample count, and reference URLs before resubmitting.
- Authentication errors: verify the Bearer key and its associated application; see authentication.
- Rate limits or temporary service errors: reduce request frequency and use exponential backoff with jitter; see errors and retries.
- Request timeout: keep an existing
taskIdand continue polling. If no ID was received, check whether the original task was accepted before submitting again.
See asynchronous tasks for the complete lifecycle.