Skip to content
kenari.

Image generation

kenari provides an image generation endpoint compatible with OpenAI Images. This endpoint only serves models marked as image models in the catalog. Calling it with a text model returns status 400.

POST /v1/images/generations

Send prompt and model, and the gateway returns an image as a URL or base64 data. Cost is deducted from the Rupiah balance per image.

FieldTypeRequiredDescription
modelstringyesImage model id from the catalog, for example gpt-image-2.
promptstringyesDescription of the requested image.
nintegernoNumber of images. Default 1.
sizestringnoImage size, for example "1024x1024". A hint, not a guarantee: see the note below.
backgroundstringno"transparent", "opaque", or "auto". "transparent" returns a PNG with a transparent background (alpha channel).
response_formatstringno"url" or "b64_json".

Models treat size differently. Some take it as given, some ignore it, and some understand only aspect ratios, so the size you send is mapped to the nearest ratio they support. Sending "1792x1024" to a ratio-based model returns a 16:9 image at whatever pixel count that model produces, not exactly 1792x1024. The shape always lands as close to the request as the model allows; the pixel count may differ. If exact pixel dimensions matter, check the returned image.

Billing is calculated per image: n multiplied by the model’s price per image, then deducted from the Rupiah balance. Requesting four images costs four times the price of one image. See Billing for balance and deduction details.

The response follows the OpenAI Images shape: a created field and a data array. Each data element contains url (when response_format is "url") or b64_json (when it is "b64_json").

{
"created": 1718700000,
"data": [
{ "url": "https://..." }
]
}

Image generation can take several minutes. While the job is running, the gateway keeps the connection open and sends a heartbeat every 20 seconds so proxies on the path do not close a connection they consider idle.

Terminal window
curl https://kenari.id/v1/images/generations \
-H "Authorization: Bearer kn-..." \
-H "Content-Type: application/json" \
-d '{"model":"gpt-image-2","prompt":"seekor panda merah sedang menulis kode","n":1,"size":"1024x1024"}'
from openai import OpenAI
client = OpenAI(
base_url="https://kenari.id/v1",
api_key="kn-...",
)
result = client.images.generate(
model="gpt-image-2",
prompt="seekor panda merah sedang menulis kode",
n=1,
size="1024x1024",
)
print(result.data[0].url)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://kenari.id/v1",
apiKey: "kn-...",
});
const result = await client.images.generate({
model: "gpt-image-2",
prompt: "seekor panda merah sedang menulis kode",
n: 1,
size: "1024x1024",
});
console.log(result.data[0].url);

POST /v1/images/edits

This endpoint edits an existing image: send one or more source images, a description of the requested change, and an image model from the catalog. Repeat the image (or image[]) field for each file, up to 16. A 17th file is rejected with 400. Unlike image generation, the request is multipart/form-data, not JSON, because the images are sent as files. Each file can be up to 25 MiB, and the whole body up to 32 MiB. If the model cannot use that many references, the request fails with 503 and every file stays on the request.

FieldTypeRequiredDescription
imagefileyesOne or more source images (PNG, JPEG, or WebP). Repeat the field, up to 16 files.
promptstringyesDescription of the requested edit.
modelstringyesImage model id from the catalog, for example gpt-image-2.
maskfilenoOne PNG mask. Transparent regions mark where the edit applies. Without a mask, the whole image is a candidate for editing.
nintegernoNumber of output images. Default 1. Independent of how many source files you send.
sizestringnoImage size, for example "1024x1024". A hint, not a guarantee: see the note below.
backgroundstringno"opaque" or "auto". "transparent" is not supported on edits yet and is rejected with a 400. Use generation for transparent backgrounds.
response_formatstringno"url" or "b64_json".

Billing and the response shape are identical to image generation above: n times the model’s per-image price, not per source file, deducted from the Rupiah balance, response {created, data:[...]}.

Terminal window
curl https://kenari.id/v1/images/edits \
-H "Authorization: Bearer kn-..." \
-F "image=@source.png" \
-F "image=@reference.png" \
-F "model=gpt-image-2" \
-F "prompt=change the sky to sunset, using the style of the second image" \
-F "n=1"
from openai import OpenAI
client = OpenAI(
base_url="https://kenari.id/v1",
api_key="kn-...",
)
result = client.images.edit(
model="gpt-image-2",
image=[open("source.png", "rb"), open("reference.png", "rb")],
prompt="change the sky to sunset, using the style of the second image",
n=1,
)
print(result.data[0].url)