Image Generation API

The image generation and editing API is compatible with the OpenAI Images protocol. It currently provides gpt-image-2, supporting both text-to-image and image-to-image. Billing is based on image count and quality tier, not tokens.

Two endpoints are available:

  • /v1/images/generations - Generate images (text-to-image; image-to-image when reference images are included)
  • /v1/images/edits - Edit images (image-to-image with reference images), compatible with OpenAI native edits usage

Both endpoints have the same capability and billing. With reference images, the request is image-to-image; without reference images, it is text-to-image.


Endpoint and Authentication

POST https://jp.icodeeasy.cc/v1/images/generations
POST https://jp.icodeeasy.cc/v1/images/edits

Examples use the official access domain https://jp.icodeeasy.cc; keep the path unchanged.

Request headers:

  • Authorization: Bearer <your API Key> (required, starts with sk_)
  • Content-Type: application/json for JSON requests or multipart/form-data for file upload requests

POST /images/generations and POST /images/edits without the /v1 prefix are also accepted and behave the same.


Two Request Body Forms

The API supports two request body forms:

  1. JSON (Content-Type: application/json): put reference images in image_urls as URLs or base64 data URLs. This is the most common form.
  2. multipart/form-data: upload reference images through image[] files and put other parameters in form fields. This matches OpenAI native edits usage and is suitable for local file uploads.

Request Parameters

  • model (required): currently only gpt-image-2 is supported.
  • prompt (required): image description in English or Chinese. OpenAI performs content safety review; rejected content is not billed.
  • n (default 1): number of images. Billing accumulates by image count.
  • size (default 1:1): output aspect ratio. See below. auto is treated as 1:1; pixel strings such as 1536x1024 are also accepted.
  • resolution (default 1k): resolution tier, 1k or 2k.
  • quality (billing only): low, medium, high, or auto. It does not affect actual output and only decides billing price. Missing value defaults to medium.
  • image_urls / image_input (optional, JSON): reference images for image-to-image, up to 16 images. Items may be public https://... URLs or data:image/...;base64,...; mixed values are allowed. The two fields are aliases.
  • image[] (optional, multipart): reference image files for image-to-image. Multiple files are allowed and are equivalent to file upload form of image_urls.

Reference image note: URLs must use https:// (http is rejected); base64 must be a valid data:image/*;base64, value.


Supported Ratios and Resolution

Supported size ratios: 1:1 / 3:2 / 2:3 / 4:3 / 3:4 / 5:4 / 4:5 / 16:9 / 9:16 / 2:1 / 1:2 / 21:9 / 9:21 / auto.

Both 1k and 2k support all ratios.


Sync / Async Modes

Default sync mode: the request waits until image generation completes and returns OpenAI-compatible data[].url.

Async mode: add ?async=1 to the URL (true and yes are also accepted). The API returns task_id immediately, and you poll for the result. Use this when you do not want to hold a long connection, need progress handling, or submit batches.

Default sync?async=1 async
Return timingWaits tens of seconds until image is readyReturns immediately (< 1 second)
Status code200202
Response body{"created":...,"data":[{"url":"..."}],"id":"..."}{"status":"pending","task_id":"..."}
How to get imageReturned in one responsePoll GET /v1/images/tasks/{task_id}

Request Examples

Minimal text-to-image, sync

curl -X POST https://jp.icodeeasy.cc/v1/images/generations \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "an orange cat sitting on a windowsill watching the sunset, watercolor style"
  }'

Specify ratio and 2K

curl -X POST https://jp.icodeeasy.cc/v1/images/generations \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a corgi astronaut on the moon, cinematic",
    "size": "16:9",
    "resolution": "2k",
    "quality": "medium"
  }'

Image-to-image using image URL (JSON)

curl -X POST https://jp.icodeeasy.cc/v1/images/edits \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "make this person 70 years old",
    "size": "1536x1024",
    "image_urls": ["https://example.com/photo.png"]
  }'

Image-to-image uploading a local file (multipart)

curl -X POST https://jp.icodeeasy.cc/v1/images/edits \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -F "model=gpt-image-2" \
  -F "prompt=make this person 70 years old" \
  -F "size=1536x1024" \
  -F "image[]=@/path/to/photo.png"

Image-to-image with multiple references (URL + base64 mixed)

curl -X POST https://jp.icodeeasy.cc/v1/images/edits \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "merge these two photos into a poster",
    "size": "4:3",
    "resolution": "2k",
    "image_urls": [
      "https://example.com/photo-a.jpg",
      "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
    ]
  }'

