本服务面向非中国大陆地区 · ZetaAPI.AI 的网站与控制台主要面向非中国大陆市场,注册与开通功能在你当前地区不可用。

Image API — generation & editing

Call gpt-image-2 to generate or edit images with ZetaAPI. OpenAI Images-compatible, with curl / Python / Node examples, multipart edits, output dimensions, billing and timeout notes.

Updated 2026-07-26

ZetaAPI’s image endpoints are fully OpenAI Images API-compatible — use your existing API key to generate or edit images with gpt-image-2, no SDK changes needed. To try it in the browser first, open the Image Playground in the console; this page covers calling it from code.

Base URL & auth

Image requests go to the dedicated image domain:

https://image.zetaapi.ai

Every request carries Authorization: Bearer sk-xxxxx (the same key you use for chat).

Why images get their own domain: image generation is a long, non-streaming request — waiting for the upstream render can take up to 240 seconds. The main domain api.zetaapi.ai sits behind a CDN that cuts the connection at roughly 120 seconds. You get a failure back, but the image was still generated upstream, and you are still billed for it. The image domain connects straight to origin and has no such limit — so do not auto-retry image requests against the main domain.

This domain serves only /v1/images/generations and /v1/images/edits. Everything else — including the Gemini high-resolution path below, which goes through /v1/chat/completions — still uses https://api.staging.cosmos-router.com.

If you received our earlier migration notice, it referred to direct.zetaapi.ai: that domain remains valid and is equivalent.

Checking that the domain is reachable

Any request to this domain outside the two endpoints above — including the root path / — is dropped without a response. curl reports Empty reply from server or HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR, not a 404. This is a deliberate security policy and does not mean the domain is down.

To confirm the domain is reachable, POST the endpoint itself (no key required, no quota consumed):

curl -i -X POST https://image.zetaapi.ai/v1/images/generations \
  -H "Content-Type: application/json" -d '{}'

A 401 Authorization Required response means DNS, TLS and the gateway are all fine — it is simply asking for your API key.

Endpoints

EndpointPurpose
POST /v1/images/generationsText-to-image
POST /v1/images/editsEdit (upload source image + optional mask, multipart)

Generate images

Parameters

ParamRequiredNotes
modelyesgpt-image-2
promptyesImage description
nno1–4 images, default 1
sizenoAccepted for OpenAI SDK compatibility but has no effect — see Output dimensions
response_formatnob64_json (default) or url

curl

curl https://image.zetaapi.ai/v1/images/generations \
  -H "Authorization: Bearer sk-xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a red panda coding at night, neon rim light, 16:9 cinematic banner",
    "n": 1
  }'

Python (openai SDK)

import base64
from openai import OpenAI

client = OpenAI(api_key="sk-xxxxx", base_url="https://image.zetaapi.ai/v1")

resp = client.images.generate(
    model="gpt-image-2",
    prompt="a red panda coding at night, neon rim light, 16:9 cinematic banner",
    n=1,
)

with open("out.png", "wb") as f:
    f.write(base64.b64decode(resp.data[0].b64_json))

Node.js (openai SDK)

import { writeFileSync } from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-xxxxx",
  baseURL: "https://image.zetaapi.ai/v1",
});

const resp = await client.images.generate({
  model: "gpt-image-2",
  prompt: "a red panda coding at night, neon rim light, 16:9 cinematic banner",
  n: 1,
});

writeFileSync("out.png", Buffer.from(resp.data[0].b64_json, "base64"));

Response

{
  "created": 1730000000,
  "data": [{ "b64_json": "iVBORw0KGgo..." }],
  "usage": { "input_tokens": 12, "output_tokens": 1024, "total_tokens": 1036 }
}

Returns b64_json (a base64-encoded PNG) by default. Pass "response_format": "url" to get an image URL instead.

Output dimensions

Control the aspect ratio from the prompt, not the size parameter.

gpt-image-2 renders every image at a fixed pixel budget of roughly 1.57 megapixels. You cannot raise it — asking for “4K” or “3840x2160” in the prompt does not produce more pixels. What you can control is the shape: describe the aspect ratio in the prompt and it is honoured precisely.

Ask for in the promptYou getRatio
(nothing) or “square”1254 × 12541:1
”16:9 cinematic banner”1672 × 94116:9
”9:16 vertical poster”941 × 16729:16
”21:9 ultra-wide”1915 × 82121:9
”3:1 panoramic banner”2172 × 7243:1
”1:3 tall vertical strip”736 × 2135~1:2.9

Supported range is 1:3 to 3:1. Common ratios are hit exactly (16:9 → 1672 × 941); near the limits you get the closest available size — asking for 1:3 measured ~1:2.9. Every ratio costs the same, since the pixel count is constant.

