Qwen API is provided by Alibaba Cloud Model Studio, with DashScope as its native interface system. Model Studio offers both an OpenAI-compatible interface and the native DashScope interface. For most teams, starting with the OpenAI-compatible interface is the least effort: existing SDKs, agent frameworks, and toolchains usually require changes in only three places — the API key, the Base URL, and the model name.

The real pitfalls are not "whether the call works" but the region of the Base URL, whether the model name is valid, how to parse streaming output, and which parameters cannot be copied directly when migrating from OpenAI. This article gets the chain working with a minimal request, then covers tool calls, error troubleshooting, and a migration checklist.

Note: Qwen, Tongyi Qianwen, Alibaba Cloud, Model Studio (Bailian), and DashScope are trademarks or product names of Alibaba Group and its affiliates. This article is for technical explanation only and implies no affiliation, agency, or endorsement relationship with Alibaba Group. Base URLs, model names, context lengths, and billing standards may change; refer to the official Alibaba Cloud Model Studio documentation and the model pricing page.

1. Before you start

Confirm three things before you begin:

  • A working API key that matches the target region.
  • The correct Base URL; mainland China, the international site, and gateway addresses cannot be mixed.
  • A model name that is actually available today, rather than an example copied from an old article.

Use curl to verify authentication and network connectivity before connecting an SDK. That way, when something fails, it is easier to tell whether the problem is the key, the address, or the code.

2. Base URL: choose the region first, then the domain

The OpenAI-compatible interface path is fixed at /compatible-mode/v1, with /chat/completions appended for the chat endpoint. Domains differ by region; common forms are shown below:

Scenario OpenAI-compatible Base URL Notes
Mainland China (Beijing, legacy shared domain) https://dashscope.aliyuncs.com/compatible-mode/v1 Compatible with old code; still available
Singapore (international site) https://dashscope-intl.aliyuncs.com/compatible-mode/v1 International-site account and key
US Virginia https://dashscope-us.aliyuncs.com/compatible-mode/v1 IPv4 only; capabilities per documentation
Hong Kong, China https://cn-hongkong.dashscope.aliyuncs.com/compatible-mode/v1 Independent region and key
Workspace-specific https://{WorkspaceId}.{region}.maas.aliyuncs.com/compatible-mode/v1 Recommended for production; better throughput and isolation
ZSQH AI Gateway https://ai.zhongshangqihang.com/v1 Unified multi-model entry point

Several points matter. First, an API key is bound to a region, and cross-region calls usually return 401 with invalid_api_key, which means the key and the address do not match rather than that the key is invalid. Second, mainland China accounts and international-site accounts are two separate systems; keys, billing, and model lists are not shared. Third, a workspace-specific domain accepts only keys from that workspace, but offers better throughput and traffic isolation, making it suitable for production; the legacy shared domain is convenient for cross-workspace access and quick tests.

If your team uses several model vendors and does not want to maintain regions, quotas, and multiple keys itself, you can create a unified key on the ZSQH AI Gateway and then switch the Base URL to the address in the last row of the table above.

3. How to choose model names

The Model Studio model list changes quickly. On the current official model page, for example, the Qwen models listed under text generation include qwen3.8-max, qwen3.7-plus, and qwen3.8-flash. From the naming you can roughly understand that max leans toward the capability ceiling, plus toward balance, and flash toward low latency and cost; the exact positioning and context length are subject to the official model documentation, and prices change, so refer to the model pricing page.

Do not select purely by "the strongest." For tasks such as customer-service Q&A, bulk classification, and content moderation, a lower-latency tier is often more cost-effective; reserve higher tiers for long-document analysis and complex agents. Make model names configuration items rather than hard-coding them, which makes later switching much easier.

There are two other common traps. Names such as qwen-max and qwen-plus in old tutorials may have been adjusted, so confirm in the console model list before connecting. When you need vector capability, use the embedding series (for example, qwen3.7-text-embedding); its request body is not the same as that of the chat interface. Qwen-Audio does not support the OpenAI-compatible protocol and must use the native DashScope interface.

4. Make the first call with curl

Prepare the environment variable first so the key does not appear in command history:

export DASHSCOPE_API_KEY="your_key_here"

curl https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.8-max",
    "messages": [
      {"role": "system", "content": "You are a concise technical assistant."},
      {"role": "user", "content": "Explain what an API gateway is in three sentences."}
    ],
    "temperature": 0.7
  }'

When the response is normal, focus on three fields: choices[0].message.content is the answer, usage is the usage for this call, and finish_reason indicates why generation ended. If you receive 401, check the key and region first; if you receive 404 with ModelNotFound, check the model name and whether that model is available in the region.

5. Calling with the Python SDK and streaming output

