Editing images through the API, step by step
Editing is the same endpoint as generation, just a different model and an image in the request body. Walked through with real examples.
4 min · · Updated · изображения
Update, October 2026. Image generation through Zukko is temporarily unavailable. The current model list is on the Models page or at
GET https://api.zukko.pro/v1/models. Closest replacement: there is no direct replacement among the available models; for image analysis (vision), the Claude and GPT models work, e.g.claude-sonnet-5orgpt-5.6-sol.
Editing an image through the gateway uses the same endpoint as generating one from scratch — POST /v1/images/generations — just with a model from the edit lineup and the source image included in the request body. The difference between "generate" and "edit" lives in which model you pick, not in which endpoint you call.
Models for editing
From the image catalog, these handle editing:
nano-banana-2-edit-developer— text-prompt-driven editingnano-banana-2-reference-to-image-developer— generation guided by a reference image (style/composition transfer, not a precise edit)openai-gpt-image-2-editandopenai-gpt-image-1.5-edit— OpenAI-style editing, including mask support
All of them are billed per generated image, not by token — the price doesn't depend on prompt length or image complexity, only on the model and how many variants you request.
A basic edit request
curl https://api.zukko.pro/v1/images/generations \
-H "Authorization: Bearer fetch_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2-edit-developer",
"prompt": "Remove the background and replace it with solid white",
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"n": 1
}'The source image is passed as a data URL with base64 content in the image field. The response is the standard structure with a URL or base64 result, depending on what the model returns by default for that request type.
Editing with a mask (openai-gpt-image)
The openai-gpt-image lineup supports an explicit mask — transparent areas mark what to change:
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")
result = client.images.edit(
model="openai-gpt-image-2-edit",
image=open("product.png", "rb"),
mask=open("mask.png", "rb"),
prompt="Replace the background with a studio backdrop, soft gray-to-white gradient",
n=1,
size="1024x1024",
)
print(result.data[0].url)mask.png must match the source image's dimensions and carry an alpha channel: transparent pixels mark the area to edit, opaque pixels stay untouched. Without a mask, the model treats the prompt as an edit to the whole image.
Reference-to-image: style transfer
nano-banana-2-reference-to-image-developer takes a reference image and applies its characteristics — style, palette, composition — to a new image generated from a prompt. This isn't a targeted edit, it's generation guided by an example:
curl https://api.zukko.pro/v1/images/generations \
-H "Authorization: Bearer fetch_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2-reference-to-image-developer",
"prompt": "A sneaker on a white background with the same lighting style",
"reference_image": "data:image/png;base64,...",
"n": 2
}'n: 2 requests two variants in one call — billing is per generated image, so a batch of two variants costs the same as two separate calls.
Node.js: editing through the official SDK
import OpenAI from "openai";
import fs from "fs";
const client = new OpenAI({
baseURL: "https://api.zukko.pro/v1",
apiKey: "fetch_your_key",
});
const result = await client.images.edit({
model: "openai-gpt-image-1.5-edit",
image: fs.createReadStream("photo.png"),
prompt: "Add snow in the background",
n: 1,
});
console.log(result.data[0].url);Checking cost before a batch job
Since billing is per item rather than per token, for a batch job (editing 200 product cards, say) it's worth running one request first and checking the X-Zukko-Cost-Micros response header to budget the whole batch ahead of time:
curl -i https://api.zukko.pro/v1/images/generations \
-H "Authorization: Bearer fetch_your_key" \
-H "Content-Type: application/json" \
-d '{"model":"nano-banana-2-edit-developer","prompt":"test","image":"data:image/png;base64,..."}' \
| grep -i x-zukko-cost-microsMultiply the single-call price by the number of images in the batch to see whether the balance covers it — check the remaining balance at GET /v1/balance.
Idempotency on repeated generation
If a pipeline retries a request after a network error, regenerating the same image charges twice for what's effectively the same prompt result. An Idempotency-Key won't help here: idempotency and caching in Zukko only apply to POST /v1/chat/completions, /v1/messages and /v1/responses, not to /v1/images/generations. So limit generation retries on the pipeline side — store each task's result, for instance, and don't rerun a task once it has one.
Common mistakes
400 model_not_found on a model with "-developer" in the name — a typo in the suffix; these models are distinguished by their full id, including the -developer or -lite-* postfix, so cross-check the exact name via GET /v1/models.
The mask gets ignored — models without explicit mask support (like nano-banana-2-edit-developer) only read the text prompt and source image; a mask field in the request has no effect on them, masks only work with openai-gpt-image-*-edit.
402 mid-batch — balance is checked per individual call, not per batch; when processing a large set of images, some will finish editing before the balance runs out and the rest will fail.
The result doesn't resemble the reference — reference_image shapes style and composition, it doesn't guarantee an exact reproduction of the object; for a precise edit of a specific object, use image plus a mask, not a reference.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- opencode agents: setting up roles, models and toolsA custom agent in opencode is a role, a model and a set of permissions. A working config where a cheap model handles routine work and a stronger one edits code.
- OpenAI API Keys in the Open: Why You Should Not Use ThemWhere free keys on GitHub come from, why using them is dangerous for you and for the owner, and how to protect your own key from the same leak.
- GLM API Errors: Why the Request Fails and How to Fix ItA wrong model id, an overflowing 128K context, the key, the balance, limits: the typical causes of GLM API errors and a quick way to find yours.
- Plan mode in Claude Code: plan first, then edit the codeIn plan mode Claude Code reads your code and proposes a plan but edits nothing until you agree. How to enable it, use it and what it costs.