Qwen Image
Models
| Model | Output resolution | Notes |
|---|---|---|
qwen-image-3.0-pro | Common sizes such as 1024x1024 and 2048x2048 | Pro tier; the 2k tier costs more than 1k |
qwen-image-3.0 | Same | Standard tier; both tiers priced the same |
Availability and pricing differ by region. Check the model list for this endpoint before integrating — see the API catalog.
Both models serve text to image (T2I) and image to image / editing (I2I): no reference image means T2I, 1–3 reference images mean I2I. Images are returned synchronously — no polling.
The async task lane is not supported. This family is served only on the synchronous endpoints; a call to
/v1/content_generation/tasksis refused.
Two inbound lanes
One model, two spellings, identical capability. Pick whichever matches the code you already have:
| Lane | Path | Who it is for |
|---|---|---|
| OpenAI-compatible | POST /v1/images/generations | Apps already written against the OpenAI Images protocol or SDK — change base_url and model only |
| Bailian native | POST /api/v1/services/aigc/multimodal-generation/generation | Apps already using the Bailian DashScope SDK — change base_url only |
The two lanes spell
sizedifferently and neither accepts the other's spelling: the OpenAI-compatible lane uses the letterx(1024x1024), the Bailian native lane uses an asterisk (1024*1024). The wrong one returns400naming the separator it expects; it is not silently rewritten — mixing the two protocols should surface here rather than as a harder problem further down.
1. OpenAI-compatible lane
POST https://api.modelgo.ai/v1/images/generations
Text to image
curl https://api.modelgo.ai/v1/images/generations \
-H "Authorization: Bearer $MODELGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-image-3.0-pro",
"prompt": "A fluffy ginger cat on a sunlit windowsill, afternoon light, film grain",
"size": "1024x1024",
"n": 1
}'Image to image / editing
No multipart: the reference images go in the top-level image field.
curl https://api.modelgo.ai/v1/images/generations \
-H "Authorization: Bearer $MODELGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-image-3.0-pro",
"prompt": "Keep her facial features; change the outfit to a champagne silk shirt and a dark grey blazer",
"image": ["https://example-cdn.com/portrait.png"],
"size": "1024x1024",
"prompt_extend": true
}'Response
{
"created": 1788339600,
"data": [{"url": "https://dashscope-result-sz.oss-cn-shenzhen.aliyuncs.com/xxx.png?Expires=xxx"}],
"usage": {
"output_width": 1024, "output_height": 1024,
"input_image_count": 0, "input_image_type": "qima_input_1k",
"output_image_count": 1, "output_image_type": "qima_output_1k"
}
}- Images are PNG, and the link is valid for 24 hours — download promptly and do not persist the URL.
usagecarries image counts and tiers, not token usage: this family bills purely per image (see Billing).response_format: "b64_json"does not error but is ignored; the response still carries an image URL.
Using the OpenAI SDK
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MODELGO_API_KEY"],
base_url="https://api.modelgo.ai/v1",
timeout=600.0, # Generation is slow; use a generous timeout
)
resp = client.images.generate(
model="qwen-image-3.0-pro",
prompt="A fluffy ginger cat on a sunlit windowsill, film grain",
size="1024x1024",
n=1,
extra_body={"prompt_extend": True}, # extensions go through extra_body
)
print(resp.data[0].url)image / negative_prompt / seed / prompt_extend / prompt_extend_mode / enable_thinking / watermark are not OpenAI parameters: pass them via extra_body with the OpenAI SDK, or at the top level of the request body over plain HTTP.
2. Bailian native lane
POST https://api.modelgo.ai/api/v1/services/aigc/multimodal-generation/generation
Request and response are Bailian's own shapes in both directions — the gateway does not translate.
curl https://api.modelgo.ai/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $MODELGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-image-3.0-pro",
"input": {
"messages": [
{
"role": "user",
"content": [
{"image": "https://example-cdn.com/portrait.png"},
{"text": "Change the outfit to a champagne silk shirt"}
]
}
]
},
"parameters": {"size": "1024*1024", "n": 1, "prompt_extend": true}
}'Response
{
"output": {
"choices": [
{
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": [{"image": "https://dashscope-result-sz.oss-cn-shenzhen.aliyuncs.com/xxx.png?Expires=xxx"}]
}
}
]
},
"usage": {
"output_width": 1024, "output_height": 1024,
"input_image_count": 1, "input_image_type": "qima_input_1k",
"output_image_count": 1, "output_image_type": "qima_output_1k"
},
"request_id": "571ae02f-5c9d-436c-83c2-f221e6df0xxx"
}Constraints of this lane
input.messagescarries exactly one object androlemust beuser(single-turn only).contentcarries exactly one{"text": ...}; omitting it or passing several returns400.{"image": ...}0–3 entries: 0 is text to image, 1–3 is image to image.- Generation parameters live under
parameters(not at the top level):size/n/seed/negative_prompt/prompt_extend/prompt_extend_mode/enable_thinking/watermark. - With the official Bailian SDK (
dashscope), pointdashscope.base_http_api_urlathttps://api.modelgo.ai/api/v1and use your ModelGo API key.
3. Parameters
| Field | Type | Notes |
|---|---|---|
model | string | qwen-image-3.0-pro / qwen-image-3.0 |
prompt (compat lane) / content[].text (native lane) | string | Required, non-empty. Chinese and English; up to about 4500 tokens recommended |
image (compat lane) / content[].image (native lane) | string / string[] | Reference images, 1–3. null and an empty array are refused |
size | string | WxH on the compat lane, W*H on the native lane. Omitted means the model picks a resolution from the prompt |
n | int | 1–6 output images, default 1. Must be an integer; the string form (e.g. "1") returns 400 |
negative_prompt | string | What to keep out of the picture |
seed | int | 0 – 2147483647. A fixed seed makes results relatively stable |
prompt_extend | boolean | Prompt rewriting, default true (recommended) |
prompt_extend_mode | string | direct (default, T2I and I2I) / agent (finer, text to image only) |
enable_thinking | boolean | Thinking mode, default true. Better images, longer latency. Only effective when prompt_extend=true |
watermark | boolean | Watermark, default false |
Validation happens before the call
The following are refused at creation (HTTP 400) — nothing reaches the upstream and nothing is charged:
nis not an integer in 1–6, or is written as a string or a decimal;sizeis far too small or large, or the aspect ratio is extreme; see the official documentation for the accepted range;sizeuses the other lane's separator (the error names whetherxor*is expected);imageisnull, an empty array, or more than 3 entries;prompt_extend_mode: "agent"is combined withimage(APE is text to image only);seedis outside0–2147483647;- on the native lane,
messagesis not exactly one, orcontentdoes not carry exactly onetext.
Reference image requirements
- Formats: JPG / JPEG / PNG / BMP / TIFF / WEBP / GIF.
- Width and height between 384 and 2048 pixels recommended; at most 10 MB each.
- Public URLs (HTTP / HTTPS) or Base64 (
data:{MIME_type};base64,{base64_data}). - A public URL must be directly
GET-able by the upstream: no auth, no redirect, no Referer / Cookie dependency. Some sites return 403 to non-browser clients, which fails the request.
4. Metering
This family is metered per image, not per token. The usage block carries image counts and tiers rather than token counts:
| Field | Meaning |
|---|---|
output_image_count | How many images were delivered |
output_image_type | The output tier this call hit: qima_output_1k or qima_output_2k |
input_image_count | How many reference images the request supplied (0 for text to image) |
input_image_type | The input tier, qima_input_1k or qima_input_2k |
The tier is decided by the OUTPUT pixel area: an area of 2,250,000 (that is, 1500×1500) or less is 1k, anything larger is 2k. The input tier is judged by the output area too, not by the size of the reference image — that is the upstream's own rule.
Text to image supplies no reference image, so input_image_count is 0 and only the delivered images are metered. Requesting n images meters n, not one.
5. Full example (Python, official Bailian SDK)
import os
import dashscope
from dashscope import MultiModalConversation
dashscope.base_http_api_url = "https://api.modelgo.ai/api/v1"
response = MultiModalConversation.call(
api_key=os.environ["MODELGO_API_KEY"],
model="qwen-image-3.0-pro",
messages=[{
"role": "user",
"content": [
{"image": "https://example-cdn.com/portrait.png"},
{"text": "Change the outfit to a champagne silk shirt; modern minimalist cafe background"},
],
}],
prompt_extend=True,
)
if response.status_code == 200:
print(response.output.choices[0].message.content[0]["image"])
else:
print(f"Error: {response.code} - {response.message}")