Async submit + polling

# 1) Submit and get task_id immediately
curl -X POST "https://jp.icodeeasy.cc/v1/images/edits?async=1" \
  -H "Authorization: Bearer sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "make this person 70 years old",
    "image_urls": ["https://example.com/photo.png"]
  }'
# -> {"status":"pending","task_id":"d142c93a-..."}

# 2) Poll until completed
curl "https://jp.icodeeasy.cc/v1/images/tasks/d142c93a-..." \
  -H "Authorization: Bearer sk_xxxxxxxx"
# -> {"status":"completed","result_url":"https://...png","cost":0.2,...}

Response Structure

Sync success (HTTP 200, OpenAI Images compatible):

{
  "id": "3e0c77bb-9cbd-4c44-9549-bff1b4060623",
  "created": 1781599773,
  "data": [
    {
      "url": "https://api.icodeeasy.cc/v1/images/files/gpt-image-2/20260616/3e0c77bb-...-1.png"
    }
  ]
}

Async submit (HTTP 202):

{ "status": "pending", "task_id": "d142c93a-de26-40c9-be62-0de840d10960" }

Async task query (GET /v1/images/tasks/{task_id}):

{
  "task_id": "d142c93a-de26-40c9-be62-0de840d10960",
  "status": "completed",
  "model": "gpt-image-2",
  "cost": 0.2,
  "result_url": "https://api.icodeeasy.cc/v1/images/files/gpt-image-2/20260616/d142c93a-...-1.png"
}
  • status: pending / completed / failed
  • data[].url / result_url: image URL, usable directly in <img src>
  • id / task_id: task ID for support troubleshooting

The API always returns URLs and does not support response_format: b64_json. Download the image yourself if you need bytes.


Image URL Behavior

data[].url looks like https://api.icodeeasy.cc/v1/images/files/gpt-image-2/YYYYMMDD/<id>-<seq>.png:

  • Open directly: GET returns 302 and redirects to the actual image URL
  • Force download: add ?download=1
  • Long-term availability: the link stays available long term
  • Access control: this path does not require API Key; the full link itself is the credential. Do not post generated result links publicly, because anyone with the full URL can download the image.

Sync Semantics and Timeout

In default sync mode, the request stays open until the image is ready:

  • Recommended client HTTP timeout: at least 200 seconds
  • One image usually takes 30 to 60 seconds; image-to-image, 2K, or multiple images may take longer
  • If you do not want to wait on a long connection, use async mode (?async=1) to get a task_id and poll later

Error Response

Error bodies use:

{
  "error": {
    "type": "server_error",
    "message": "...",
    "provider": "icodeeasy.cc"
  }
}

Common statuses:

  • 400 invalid_request_error: invalid parameters, unsupported ratio, more than 16 reference images, non-https reference URL, invalid base64, and similar issues
  • 401 authentication_error: missing or invalid API Key
  • 402 payment_required: insufficient balance or exhausted monthly quota
  • 429 rate_limit_error: rate limit exceeded
  • 5xx: service temporarily unavailable or generation failed; retry later

Failed requests are not billed and do not deduct balance.


Billing

Billing is fixed by image count x quality tier in CNY and is unrelated to tokens:

  • low: CNY 0.10 / image
  • medium / auto (default): CNY 0.20 / image
  • high: CNY 0.40 / image

quality decides the billing tier. Missing value uses medium. In Usage Details, the request is recorded as model = gpt-image-2, and cost_breakdown includes image_count, image_cost_rmb, and image_urls, so you can copy links or download images from history.


Differences from OpenAI Images API

  • Model: only gpt-image-2; no gpt-image-1 or dall-e-3
  • Endpoints: generations and edits have the same capability and switch automatically based on whether reference images exist
  • size: aspect ratios such as 16:9 are recommended; pixel strings are also accepted
  • resolution: new field not present in OpenAI Images API, 1k or 2k
  • quality: low, medium, high, or auto; billing only, different from OpenAI standard / hd
  • response_format: b64_json is not supported; URLs are always returned
  • Reference images: image_urls / image_input (JSON) or image[] (multipart), up to 16 images, URLs and base64 can be mixed
  • Async mode: OpenAI has no such mode; this API supports ?async=1, returns task_id, and polls /v1/images/tasks/{id} for result
  • Task ID: responses include id / task_id for troubleshooting