The size parameter is accepted so that the OpenAI SDKs keep working, but it is ignored — size: "1024x1536" with a neutral prompt still returns a square image. If you need an exact pixel size, generate at the closest ratio and resize locally.

Need genuinely higher resolution? The pixel cap is an upstream limit on gpt-image-2 that we cannot change — use Gemini 3 Pro Image instead, which renders up to 17 MP.

High resolution: Gemini 3 Pro Image

For work that needs real pixels — print, large banners, wallpapers — use gemini-3-pro-image-preview. Resolution is selectable and honoured exactly. The sizes below are measured without aspect_ratio — setting one changes the width/height while keeping the same pixel tier:

image_sizeOutputPixels
1K (default)1408 × 7681.1 MP
2K2816 × 15364.3 MP
4K5632 × 307217.3 MP

This model is not available on /v1/images/* — the upstream provider only exposes it through chat completions. Two things differ from the Images API:

  1. Call POST /v1/chat/completions and pass the resolution in extra_body.
  2. The image comes back as a Markdown data-URI inside choices[0].message.content, not as data[0].b64_json.
curl https://api.staging.cosmos-router.com/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image-preview",
    "messages": [{"role": "user", "content": "Generate an image: a red panda coding at night, neon rim light"}],
    "extra_body": {"google": {"image_config": {"image_size": "4K"}}}
  }'
import base64, re
from openai import OpenAI

client = OpenAI(api_key="sk-xxxxx", base_url="https://api.staging.cosmos-router.com/v1")

resp = client.chat.completions.create(
    model="gemini-3-pro-image-preview",
    messages=[{"role": "user", "content": "Generate an image: a red panda coding at night"}],
    # The SDK merges extra_body into the top level, but the gateway reads a
    # top-level `extra_body` field — so it must be nested once more here.
    # Omitting the extra level silently falls back to 1K.
    extra_body={"extra_body": {"google": {"image_config": {"image_size": "4K"}}}},
)

# content looks like: "Image generated successfully.\n![image](data:image/png;base64,iVBOR...)"
content = resp.choices[0].message.content
m = re.search(r"base64,([A-Za-z0-9+/=]+)", content or "")
if not m:
    raise RuntimeError(f"no image in response (refused or plain text): {content!r}")
with open("out.png", "wb") as f:
    f.write(base64.b64decode(m.group(1)))

Notes:

4K output in the console

No code required: open the console → image Playground and set Resolution to “4K (long edge >= 3840)”. Both the generate and edit tabs support it.

This is a console feature. Calling gpt-image-2 through the API still returns the ~1.57 MP output described above.

Edit images

Edits use multipart/form-data: upload the source image (required) plus an optional mask (transparent areas are repainted):

curl https://image.zetaapi.ai/v1/images/edits \
  -H "Authorization: Bearer sk-xxxxx" \
  -F model=gpt-image-2 \
  -F 'prompt=make the center square blue' \
  -F image=@source.png \
  -F mask=@mask.png

Generating images in Codex

Codex ships with a built-in image tool, image_gen, but it does not work on this platform — that is not a configuration problem, so there is no switch to look for.

image_gen is a hosted tool that Codex hard-codes to the ChatGPT login. In any session authenticated with an API key plus a custom base_url — which is what cc-switch and similar tools set up — the tool never appears in the model’s tool list at all, and [features] image_generation = true has no effect on such a session. OpenAI is tracking this in issue #24465; there is no workaround today.

We ship a Codex plugin that fills the gap:

codex plugin marketplace add Hermerz/zetaapi-codex-plugins
codex plugin add zeta-imagegen@zetaapi
export ZETAAPI_KEY=sk-your-key

Once installed, just ask Codex in plain language — “draw a cyberpunk city at night, 16:9”. Editing works too (“make this one snowy” plus a local file path).

The plugin only accepts ZETAAPI_KEY, or reuses the key of the active model_provider when its base_url points at this platform. It never reads credentials belonging to your other providers — a gateway key is indistinguishable in shape from an OpenAI or Anthropic key, so guessing would send your real third-party credentials to the wrong place. Ownership is therefore decided by base_url, not by the key itself. Source is public: Hermerz/zetaapi-codex-plugins

Prefer not to install a plugin? Codex can run commands: wrap the curl above in a script and let Codex call it — same result.

Billing, latency & timeout

Error codes

Consistent with the other endpoints. Common ones:

HTTPMeaning
400Bad request (missing prompt, or the prompt was refused by content policy)
401Invalid or revoked key
402Insufficient balance
413Edit upload over 14MB
429Rate-limited — retry with exponential backoff

Full list in the API Reference.

More