Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use the Qwen Image 2.1 Turbo API: curl, Python, and a Tested Request

hiapiqwen-image-2.1-turbotutorialimage-generation

Qwen Image 2.1 Turbo (qwen-image-2.1-turbo) is the fast, low-price tier of Alibaba's 2.1 image family on hiapi. It takes a text prompt, optionally 0–10 reference images, and returns a 2048×2048 PNG. This guide gives you a request that runs, the exact input schema as the API enforces it, an edit call, and what we saw when we tested the "transparent PNG" claim.

You need a hiapi API key from the dashboard. Calls go through the unified async task API, so there is no synchronous image response.

Minimal request: text to image

curl -s -X POST https://www.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.1-turbo",
    "input": {
      "prompt": "Sticker-style illustration of a straw-hat shiba sitting on a surfboard, flat colors, bold outlines, coral orange and sea blue",
      "aspect_ratio": "1:1",
      "seed": 42
    }
  }'
# {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}

Then poll GET /v1/tasks/<taskId> until data.status is success and read data.output[0].url.

import os, time, requests

BASE = "https://www.hiapi.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}

def run(input_: dict) -> str:
    r = requests.post(f"{BASE}/v1/tasks", headers=HEADERS, timeout=30,
                      json={"model": "qwen-image-2.1-turbo", "input": input_})
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]          # note: taskId, not id

    while True:
        try:
            d = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        except requests.RequestException:
            time.sleep(3)                          # transient network error: keep polling the same id
            continue
        if d["status"] == "success":
            return d["output"][0]["url"]
        if d["status"] in ("fail", "failed"):
            raise RuntimeError(d)
        time.sleep(3)                              # pending / running / archiving

url = run({"prompt": "a straw-hat shiba on a surfboard, flat sticker style", "aspect_ratio": "1:1"})
open("out.png", "wb").write(requests.get(url, timeout=60).content)

Download the file right away. The output URL lives on temp.hiapi.ai and carries an expireAt timestamp (about seven days after creation in our run); store the bytes yourself if you need them longer.

Input schema (as the API enforces it)

We read these from validation errors returned by deliberately invalid requests, so they reflect the live endpoint rather than a doc paraphrase:

FieldRule
promptrequired string (the model page's form caps it at 4500 characters)
aspect_ratioone of 1:1, 16:9, 9:16, 4:3, 3:4
image_urlsarray of reference image URLs, 0–10 items; a bare string is rejected with image_urls must be an array
prompt_extendboolean, prompt optimization toggle
seedinteger, 0 to 2147483647

Two things differ from sibling Qwen models. There is no resolution field: sending one returns additional properties 'resolution' not allowed. Output is a fixed 2048×2048 canvas for 1:1, which we measured. And unknown fields in general are rejected, not ignored. A bad aspect_ratio returns HTTP 400 with error_code: INVALID_REQUEST and the allowed values in message.

Editing with reference images

Edit and restyle use the same model id. Pass the source image in image_urls and describe the change in the prompt:

curl -s -X POST https://www.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.1-turbo",
    "input": {
      "prompt": "Recolor the straw hat to deep purple and keep everything else",
      "image_urls": ["https://temp.hiapi.ai/.../source.png"],
      "aspect_ratio": "1:1",
      "seed": 42
    }
  }'

What we observed in real runs

We ran one text-to-image call and one edit call on 2026-10-24, both with seed: 42, aspect_ratio: "1:1".

  • Latency: text-to-image reached success about 29 seconds after creation (task created to completed timestamps); the edit took about 22 seconds. The status passes through archiving for a few polls before success, so don't treat a non-terminal status as an error. These are two samples, not a benchmark.
  • Output: both returned a 2048×2048 PNG, about 3.9 MB for the text-to-image result.
  • Edit behavior: we fed the first output back in and asked for a purple hat. The result kept the dog, pose, waves and layout, and shifted the hat band and ribbon toward purple; the straw body of the hat stayed mostly straw-colored. Expect instruction-following on the edit to be partial for colour changes on textured objects, and phrase prompts specifically ("recolor the hat band") rather than broadly.
  • Transparent background: the alpha channel was opaque. The model page advertises transparent-background PNG output, and we put "pure transparent background, keep only the subject and splash" in the prompt. The returned file was RGBA, but every pixel had alpha 255 (zero transparent pixels), and the corners were light grey-white (e.g. (241, 243, 248, 255)). Looking at the image, the model had painted a faint checkerboard-style backdrop into the pixels instead of leaving them transparent. The edit output behaved the same way (minimum alpha 241). So in our runs, a prompt alone did not give a cut-out you can drop onto a coloured page. This is a result for one prompt wording; we did not find a request field that toggles transparency (transparent is rejected as an unknown property). If you need a real alpha channel, plan a background-removal step, for example the 851-labs background remover guide, and verify with a pixel check like Image.open(f).getchannel("A").getextrema() before shipping.

Production notes

  • Callbacks over polling at volume: add "callback": {"url": "https://your.app/hook", "when": "final"} to the task body and treat the callback as a hint, then confirm with GET /v1/tasks/<taskId>.
  • Keep the taskId: if a poll fails with a network error, re-poll the same id rather than resubmitting. Resubmitting creates and bills a second task.
  • Pin seed when you want comparable outputs across prompt tweaks; treat it as best-effort, not a hard guarantee.
  • Validate before billing: schema errors (HTTP 400, INVALID_REQUEST) are returned at creation time, before any image is generated.

Which tier

The same family has Qwen Image 2.1 Pro, listed at a higher per-image price than Turbo on the pricing page. Both are described as supporting text-to-image, editing and 0–10 references; we only ran Turbo, so we make no claim about relative image quality. Turbo's case is the lower price and 8-step speed; if output quality is what matters for your assets, run the same prompt and seed on both and compare. For the newer Qwen 3.0 generation, see the Qwen Image 3.0 API guide and the Qwen Image 3.0 Pro guide.

FAQ

What is the model id? qwen-image-2.1-turbo, sent through POST /v1/tasks.

Can I choose the output resolution? Not in this schema: there is no resolution field. Choose an aspect_ratio from the five allowed values.

Does it support editing? Yes: pass 1–10 source images in image_urls with an instruction prompt. Colour edits on textured regions were only partly applied in our test.

Does it return a transparent PNG? In our test, no: the file had an RGBA mode but a fully opaque alpha channel with a painted backdrop. Verify alpha yourself and add background removal if you need true transparency.

How much does it cost? See the pricing page; at the time of writing it was the lower-priced of the two 2.1 tiers.

Generate it with HiAPI

Choose a model, enter your prompt, and see the result.

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Start generating