API reference
Image editing
Parameters and examples for POST /v1/images/edits — upload source images with a prompt to change them, combine several images or repaint part of one with a mask. multipart/form-data, same format as the OpenAI image editing API. Requests are relayed as-is.
POST /v1/images/edits creates a new image from one or more source images and a prompt. Typical uses: swap the background, change text in the picture, repaint one area, or put a logo onto a product shot. Files are uploaded as multipart/form-data, in the same format as the OpenAI Images API. Requests are relayed to the model service in their original format; supported fields and values differ by model and follow that model's official documentation.
https://open.tutujin.com/v1/images/editsHeaders
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer sk-..., an API key from the console |
Content-Type | Yes | multipart/form-data. SDKs and curl -F set it with the boundary for you; do not write it by hand |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model name, e.g. gpt-image-1.5 |
image | file | Yes | Source image, usually PNG, JPEG or WEBP. GPT Image models accept several; name the form field image[] |
prompt | string | Yes | What to change, and what must stay the same |
mask | file | No | PNG mask. Transparent areas (alpha 0) are repainted; it must match the source size and applies to the first image |
n | integer | No | Number of images, default 1 |
size | string | No | Output size; allowed values vary by model |
quality | string | No | GPT Image models accept low, medium, high, auto |
response_format | string | No | url or b64_json; some models only support one of them |
Request example
This example puts a logo on a mug: mug.png is the product shot and logo.png the logo.
curl https://open.tutujin.com/v1/images/edits \
-H "Authorization: Bearer $TUTUJIN_API_KEY" \
-F model="gpt-image-1.5" \
-F "image[]=@mug.png" \
-F "image[]=@logo.png" \
-F prompt="Print the logo from the second image on the front of the mug; keep the mug's shape, color and lighting unchanged"import base64
import os
from openai import OpenAI
client = OpenAI(base_url="https://open.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"], timeout=300)
resp = client.images.edit(
model="gpt-image-1.5",
image=[open("mug.png", "rb"), open("logo.png", "rb")],
prompt="Print the logo from the second image on the front of the mug; keep the mug's shape, color and lighting unchanged",
)
img = resp.data[0]
if img.b64_json:
with open("mug-logo.png", "wb") as f:
f.write(base64.b64decode(img.b64_json))
else:
print(img.url) # temporary link: download and store it right awayimport fs from 'node:fs'
import OpenAI, { toFile } from 'openai'
const client = new OpenAI({ baseURL: 'https://open.tutujin.com/v1', apiKey: process.env.TUTUJIN_API_KEY, timeout: 300_000 })
const resp = await client.images.edit({
model: 'gpt-image-1.5',
image: [
await toFile(fs.createReadStream('mug.png'), 'mug.png', { type: 'image/png' }),
await toFile(fs.createReadStream('logo.png'), 'logo.png', { type: 'image/png' }),
],
prompt: "Print the logo from the second image on the front of the mug; keep the mug's shape, color and lighting unchanged",
})
const img = resp.data[0]
if (img.b64_json) fs.writeFileSync('mug-logo.png', Buffer.from(img.b64_json, 'base64'))
else console.log(img.url)Repaint part of an image with a mask
To change only part of the picture, also upload a PNG mask the same size as the source, with the area to repaint made transparent:
curl https://open.tutujin.com/v1/images/edits \
-H "Authorization: Bearer $TUTUJIN_API_KEY" \
-F model="gpt-image-1.5" \
-F "image[]=@room.png" \
-F mask=@mask.png \
-F prompt="Place a potted plant in the transparent area, matching the room's style and lighting"Response example
{
"created": 1794000000,
"data": [
{ "b64_json": "iVBORw0KGgo..." }
]
}| Field | Description |
|---|---|
data[].b64_json | Base64 image data |
data[].url | A temporary link, when the model returns links; it expires |
usage | Token-billed image models return input and output tokens; source images count as input |
Notes
- This endpoint is relayed as-is and has not been verified separately on this site. Models other than GPT Image may expect different field names or multi-image syntax, so confirm with a request or two first.
- File extensions must match the real format:
mug.pngmust really be a PNG, or you may get an error or a broken result. - Larger source images are slower and can exceed the request size limit (413). Scale images down to what you need before sending.
- Returned links are temporary; download the image and keep it in your own storage.
- Image editing takes a while, so set the client timeout to around 300 seconds. The Usage page in the console is the billing record.
Models that support this endpoint
| Model | Vendor | Cheapest group | Input ¥/1M | Output ¥/1M | Per request ¥ |
|---|---|---|---|---|---|
| nano-banana-pro | Standard | — | — | ¥0.4 | |
| flux-schnell | Flux | Standard | — | — | ¥0.02 |
| flux | Flux | Standard | — | — | ¥0.02 |
| flux-dev | Flux | Standard | — | — | ¥0.06 |
| gpt-4o-image | OpenAI | Standard | — | — | ¥0.1 |
| flux-pro | Flux | Standard | — | — | ¥0.1 |
| grok-imagine-image-2.0 | xAI | Standard | — | — | ¥0.12 |
| gpt-image-1.5 | OpenAI | Standard | — | — | ¥0.12 |
Prices in CNY, cheapest group for each model; updated Nov 12, 2026, 8:17 PM.
31 models support this endpoint; the table shows some of them. See them all in the model hub
Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.