Skip to content

GPT Image

Generate and edit images with GPT Image: parameters, responses, and caveats.

ItemValue
Base URLhttps://api.hop-base.com/v1
Generate imagesPOST /v1/images/generations
Edit imagesPOST /v1/images/edits
Query async tasksGET /v1/images/tasks?task_id=…
Key groupGPT Image (all models)

Requests are synchronous by default and return Base64 images; add Prefer: respond-async to run an async task. Keys from chat groups get 404 for gpt-image-*.

Available models

ModelModel IDquality tiersOfficial price
GPT Image 2.5 Flaregpt-image-2.5-flarelow / medium / high / xhigh / max$5 / $30/ 1M tokens
GPT Image 2.5 Sunburstgpt-image-2.5-sunburstlow / medium / high / xhigh / max$5 / $30/ 1M tokens
GPT Image 2gpt-image-2low / medium / high$5 / $30/ 1M tokens

Which to pick: Flare is the everyday default; Sunburst has higher fidelity and is slower than Flare at the same settings; gpt-image-2 is general-purpose, and its ID is gpt-image-2, not gpt-image-2.0. Reference timings for one 1024x1024 image: about 14 seconds at low on either 2.5 model; at high, Flare takes about 19 seconds and Sunburst about 37.

Request parameters

Generate

POST /v1/images/generations with a JSON body.

ParameterRequiredType and limitsDefaultNotes
modelRequiredstring—One of the three IDs above
promptRequiredstring, ≤ 32,000 characters—Must be non-empty after trimming
sizeOptionalauto or WIDTHxHEIGHT—Rules below the table
qualityOptionalauto / low / medium / high—2.5 adds xhigh / max
nOptionalinteger, 1–101Some groups accept only 1
backgroundOptionalauto / opaque / transparent—Transparent needs png / webp
output_formatOptionalpng / jpeg / webppngFormat of the decoded image
output_compressionOptionalinteger, 0–100100jpeg / webp only
moderationOptionalauto / low—Does not turn off safety checks
userOptionalstring—End-user identifier
streamOptionalbooleanfalsetrue switches to Images SSE
response_formatOptionalstring—Omit it
input_fidelityOptionallow / high—Compatibility field; omit it

For size, WIDTHxHEIGHT sides must be multiples of 16, each side ≤ 3840, aspect ratio ≤ 3:1, and total pixels 655,360–8,294,400. The 1K / 2K / 4K shorthands are not accepted; an invalid size returns 400 before generation and is not billed.

Higher quality tiers emit more output tokens and cost more. GPT Image always returns b64_json whatever response_format says; user is not a HopBase account ID and does not change who is billed.

Edit

POST /v1/images/edits accepts every parameter above, plus references and a mask. Prefer multipart/form-data for local files; JSON with URL / Data URL references also works.

ParameterRequiredType and limitsDefaultNotes
imageRequired1–16 images—Multipart: image or repeated image[]
maskOptionalPNG with an alpha channel—Transparent pixels mark the edit area

JSON image can be a URL / Data URL string, a string array, or {"url": …} objects. images is not read, and bare base64 or file_id is not accepted.

