> Raw Markdown twin (generated at build time from the source Markdown). Rendered page: https://docs.gatellm.io/en/quickstart/dashscope · Doc index: https://docs.gatellm.io/en/llms.txt


# Connect a DashScope upstream

DashScope is Alibaba Cloud's AI service, covering text generation, multimodal, text embedding, reranking, ASR, and other model types. This chapter walks you through creating a `dashscope` upstream + `qwen-turbo` model, calling it with the OpenAI SDK, and briefly covering the other `kind` variants.

## Prerequisites

- The gateway is running (`http://localhost:7890`) and you can log in to the Console
- `ENCRYPTION_KEY` is set — the upstream API key and access key saved below are encrypted before being stored; if it's not set, saving reports `encryption_key not set in config`. See [Docker single node → Prerequisites](/en/quickstart/docker-single-node.md#prereq)
- An Alibaba Cloud DashScope API key

## 1. Create a dashscope upstream

Console → **Upstreams** → **New**:

| Field | Value | Description |
|------|-----|------|
| Name | `dashscope` | Unique upstream identifier |
| Protocol | `dashscope` | Determines the executor and request schema |
| Base URL | `https://dashscope.aliyuncs.com` | The real upstream address, no trailing `/` |
| API Key | Alibaba Cloud key | Click "Add" to add multiple keys, distributed by weight |
| Enabled | ✓ | |

Save.

## 2. Create a qwen-turbo model

On the `dashscope` upstream row, click **Expand** → model sub-table → **New model**:

| Field | Value | Description |
|------|-----|------|
| Name | `qwen-turbo` | The model name exposed to clients |
| Upstream | `dashscope` | Select the upstream you just created |
| Upstream model ID | `qwen-turbo` | The real DashScope model name |
| Protocol | `dashscope` (inherited from upstream) | Can also be overridden at the model level |
| Enabled | ✓ | |

Save.

> Different DashScope model types have different endpoints, selected by the `kind` field. Text generation (such as `qwen-turbo`, `qwen-plus`, `qwen-max`) uses the default endpoint `/api/v1/services/aigc/text-generation/generation` and does not need `kind` specified. See the table below for other variants.

## 3. Configure a key group to allow access

Console → **Access Keys** → **Key Groups** tab → **New**:

| Field | Value | Description |
|------|-----|------|
| Name | `default` | Group name |
| Models | Select `qwen-turbo`, or `*` (all) | Determines which models this group's keys can call |
| Enabled | ✓ | |

## 4. Issue an access key

Console → **Access Keys** → **New**:

| Field | Value | Description |
|------|-----|------|
| Name | `my-app-key` | The key's identifier, used for management and audit |
| API key | Click "Generate" | Auto-generates a string; the credential clients send when calling |
| Group | `default` | Determines which models this key can access |
| Enabled | ✓ | |

## 5. Call with the OpenAI SDK

```python
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:7890/v1",
    api_key="<your access key>",
)

resp = client.chat.completions.create(
    model="qwen-turbo",
    messages=[{"role": "user", "content": "hi"}],
)
print(resp.choices[0].message.content)
```

The gateway automatically translates the OpenAI request format into the DashScope format, sends it to `https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation`, and translates the response back into the OpenAI format.

## 6. Or use curl

```bash
curl http://localhost:7890/v1/chat/completions \
  -H "Authorization: Bearer <your access key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-turbo",
    "messages": [{"role":"user","content":"hi"}]
  }'
```

Receiving a reply means it's working.

## Other kind variants

DashScope text generation uses the default endpoint; other model types switch endpoints via the `kind` field. The table below is an overview; see [Upstream and model fields](/en/reference/upstreams-models-fields.md) for full field descriptions.

| kind | Endpoint | Applicable models |
|------|------|---------|
| (default) | `/api/v1/services/aigc/text-generation/generation` | qwen-turbo, qwen-plus, qwen-max |
| `dashscope-multimodal` | `/api/v1/services/aigc/multimodal-generation/generation` | qwen-vl-chat-v1, qwen-vl-plus, qwen-audio, fun-asr-flash |
| `dashscope-text-embedding` | `/api/v1/services/embeddings/text-embedding/text-embedding` | text-embedding-v4 |
| `dashscope-rerank` | `/api/v1/services/rerank/text-rerank/text-rerank` | gte-rerank |
| `dashscope-audio-asr` | `/api/v1/services/audio/asr/transcription` (async) | fun-asr |

