GPT-Image 2 Image Generation and Editing
Inference Space GPT-Image 2 text-to-image, image-to-image, and multi-image editing API with OpenAI compatibility.
GPT-Image 2 is Inference Space's image generation and editing model, with an interface compatible with the OpenAI Images API. It supports text-to-image generation, single-image editing, and multi-image fusion editing with up to 16 reference images. The model performs consistently with Chinese prompts, layout control, and image-text consistency, making it suitable for e-commerce hero images, posters, illustrations, and product-image compositing.
Overview
- Text-to-image:
POST https://ai.inf.space/v1/images/generations,application/json. - Image-to-image / multi-image editing:
POST https://ai.inf.space/v1/images/edits,multipart/form-data. - model is fixed at
gpt-image-2. - Multi-image editing is the core capability: upload multiple reference images with repeated
image[]fields, then refer to them in upload order as “image 1 / image 2 / image 3” in the prompt.
The interface is compatible with the OpenAI Images API. Existing OpenAI image clients can connect by changing only the Base, Key, and model. Note that this gateway forwards only the parameters it actually supports; other OpenAI parameters are ignored. See the “Parameters” and “OpenAI compatibility” sections below for details.
Authentication and Base
- API Base:
https://ai.inf.space/v1(the browser console shares the host; use the/v1path for API requests) - Authentication header:
Authorization: Bearer $AI_TOS_API_KEY
Create an API Key in the console and pass it in the Authorization header for each request. In production, keep the Key on the server and do not expose it in the browser.
Text-to-image
Send a JSON request to /v1/images/generations with model and prompt, plus optional size and quality parameters. Text-to-image generates one PNG image.
curl "https://ai.inf.space/v1/images/generations" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A white ceramic mug on a gray tabletop, soft natural light, e-commerce hero-image style",
"size": "1024x1024",
"quality": "auto"
}'In addition to OpenAI's standard size, text-to-image supports the gateway extension aspectRatio (for example, "3:4", automatically aligned to a supported widthxheight at the 1K / 2K / 4K tier). Clients must not select a provider; the gateway selects a service from organization routing policy and performs failover.
Image-to-image and multi-image editing
Send a multipart/form-data request to /v1/images/edits.
Quick verification with a public image URL
For a quick end-to-end verification, pass a publicly accessible image URL as JSON without downloading it locally first:
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "Improve the e-commerce image layout and typography, and change the model's hairstyle to loose waves",
"input_images": [
"https://tos.cn-sh2.ufileos.com/public/image-curl-verify/2026-07-02/test_image-d9d3d81e4d88.png"
],
"size": "1024x1024",
"quality": "low"
}'input_images / images support public https:// image URLs, data URLs, or raw base64. For production integrations, your own CDN is still recommended to avoid broken third-party image links.
Single-image editing
Send one image field:
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-F "model=gpt-image-2" \
-F "image=@product.png" \
-F "prompt=Replace the background with a pure-white e-commerce hero-image background while preserving the product details" \
-F "size=1024x1024"Multi-image editing (core capability)
Upload multiple reference images with repeated image[] fields (OpenAI array syntax), up to 16 images, each in PNG / JPEG / WebP format. Upload order determines reference order; refer to the corresponding images as “image 1 / image 2 / image 3” in the prompt.
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-F "model=gpt-image-2" \
-F "image[]=@bag.png" \
-F "image[]=@scarf.png" \
-F "image[]=@model.png" \
-F "prompt=Have the model in image 3 carry the handbag from image 1 and wear the silk scarf from image 2, with an overall street-style look" \
-F "size=1024x1536"Upload order determines image numbering: the first image[] is “image 1,” the second is “image 2,” and so on. Make sure numbered references in the prompt match upload order.
Local editing (mask)
Use the mask field for inpainting: only transparent areas of the mask are redrawn, while opaque areas are preserved. mask is effective only with multipart/form-data on the edits endpoint, and its alpha channel is preserved.
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-F "model=gpt-image-2" \
-F "image=@room.png" \
-F "mask=@room-mask.png" \
-F "prompt=Replace the masked area with a floor-to-ceiling window" \
-F "size=1024x1024"- The mask must be a PNG with an alpha channel: transparent areas = areas to redraw, opaque areas = areas to preserve.
- The mask applies to the first reference image (the first
image/image[]). - Only multipart is supported (not a JSON body); the default path and the policy-routing / failover editing paths all support it.
- All currently available gpt-image-2 services support masks; see the model catalog and console for current availability.
The mask semantics follow OpenAI gpt-image: areas with transparent alpha are redrawn, and areas with opaque alpha are preserved. The areas to redraw must therefore be transparent in the mask; do not invert them.
Hard requirements for mask dimensions and format
- The mask dimensions must match the first source image pixel for pixel: even a one-pixel difference causes an error. The safest approach is to derive the mask from the source image (
original.size) so the dimensions align automatically. - The mask must be an RGBA PNG. RGB / L / P modes are rejected (a missing alpha channel returns
invalid_image_file). - Each mask file should be under 4 MB.
- The redraw region is determined by the alpha channel itself, not by visible black and white. Convert a black-and-white mask to alpha with
putalphabefore using it.
Programmatically generate a mask (transparent area = area to redraw):
from PIL import Image, ImageDraw
# Method 1: draw a transparent rectangle for the redraw area at the source-image size
mask = Image.new("RGBA", original.size, (255, 255, 255, 255)) # opaque = preserve
ImageDraw.Draw(mask).rectangle((300, 250, 750, 800), fill=(0, 0, 0, 0)) # transparent = redraw
mask.save("mask.png")
# Method 2: convert an existing black-and-white mask to alpha (black 0 -> redraw, white 255 -> preserve)
bw = Image.open("mask_bw.png").convert("L")
rgba = Image.new("RGBA", bw.size, (255, 255, 255, 255))
rgba.putalpha(bw)
rgba.save("mask.png")Describe the full image in the prompt
The gpt-image mask provides prompt-guided editing through full-image regeneration, rather than hard pixel compositing like DALL·E 2. The prompt should therefore not describe only the local area to redraw. Describe the desired complete image and explicitly state what must remain unchanged:
Modify only the transparent area of the mask and replace the person's top with a solid-red, crew-neck cotton T-shirt;
keep the person's face, hairstyle, body pose, and background unchanged.The mask is not an absolute pixel-level crop: because the whole image is regenerated, unmasked areas may also change slightly (for example, shadows, lighting, reflections, or background-edge transitions). If the business requirement is byte-for-byte preservation of unmasked pixels, composite the original back onto unmasked areas after receiving the result (Image.composite + feathered edges).
Common pitfalls: 1) inverting the mask (the easiest mistake; inspect alpha, not color); 2) a one-pixel dimension mismatch with the source image, which causes an error—use NEAREST resampling when resizing; 3) lossy re-saving by an image tool, which can damage the alpha channel—re-export consistently with .convert("RGBA").save(...).
Output format and count
output_format(defaultpng, optionspng/jpeg/webp) is effective only on the edits endpoint and specifies the encoding format of returned images.n(number of generated images) is sent only on the edits endpoint whenn > 1; when omitted or set to 1, one image is returned. Text-to-image does not supportnand always returns one image.
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-F "model=gpt-image-2" \
-F "image=@product.png" \
-F "prompt=Replace the background with a pure-white e-commerce hero-image background while preserving the product details" \
-F "size=1024x1024" \
-F "output_format=webp"Input-image compression (edits only)
For heavy multi-image fusion edits, enable lossy compression of input reference images with the x-input-image-compress: true request header. This can significantly reduce upload and storage size, with nearly imperceptible quality loss.
- Enable it with:
x-input-image-compress: true(exact match fortrue, case-insensitive). - Scope: applies only to reference images uploaded to edits; it takes effect only for images larger than 200 KB, while smaller images are forwarded unchanged.
- Encoding: sharp (libvips) lossy re-encoding at q85 while preserving the original format—JPEG → mozjpeg q85; PNG → lossy palette (libimagequant) q85 + maximum compression level; WebP → q85.
gif/svg/ unknown formats are forwarded unchanged. - Never increases size: if re-encoding produces a larger file, the original is retained.
- Best effort: if sharp is unavailable or encoding fails, the image is forwarded unchanged and the request itself is not affected.
curl "https://ai.inf.space/v1/images/edits" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "x-input-image-compress: true" \
-F "model=gpt-image-2" \
-F "image[]=@bag.png" \
-F "image[]=@scarf.png" \
-F "image[]=@model.png" \
-F "prompt=Have the model in image 3 carry the handbag from image 1 and wear the silk scarf from image 2, with an overall street-style look" \
-F "size=1024x1536"x-input-image-compress compresses the input image, whereas OpenAI's output_compression compresses the output image. They are different features, and this gateway currently does not support output_compression.
Parameters
The table below lists the parameters this gateway actually forwards or applies. Unlisted OpenAI parameters are ignored; see “OpenAI compatibility” below.
| Parameter | Type | Applicable interface | Required | Description |
|---|---|---|---|---|
model | string | General | Yes | Fixed at gpt-image-2 |
prompt | string | General | Yes | Generation or editing instruction; Chinese is supported natively |
size | string | General | No | Target size; see the size details below |
quality | string | General | No | Defaults to auto (the model selects quality automatically when omitted); options are auto / low / medium / high, affecting quality and billing tier (auto is billed at the high-tier baseline) |
aspectRatio | string | Text-to-image | No | Gateway extension, such as "3:4", automatically aligned to a supported widthxheight at the selected size tier |
image[] | file | Editing | Yes | Reference image; repeat the field for multiple uploads, up to 16 images, PNG / JPEG / WebP; single-image editing may also use one image field |
mask | file | Editing | No | Alpha PNG; transparent areas are redrawn and it applies to the first image; multipart only, forwarded unchanged |
output_format | string | Editing | No | Defaults to png, options are png / jpeg / webp; effective only on edits |
n | integer | Editing | No | Number of generated images; sent only on edits when n > 1, otherwise one image is returned |
The text-to-image endpoint (JSON body) accepts model / prompt / quality / size, plus the aspectRatio extension. The editing endpoint (multipart) accepts image / image[] / model / prompt / size / quality, plus output_format and n. Neither request type may select a provider.
Size details
size has two uses:
- Quick experimentation: send
1K/2K/4K, and sendaspectRatiofor text-to-image. - Specify the request canvas: send a
widthxheightvalue from the table. These are the recommended specifications;aspectRatiois not also required.
The table below shows the recommended sizes. Explicit sizes outside the table are aligned by aspect ratio to the nearest supported specification; use the returned image pixels as the final result.
| Aspect ratio | 1K | 2K | 4K |
|---|---|---|---|
| 1:1 | 1280x1280 | 2048x2048 | 2880x2880 |
| 16:9 | 1280x720 | 2048x1152 | 3840x2160 |
| 9:16 | 720x1280 | 1152x2048 | 2160x3840 |
| 4:3 | 1280x960 | 2048x1536 | 3312x2480 |
| 3:4 | 960x1280 | 1536x2048 | 2480x3312 |
| 3:2 | 1280x848 | 2048x1360 | 3520x2336 |
| 2:3 | 848x1280 | 1360x2048 | 2336x3520 |
| 5:4 | 1280x1024 | 2048x1632 | 3216x2560 |
| 4:5 | 1024x1280 | 1632x2048 | 2560x3216 |
| 21:9 | 1280x544 | 2048x864 | 3840x1632 |
Explicit dimensions select the aspect ratio and tier, but the final returned pixels may vary slightly. When a fixed delivery size is required, use a value from the table and read the actual returned image pixels after generation. quality affects quality, latency, and billing, but does not change the requested aspect ratio.
Use a lowercase half-width x in size strings (for example, 1728x2304), not an uppercase X or full-width ×. For general semantics of advanced size and quality options, see the OpenAI Image Generation guide.
OpenAI compatibility
This interface is compatible with the OpenAI Images API. When migrating from OpenAI, note that the following parameters are not currently forwarded or supported by this gateway and are silently ignored when set:
output_compression: compresses the output image—unsupported by this gateway. To compress, usex-input-image-compresson edits to compress input reference images (a different use case; see above).background(opaque/transparent/auto): unsupported; gpt-image-2 outputs an opaque background by default.output_format: unsupported on the text-to-image endpoint (PNG is always returned); effective only on edits.n: unsupported on the text-to-image endpoint (always one image); effective only on edits whenn > 1.- Caller-facing
stream/partial_images: unsupported; callers always receive one complete JSON response (see “Response” below).
Response
The response is always one complete JSON response; caller-facing streaming is not available.
Each image in data[] is returned as b64_json (raw base64) or url (a serve URL); usage provides usage information.
{
"created": 1717488000,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"usage": {
"input_tokens": 256,
"output_tokens": 1568,
"total_tokens": 1824,
"generated_images": 1
}
}b64_jsonis a raw base64 string. Before saving it or displaying it in a frontend, prepend thedata:image/png;base64,prefix yourself.urlis a time-limited serve link; copy the image to your own storage promptly.usagecontainsinput_tokens(when reported),output_tokens,total_tokens, andgenerated_images.
Asynchronous Jobs API (/api/jobs)
For long-running generation such as 4K, multi-image fusion, or local redrawing, use asynchronous jobs: submit once to receive a job ID, then poll for the result so long-lived connections are not interrupted by releases or timeouts.
Asynchronous and synchronous requests support the same generation parameters. The asynchronous endpoint accepts the same generation parameters as synchronous /v1/images/* endpoints; parameters unsupported synchronously (such as output_compression / background) are also unsupported asynchronously. This asynchronous protocol is shared by gpt-image-2 and Gemini (Nano Banana): submission, polling, and cancellation endpoints and response structures are identical; only model changes.
Full parameter set
In addition to model / prompt / size / aspectRatio, asynchronous submission supports the following parameters, consistent with synchronous requests:
| Parameter | Applicable interface | Description |
|---|---|---|
n | Editing | Number of generated images; when n > 1, multiple images are returned, outputs contains multiple entries, and outputs_count reports the actual count |
mask | Editing | Alpha PNG for local redrawing, applied to the first reference image; upload a file with multipart, or supply a public URL, data URL, or base64 with JSON. The alpha channel is preserved |
output_format | Editing | Encoding format for returned images; default png, options png / jpeg / webp |
quality | General | auto / low / medium / high, affecting quality and billing tier |
response_format | General | Accepted for synchronous-interface alignment; asynchronous results are always downloadable URLs in outputs |
media_resolution | General | Effective only for Gemini models; controls media input resolution |
n / output_format / mask have exactly the same semantics as the synchronous edits endpoint (see “Image-to-image and multi-image editing” and “Local editing (mask)” above). These parameters were previously discarded by asynchronous jobs and are now supported—async == sync.
Submission
POST https://ai.inf.space/api/jobs accepts two request-body formats:
application/json: text-to-image and edits whose references are already public URLs, data URLs, or base64. The OpenAI-shaped single-image field isimage; useimagesfor multiple references. The compatibility fieldinput_imagesalso works, but new integrations should useimage/images.multipart/form-data: local file uploads, especially local redrawing that uploads a PNG mask.
For JSON, the service downloads an http(s) image URL while submitting the job. The URL must be publicly reachable. Private, loopback, and metadata addresses are rejected. Replace IMAGE_URL with your own public image URL.
# Text-to-image (OpenAI shape): multiple images + specified output format
curl "https://ai.inf.space/api/jobs" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "gpt-image-2", "prompt": "A cyberpunk city at night", "size": "4K", "aspectRatio": "16:9" }'
# gpt-image-2: non-multipart image-URL edit (OpenAI shape)
export IMAGE_URL='https://example.com/public-source.png'
curl "https://ai.inf.space/api/jobs" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"model\":\"gpt-image-2\",\"prompt\":\"Turn the reference image into a clean blue technology poster. Preserve the subject silhouette on a white background.\",\"images\":[\"$IMAGE_URL\"],\"size\":\"1K\",\"aspectRatio\":\"1:1\",\"n\":1}"
# Local redrawing (mask): multipart, reference image + mask + WebP output
curl "https://ai.inf.space/api/jobs" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-F "model=gpt-image-2" \
-F "image=@room.png" \
-F "mask=@room-mask.png" \
-F "prompt=Replace the sofa with a fabric sofa while preserving the rest of the furnishings" \
-F "output_format=webp"
# Gemini Image Pro: same OpenAI-shaped JSON and image URL; only model differs
curl "https://ai.inf.space/api/jobs" \
-H "Authorization: Bearer $AI_TOS_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"model\":\"gemini-3-pro-image\",\"prompt\":\"Turn the reference image into a clean blue technology poster. Preserve the subject silhouette on a white background.\",\"images\":[\"$IMAGE_URL\"],\"size\":\"1K\",\"aspectRatio\":\"1:1\",\"n\":1}"The model selects the actual model: gpt-image-2 and gemini-3-pro-image are distinct routes. Setting model to gpt-image-2 cannot invoke Gemini. Gemini also accepts media_resolution: "high"; that parameter has no effect on gpt-image-2.
Submission returns a job object (id / status / progress, and so on). Save its id and poll until it reaches completed:
curl "https://ai.inf.space/api/jobs/<job-id>" \
-H "Authorization: Bearer $AI_TOS_API_KEY"On completed, outputs contains downloadable URLs rather than inline base64. On failed, inspect execution_error. Polling, cancellation, listing, and the seven-day retention period are identical to Nano Banana asynchronous jobs.
Pricing
Billing is per image based on image specification and quality tier; image tokens are not billed separately. Actual prices are shown in the console, with organization-specific prices taking precedence.
Latency and error handling
Image generation and editing latency varies significantly with quality and resolution. Set the client timeout to at least 600 seconds:
auto(default): the model selects quality automatically based on content; latency falls within the ranges below.low: approximately 10–40smedium: approximately 30–90shighor complex 2K / 4K editing: 3–5 minutes- Multi-image editing takes longer; reserve timeout according to the most complex scenario.
Integration guidance:
- Keep the API Key on the server and do not expose it in the browser.
- Complex, high-resolution edits may be slow. Limited retries are appropriate for transient network errors such as connection timeouts and 5xx network jitter.
- For system-busy errors such as “An error occurred while processing your request.”, tell the user to try again later instead of repeatedly retrying and extending the overall timeout.
- When
urlis returned, copy the image to your own storage promptly because the link is time-limited.
Image Generation and Editing
OpenAI-compatible `/v1/images/generations` text-to-image and `/v1/images/edits` image-to-image, multi-image fusion, and mask-based inpainting.
Nano Banana Image Generation and Editing
Inference Space Nano Banana (Gemini image generation) series text-to-image and image-to-image API, centered on the native Google generateContent protocol, compatible with OpenAI Images, with unified asynchronous jobs and per-image billing.