Edit Image
Edit existing images with a natural-language instruction and one or more reference images.
Image editing applies a text instruction to one or more reference images while preserving the original structure. Like generation, it is synchronous by default and returns the edited image URL — and like generation, supplying a delivery target switches it to the asynchronous 202 contract. See Async Image Generation.
POST /v1/images/edit
Edit an image using a text instruction and reference image URL(s).
Auth: API Key
| Parameter | Type | Required | Description |
|---|---|---|---|
instruction |
string |
Yes | What to change, in natural language. Required. Maximum 4000 characters. |
image_urls |
string[] |
Yes | URLs of images to edit. Required — between 1 and 5 images. |
model |
string |
No | Model id. Defaults to gemini-3.1-flash-image-preview. |
size |
string |
No | Output quality: 1K, 2K, or 4K. Optional; the API uses 1K when omitted. |
callback_url |
string |
No | Public HTTPS URL to POST the result to. Supplying this returns 202 instead of 200. Maximum 2048 characters; private and loopback addresses are rejected. |
webhook |
object |
No | Delivery target as {"id": "…"} (a webhook registered in the console) or {"url": "…"} (one-off), with an optional events array. Also returns 202. |
idempotency_key |
string |
No | Body-level twin of the Idempotency-Key header. The header wins if both are sent. |
| Header | Type | Required | Description |
|---|---|---|---|
Idempotency-Key |
string |
No | Deduplicate retried requests. If a request with the same key was already completed, the original response is returned without re-billing credits. 8–128 URL-safe characters. |
Response — 200, synchronous (no delivery target)
{
"id": "img_def456abc123",
"url": "https://cdn.picxstudio.com/edited/def456.png",
"model": "gemini-3.1-flash-image-preview",
"size": "2K",
"aspect_ratio": null,
"credits_used": 35,
"created_at": "2026-06-17T20:00:00Z"
}
Response — 202, asynchronous (callback_url or webhook supplied)
{
"id": "b68b2362-4bcc-48ff-b5cd-fbbd2ca34dd8",
"status": "pending",
"type": "image",
"model": "gemini-3.1-flash-image-preview",
"poll_url": "/v1/generations/b68b2362-4bcc-48ff-b5cd-fbbd2ca34dd8",
"events_url": "/v1/generations/b68b2362-4bcc-48ff-b5cd-fbbd2ca34dd8/events",
"webhook": {
"mode": "inline",
"id": null,
"url": "https://your-server.com/hooks/picx",
"events": ["generation.completed", "generation.failed"]
}
}
Edits submitted this way arrive as a generation.completed event with data.type of "image", exactly like a generation — the delivery payload does not distinguish edit from generate, so correlate on the id you were given.
Edit an image
JavaScript SDK
npm install picx-ai
import { PicX } from "picx-ai";
const picx = new PicX(process.env.PICX_API_KEY);
const edited = await picx.images.edit({
instruction: "make the colors more vibrant and add a subtle glow effect",
image_urls: ["https://cdn.picxstudio.com/api/generated/image_abc123.png"],
model: "gemini-3.1-flash-image-preview",
size: "1K",
});
console.log(edited.url);
console.log(edited.credits_used);
Python SDK
pip install picx-ai
import os
from picx import PicX
picx = PicX(os.environ["PICX_API_KEY"])
edited = picx.images.edit(
instruction="make the colors more vibrant and add a subtle glow effect",
image_urls=["https://cdn.picxstudio.com/api/generated/image_abc123.png"],
model="gemini-3.1-flash-image-preview",
size="1K",
)
print(edited.url)
print(edited.credits_used)
curl
curl -X POST https://api.picxstudio.com/v1/images/edit \
-H "Authorization: Bearer pxsk_your_key" \
-H "Content-Type: application/json" \
-d '{"instruction":"make the colors more vibrant and add a subtle glow effect","image_urls":["https://cdn.picxstudio.com/api/generated/image_abc123.png"],"model":"gemini-3.1-flash-image-preview","size":"1K"}'
Multiple reference images
Pass several URLs to composite or use additional references:
const composite = await picx.images.edit({
instruction: "place the product from the second image onto the background of the first",
image_urls: [
"https://example.com/background.jpg",
"https://example.com/product.png",
],
size: "2K",
});
composite = picx.images.edit(
instruction="place the product from the second image onto the background of the first",
image_urls=[
"https://example.com/background.jpg",
"https://example.com/product.png",
],
size="2K",
)
image_urlsaccepts 1–5 URLs. More than five is rejected with a validation error before the request is sent, so you fail fast instead of burning a round trip.
Be explicit with verbs like add, remove, change, or replace. Clear, well-lit reference images produce the best edits.
FAQ
How many reference images can I edit with in one request?
Between 1 and 5. Passing more than five is rejected with a validation error before the request is sent, so you fail fast instead of burning a round trip.
Can I composite two images together, not just edit one?
Yes — pass multiple image_urls and describe the composition in the instruction, e.g. placing a product from one image onto the background of another. See "Multiple reference images" above.
Does editing preserve the original image's structure?
Yes — the instruction is applied while preserving the original structure, rather than regenerating the image from scratch.
Is edit-image synchronous, like generate-image?
Yes. It waits for the edit and returns the edited image's hosted URL directly in the response — there's no job to poll.
How do I avoid double-billing on a retried request?
Send an Idempotency-Key header, exactly as with image generation — a repeated request with the same key returns the original response without re-billing credits.