Choose a model, enter your prompt, and see the result.
HiAPI Blog
HiAPI
Generate it with HiAPI
gpt-image-2.5-sunburst@pro is the Pro route of the gpt-image-2.5-sunburst model on hiapi. This guide gets you from zero to a working request: what the model id actually is, the exact input fields it accepts, a runnable curl/Python example, and the production patterns (idempotency, callbacks, error handling) you'll want before this runs unattended.
Authorization: Bearer sk-<your key>.The one thing specific to this model: @pro is a route suffix, not a nickname. hiapi exposes some models with more than one calling mode, and gpt-image-2.5-sunburst is one of them — the plain model id and the @pro-suffixed id take different input fields and are billed on different pricing tiers. This guide is scoped to gpt-image-2.5-sunburst@pro specifically; using the bare gpt-image-2.5-sunburst id gets you a different mode with a different schema (see FAQ).
Every hiapi generation model — image, video, or audio — is called through the same unified endpoint: POST /v1/tasks. You submit model and input, get a taskId back immediately, and the generation runs asynchronously.
For gpt-image-2.5-sunburst@pro, input takes:
| Field | Type | Required | Notes |
|---|---|---|---|
prompt | string | yes | 1–32,000 characters |
image_urls | string[] | no | 1–16 public JPEG/PNG/WebP URLs; include this to do image-to-image instead of text-to-image (SVG unsupported) |
aspect_ratio | enum | no | e.g. 1:1, 16:9, 9:16, or explicit sizes like 1536x1024; defaults to 1:1 |
quality | enum | no | low / medium / high / xhigh / max / auto; defaults to medium — see the production note below before raising this |
background | enum | no | transparent, opaque, or auto; defaults to auto |
output_format | enum | no | png, jpeg, or webp; defaults to webp |
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sunburst-pro-demo-001" \
-d '{
"model": "gpt-image-2.5-sunburst@pro",
"input": {
"prompt": "A minimalist product photo of a ceramic pour-over coffee dripper on a light wood table, soft studio lighting",
"aspect_ratio": "1:1",
"quality": "medium",
"output_format": "webp"
}
}'
This returns a taskId immediately:
{ "code": 0, "message": "ok", "data": { "taskId": "task_xxxxxxxx" } }
Then poll for the result:
curl -s "https://api.hiapi.ai/v1/tasks/task_xxxxxxxx" \
-H "Authorization: Bearer sk-YOUR_API_KEY"
Once data.status is success, the image is at data.output[0].url. Download it immediately — the URL comes with an expireAt and isn't meant for permanent hotlinking.
import time
import requests
API_KEY = "sk-YOUR_API_KEY"
BASE = "https://api.hiapi.ai/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def submit_task():
payload = {
"model": "gpt-image-2.5-sunburst@pro",
"input": {
"prompt": "A minimalist product photo of a ceramic pour-over coffee dripper "
"on a light wood table, soft studio lighting",
"aspect_ratio": "1:1",
"quality": "medium",
"output_format": "webp",
},
}
r = requests.post(
f"{BASE}/tasks",
headers={**HEADERS, "Idempotency-Key": "sunburst-pro-demo-001"},
json=payload,
timeout=30,
)
r.raise_for_status()
return r.json()["data"]["taskId"]
def poll_task(task_id, timeout_s=180, interval_s=3):
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{BASE}/tasks/{task_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
if data["status"] == "success":
return data["output"][0]["url"]
if data["status"] == "fail":
raise RuntimeError(f"task failed: {data.get('error')}")
time.sleep(interval_s)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = submit_task()
image_url = poll_task(task_id)
print("image ready:", image_url)
Poll vs. callback. The loop above works fine for scripts and low-volume use. For anything server-side, prefer a callback instead of polling: add a callback object to the same request —
{
"model": "gpt-image-2.5-sunburst@pro",
"input": { "...": "..." },
"callback": { "url": "https://your-domain.com/hiapi/callback", "when": "final" }
}
callback.url must be HTTPS, and when: "final" (currently the only supported value) notifies you once on both success and failure — no polling loop, no wasted requests. hiapi may deliver a callback more than once, so dedupe on taskId on your end.
Idempotency. Add an Idempotency-Key header (any string up to 255 bytes, e.g. an order id) to POST /v1/tasks. If a network timeout makes your client retry the same submission, the platform returns the original taskId (with an Idempotent-Replay: true response header) instead of creating — and billing — a second task. The key is scoped to your account and expires after 24 hours; reusing it with a different request body returns a 422 IDEMPOTENCY_KEY_MISMATCH instead of silently creating a new task, so a mismatch is a signal to check your retry logic, not something to retry blindly.
Auth errors. A malformed or wrong API key fails fast with 401 and a permission_denied error code, before any task is created:
{
"error": {
"code": "permission_denied",
"message": "This API key is invalid. Check that it is correct or use another API key and try again.",
"type": "hiapi_error"
}
}
If you see this, the fix is almost always the key itself (wrong env var, stale key, missing sk- prefix) — not the request body. Treat it as non-retryable until the key is corrected.
On quality. quality defaults to medium and that's a reasonable default to ship with — raising it increases both cost and generation time, so only step up to high/xhigh/max after you've confirmed a given prompt still succeeds reliably at that tier in your own testing.
/v1/tasks contract (idempotency, callbacks, status codes) that every hiapi generation model shares.@pro) mode instead, this covers its separate resolution-based schema in detail.quality tier.Is gpt-image-2.5-sunburst@pro a different model from gpt-image-2.5-sunburst?
It's the same model family, different route. The bare gpt-image-2.5-sunburst id (and its /text-to-image mode) takes a resolution field (1K/2K/4K) and no quality or image_urls fields. @pro swaps that for quality tiers and adds optional image_urls, so it's the route to use when you want either quality-tier control or image-to-image in the same call.
Do I need a reference image?
No. Omit image_urls entirely for text-to-image. Include 1–16 public image URLs to condition the output on reference images instead.
Can I use this model without an API key?
No — every request requires a valid Authorization: Bearer header with a real hiapi API key from your account. There's no unauthenticated or key-free tier.
How much does this cost?
Pricing varies by quality tier and is kept current on the pricing page rather than duplicated here — check it before estimating cost at scale.
What if my callback never arrives?
Callback delivery isn't guaranteed to be instant, and hiapi may retry delivery (so dedupe by taskId). If you need a hard upper bound, keep a fallback poll of GET /v1/tasks/:id after a timeout rather than waiting on the callback indefinitely.
Why did I get a fail status instead of an error at submission time?
Submission (200/taskId returned) only means the request was accepted — generation itself can still fail asynchronously. Check data.status after polling or via callback, and inspect data.error for the reason before resubmitting.