The OpenAI SDK must be version 1.0 or later. After pointing the Base URL at Model Studio, usage is basically the same as with OpenAI:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

stream = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[{"role": "user", "content": "Write a short product introduction, no more than one hundred words."}],
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

For streaming output, note that the first chunk may contain only role information with an empty content; do not assume every chunk contains text. With stream_options={"include_usage": True}, usage appears in the final chunk. With a direct HTTP connection, the response is in SSE format and ends with data: [DONE]. When a user closes the page, the server should cancel the upstream request as soon as possible to avoid continued generation and billing.

6. Tool calls and parameter differences

Tool calls follow OpenAI's tools and tool_choice format. After the model returns message.tool_calls, parse each call's function.arguments as JSON, execute the local function, and send the result back as a message with role: "tool". In a multi-turn flow, every request must include tools. Production environments need argument validation, permission checks, and timeout control; never trust model-generated arguments directly.

The official compatibility documentation currently lists two limitations for tools: only some models are listed as supported, and tools cannot yet be used together with stream=True. Model lists and capabilities are continually updated, so test with the target model before launch. If your business requires streaming and tool calls at the same time, consider the native DashScope interface or turn tool calls into a non-streaming step.

When migrating from OpenAI, also watch for these parameter differences:

  • messages: only messages[0] may use the system role; user and assistant messages generally alternate, and the last message must be from the user.
  • temperature: the range is [0, 2), and setting it to 0 is not recommended officially.
  • top_p: the range is (0, 1.0).
  • seed: use an unsigned 64-bit integer.
  • stop: array elements cannot mix token IDs and strings.
  • system_fingerprint: currently returns an empty string.
  • Extension parameters such as enable_search: usually passed through extra_body, and not supported by every model.
  • Fields such as response_format and frequency_penalty: the compatibility documentation does not promise them, so do not assume behavior identical to OpenAI.

7. Common errors at a glance

Symptom Common error code Possible cause What to do
401 InvalidApiKey / invalid_api_key Wrong key, region mismatch, package key mixed in Check the region and type of the key and Base URL
404 ModelNotFound / model_not_found Misspelled model name, model absent in the region, not enabled Check the console model list
404 model_not_supported Model does not support OpenAI-compatible mode Switch to the native DashScope interface
403 AccessDenied / Workspace.AccessDenied Insufficient workspace or model permission Check workspace authorization
403 AllocationQuota.FreeTierOnly Free quota exhausted Top up or adjust the plan
429 The Throttling family Request rate, token, or concurrency limit exceeded Reduce concurrency, back off and retry, request a quota increase
400 Arrearage Account in arrears Top up and retry
400 Range of input length... Input exceeds the context limit Compress the prompt or split the input
400 DataInspectionFailed Input or output blocked by content safety Adjust the content and retry

Retries work only for 429, 5xx, and network timeouts. Retrying 401, 403, 404, and parameter errors will not improve anything; it only wastes time and quota. During troubleshooting, record the Request ID in the response and look it up in the console logs — much faster than guessing.

8. Checklist for migrating from OpenAI

  1. Back up existing prompts, model parameters, and evaluation sets.
  2. Create a new Qwen key that matches the target region; do not reuse another vendor's key.
  3. Turn the Base URL and model name into configuration items.
  4. Check the messages role rules, ensuring the first message is system and the last is user.
  5. Check streaming parsing and usage accounting.
  6. Run a tool-call regression test with real tools.
  7. Compare output quality, latency, and usage on the same batch of samples.
  8. Adjust retries, timeouts, and concurrency, and observe for a week before a full cutover.
  9. Record Request IDs in logs and keep a rollback switch.

9. Frequently asked questions (FAQ)

1. Is Qwen API compatible with OpenAI?

Most common chat endpoints are compatible, but differences remain in region binding, role order, parameter ranges, and tool-call limitations. Verify item by item against the official OpenAI compatibility documentation; do not assume all parameter behavior is identical.

2. Can mainland China and the international site share one key?

No. The two sites have independent accounts, keys, endpoint domains, and billing. Cross-region or cross-site calls usually return 401 with invalid_api_key.

3. Should the Base URL use the legacy domain or a workspace-specific domain?

The legacy shared domain is fine for quick tests; for production, a workspace-specific domain is recommended for better throughput and traffic isolation. The key point is that the key must match the region and workspace that the domain belongs to.

4. Why does a correct model name still return model_not_found?

Common reasons include the model not being available in that region, the model not being enabled, inconsistent capitalization, or access to a retired version. Use the console's current model list as the source of truth.

5. Can tools be used together with stream?

The official compatibility documentation currently states that the two cannot be used together, and tool calling is listed as supported only for some models. Capabilities and limitations change with model updates; test with the target model before launch, or switch to the native DashScope interface.