> The last three rows (embedding / rerank / ASR) have endpoints under the **Bailian MaaS domain** (`https://<workspace-id>.cn-beijing.maas.aliyuncs.com`), a different domain from text generation's `https://dashscope.aliyuncs.com`, so you need a separate upstream — see [Text embedding (separate upstream)](#text-embedding) below.

### Video generation (direct_path) {#video-generation}

Async models such as video generation need `direct_path = true` plus the full endpoint URL:

```json
{
  "name": "wanx2.1-t2v",
  "upstream": ["dashscope"],
  "upstream_model_id": "wanx2.1-t2v",
  "protocol": "dashscope",
  "direct_path": true,
  "base_url": "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis"
}
```

Async models also need this in `extra_config`: `{"dashscope": {"async_mode": true}}`

### Text embedding (separate upstream) {#text-embedding}

Text embedding / rerank / ASR models use the Bailian MaaS domain, a different domain from text generation's `https://dashscope.aliyuncs.com`, so you must first create a separate upstream and then create models under it.

**1) Create an upstream `dashscope-maas`** (Console → Upstreams → New):

| Field | Value | Description |
|------|-----|------|
| Name | `dashscope-maas` | Unique upstream identifier; the models below reference it via `upstream` |
| Protocol | `dashscope` | Same as text generation |
| Base URL | `https://<workspace-id>.cn-beijing.maas.aliyuncs.com` | The Bailian MaaS domain; replace `<workspace-id>` with your Bailian workspace ID |
| API Key | Alibaba Cloud key | Can be the same key as text generation |
| Enabled | ✓ | |

**2) Create a text embedding model under that upstream**:

```json
{
  "name": "text-embedding-v4",
  "upstream": ["dashscope-maas"],
  "upstream_model_id": "text-embedding-v4",
  "protocol": "dashscope",
  "kind": "dashscope-text-embedding"
}
```

Clients send requests using the standard OpenAI `/v1/embeddings` protocol, and the gateway automatically translates them to the DashScope format. Similarly, mount rerank / ASR under `dashscope-maas` with `kind` set to `dashscope-rerank` / `dashscope-audio-asr` respectively.

## Passthrough vs translation

DashScope clients can go two ways:

- **Passthrough**: `POST /v1/services/{*rest}` — the request body is sent to the DashScope upstream as-is
- **Translation**: `POST /v1/chat/completions` — the gateway translates the OpenAI format into the DashScope format

Passthrough suits the DashScope native SDK or cases where you want to bypass translation entirely; translation suits direct OpenAI SDK integration.

## FAQ

**Q: The client reports 400 unsupported_feature?**
That "client protocol → upstream protocol" combination has no translator. Check the [Protocol interop matrix](/en/reference/protocol-matrix.md). OpenAI → dashscope is supported.

**Q: The client reports 401 / 403 / 404?**
- 401: the access key isn't correct
- 403 model_access_denied: the key group's "Models" list doesn't include `qwen-turbo`
- 404 model_not_found: the model name is misspelled, or `hide_name` is set on it

**Q: The client reports 502 bad_gateway?**
The upstream is unreachable. Check DashScope's `base_url` (`https://dashscope.aliyuncs.com`, no trailing `/`), whether the API key is correct, and whether it's in the Alibaba Cloud allowlist.

**Q: Calling a video/image generation model reports 404?**
Async models need `direct_path = true` + the full endpoint URL + `extra_config.dashscope.async_mode = true`. See [Upstream and model fields](/en/reference/upstreams-models-fields.md) for details.

**Next**: [Upstream and model fields](/en/reference/upstreams-models-fields.md) for full upstream/model fields and all `kind` variants; [Endpoints · auth · protocol interop](/en/reference/endpoints.md) for the full endpoint list; [Client integration and gateway differences](/en/reference/clients-and-gateway-diffs.md) for SDK integration.