A remote URL must be ≤ 25 MiB with an image/* Content-Type, and must not point to an internal address; it may be compressed to 4 MiB before forwarding. The whole request body is capped at 60 MB; larger bodies return 413.

Async

Add the HTTP header Prefer: respond-async to a generation or edit request; the body stays the same. It is a header, not a JSON parameter.

Async tasks keep only model, prompt, n, size, quality, background, output_format, input_fidelity, and edit images / mask; other fields are dropped.

Response

Sync

FieldTypeNotes
createdintegerUnix seconds
data[].b64_jsonstringBase64 image; decode and save in the output_format format
usage.input_tokensintegerInput tokens (may be returned)
usage.output_tokensintegerOutput tokens (may be returned)
usage.total_tokensintegerTotal (may be returned)
errorobjectOn failure: message, type, code
{
  "created": 1760000000,
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAA..."
    }
  ],
  "usage": {
    "input_tokens": 42,
    "output_tokens": 1760,
    "total_tokens": 1802
  }
}
Generations over 40 seconds: the status stays 200 - check the error field.

After about 40 seconds, the server returns HTTP 200 and keeps writing whitespace at the start of the body to hold the connection; the full JSON follows later. From then on the status stays 200 even if generation fails, so check the body for error and set the read timeout to at least 300 seconds.

Streaming (stream: true)

The response switches to Images SSE: while waiting, the stream sends keepalive comment lines starting with a colon, and the last data: event holds the complete Images JSON, followed by [DONE]. These are not OpenAI's native progressive-image events.

: hopbase-keepalive

data: {"created":1760000000,"data":[{"b64_json":"iVBORw0KGgoAAA..."}]}

data: [DONE]

Async tasks

Submitting returns 202 Accepted right away; the Location response header points to the same query URL:

{
  "object": "image.task",
  "task_id": "your-task-id",
  "status": "pending",
  "status_url": "/v1/images/tasks?task_id=your-task-id"
}

Query only with GET /v1/images/tasks?task_id=…; putting the task ID in the path is not supported. pending, processing, and retrying mean in progress; completed and failed are terminal.

FieldTypeNotes
task_idstringTask ID
statusstringTask status
result_contentstringWhen completed: Markdown, one line per image
errorstringOnly when failed: English reason, no code
usage.costnumberAmount actually deducted for this task
usage.currencystringLedger currency, currently CNY
usage.cost_cnynumberAmount in CNY, for reconciliation
usage.cost_usdnumberAmount in USD, for reconciliation
{
  "task_id": "your-task-id",
  "status": "completed",
  "result_content": "![image](/assets-runtime/2026/09/xxxxxxxxxxxx.png)",
  "usage": {
    "cost": 1.36,
    "currency": "CNY",
    "cost_cny": 1.36,
    "cost_usd": 0.2
  }
}

result_content holds relative paths; prepend https://api.hop-base.com to download. usage appears once the task is completed or failed, and only the key that created the task sees it.

Examples

Generate

curl https://api.hop-base.com/v1/images/generations \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-flare",
    "prompt": "A shiba inu under a cherry tree, Japanese watercolor",
    "size": "1024x1024",
    "quality": "medium",
    "output_format": "png"
  }' \
  | jq -r '.data[0].b64_json' | base64 --decode > result.png

The curl example needs jq installed.

Edit (multiple references + mask)

curl https://api.hop-base.com/v1/images/edits \
  -H "Authorization: Bearer sk-your-key" \
  -F "model=gpt-image-2.5-flare" \
  -F "prompt=Fill the masked area with a vase styled like the second image" \
  -F "image[][email protected]" \
  -F "image[][email protected]" \
  -F "[email protected]" \
  -F "size=1024x1024" \
  -F "quality=high" \
  -F "output_format=png"

For JSON, replace the files with URLs: "image": ["https://example.com/scene.png", "https://example.com/style.png"] and "mask": "https://example.com/mask.png".

Async

# 1. Submit and receive 202 + task_id
curl -i https://api.hop-base.com/v1/images/generations \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -H "Prefer: respond-async" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "A cinematic futuristic city at night",
    "size": "2048x2048"
  }'

# 2. Poll with the task_id from the first response
curl "https://api.hop-base.com/v1/images/tasks?task_id=your-task-id" \
  -H "Authorization: Bearer sk-your-key"

Caveats

  • For 2K / 4K images, prefer async so long requests are not cut off by CDN timeouts.
  • Set the client read timeout for sync requests to at least 300 seconds.
  • size accepts only auto or WIDTHxHEIGHT; tier shorthands return 400.
  • xhigh / max exist only on the two 2.5 models.
  • background: "transparent" requires png or webp; transparency on gpt-image-2 is a preview capability.
  • The official streaming field partial_images (0–3) is not supported; omit it.
  • With official SDKs, keep stream at its default false.
  • The gateway resizes the mask to the first reference, and pixel-perfect preservation outside it is not guaranteed.
  • The result_content URL opens without a key, so do not share it publicly and download it to your own storage soon.

Common errors

Invalid parameters return 400 before generation and are not billed. Content-safety rejections also return 400 and are not billed, with error.code set to safety_rejected.

ErrorFix
size must be WIDTHxHEIGHT or auto and other size errorsFollow the size rules above
prompt must not be emptySend a non-empty prompt
n must be 1 for this model in the current groupSplit into separate requests
/v1/images/edits requires at least one imagePut references in image, not images
image download returned HTTP 404Use a public URL the server can fetch
Your request was rejected by the safety system.Rephrase the prompt or change the reference
Request body exceeds the size limit (60 MB) (413)Compress the images, or send URLs
HTTP 200 with error in the bodyFailed after keepalive started; act on error.message

Billing

Billed by token; higher quality emits more output tokens. Measured at 1024x1024: about 200 at low, 1,760 at high, 3,120 at xhigh, and 7,020 at max. For async tasks, the actual charge is usage.cost in the query result (cost_cny / cost_usd use a fixed 1 USD = 6.8 CNY), and a failed task usually shows 0.

Prices are on the model cards above and in the signed-in model catalog.

Next steps