> ## Documentation Index
> Fetch the complete documentation index at: https://docs.modelstudio.console.alibabacloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Qwen-OCR API reference

> Extract text, structured data, and key information from images using the Qwen-OCR model. Qwen-OCR supports two API protocols: the OpenAI-compatible API and the DashScope API.

> For use cases and getting-started guidance, see [Text extraction (Qwen-OCR)](/en/model-studio/qwen-vl-ocr).

## OpenAI-compatible API <span id="d397bcc41eu3q" /> <span id="7c782df20fkq8" />

## Endpoints <span id="h3_75251f02" /> <span id="section_cb340bc5" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /></colgroup><thead><tr><th><p><span><strong>Region</strong></span></p></th><th><p><span><strong>SDK</strong></span><code>base\_url</code></p></th><th><p><span><strong>HTTP endpoint</strong></span></p></th></tr></thead><tbody><tr><td><p>Singapore</p></td><td><p><code>https\://\{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1</code></p></td><td><p><code>POST https\://\{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions</code></p></td></tr><tr><td><p>US (Virginia)</p></td><td><p><code>https\://\{WorkspaceId}.us-east-1.maas.aliyuncs.com/compatible-mode/v1</code></p></td><td><p><code>POST https\://\{WorkspaceId}.us-east-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions</code></p></td></tr><tr><td><p>China (Beijing)</p></td><td><p><code>https\://\{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1</code></p></td><td><p><code>POST https\://\{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/chat/completions</code></p></td></tr></tbody></table>

<Tip>
  Alibaba Cloud Model Studio has released workspace-specific domains for the China (Beijing) and Singapore regions. <strong>The new dedicated domains deliver superior performance and higher stability for inference requests</strong>. We recommend migrating to the new domains:

  - China (Beijing): from `https://dashscope.aliyuncs.com` to `https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com`
  - Singapore: from `https://dashscope-intl.aliyuncs.com` to `https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com`

  `{WorkspaceId}` is your workspace ID, which can be found on the <strong>Workspace Details</strong> page in the Alibaba Cloud Model Studio console. The existing domain remains fully functional.
</Tip>

## Prerequisites <span id="h3_3bd70d7b" /> <span id="section_cdff952a" />

[Get an API key](https://www.alibabacloud.com/help/model-studio/get-api-key) and [set it as an environment variable](/en/model-studio/get-api-key). If you use the OpenAI SDK, [install the SDK](/en/model-studio/install-sdk).

## Quick start <span id="h3_070d69c1" /> <span id="section_4efbbf5e" />

Use the OpenAI-compatible chat completions endpoint. Send a `user` message with an image URL and text prompt. The model extracts text and returns it in `choices[0].message.content`.

## Non-streaming <span id="h4_c0e0b97a" /> <span id="section_c65935d1" />

<strong>Python</strong>

```python expandable
from openai import OpenAI
import os

PROMPT_TICKET_EXTRACTION = """
Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image.
You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?).
Return the data in JSON format as follows: {'invoice_number': 'xxx', 'departure_station': 'xxx', 'arrival_station': 'xxx', 'departure_date_and_time':'xxx', 'seat_number': 'xxx','ticket_price':'xxx', 'id_card_number': 'xxx', 'passenger_name': 'xxx'},
"""

try:
    client = OpenAI(
        # If the environment variable is not configured, replace with: api_key="sk-xxx"
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        # Singapore region. For US (Virginia), use https://{WorkspaceId}.us-east-1.maas.aliyuncs.com/compatible-mode/v1
        # For China (Beijing), use https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
        base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
    )
    completion = client.chat.completions.create(
        model="qwen-vl-ocr-2025-11-20",
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image_url",
                        "image_url": {"url":"https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg"},
                        # Minimum pixel count. Images below this are upscaled.
                        "min_pixels": 32 * 32 * 3,
                        # Maximum pixel count. Images above this are downscaled.
                        "max_pixels": 32 * 32 * 8192
                    },
                    # Custom prompt. Without this, the model uses: "Please output only the text content from the image without any additional descriptions or formatting."
                    {"type": "text",
                     "text": PROMPT_TICKET_EXTRACTION}
                ]
            }
        ])
    print(completion.choices[0].message.content)
except Exception as e:
    print(f"Error message: {e}")
```

<strong>Node.js</strong>

```javascript expandable
import OpenAI from 'openai';

const PROMPT_TICKET_EXTRACTION = `
Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image.
You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?).
Return the data in JSON format as follows: {'invoice_number': 'xxx', 'departure_station': 'xxx', 'arrival_station': 'xxx', 'departure_date_and_time':'xxx', 'seat_number': 'xxx','ticket_price':'xxx', 'id_card_number': 'xxx', 'passenger_name': 'xxx'}
`;

const client = new OpenAI({
  // If the environment variable is not configured, replace with: apiKey: "sk-xxx"
  apiKey: process.env.DASHSCOPE_API_KEY,
  // For China (Beijing), use https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
  baseURL: 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1',
});

async function main() {
  const response = await client.chat.completions.create({
    model: 'qwen-vl-ocr-2025-11-20',
    messages: [
      {
        role: 'user',
        content: [
          { type: 'text', text: PROMPT_TICKET_EXTRACTION},
          {
            type: 'image_url',
            image_url: {
              url: 'https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg',
            },
              // Minimum pixel count. Images below this are upscaled.
              "min_pixels": 32 * 32 * 3,
              // Maximum pixel count. Images above this are downscaled.
              "max_pixels": 32 * 32 * 8192
          }
        ]
      }
    ],
  });
  console.log(response.choices[0].message.content)
}

main();
```

<strong>curl</strong>

```bash
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "qwen-vl-ocr-2025-11-20",
  "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url":"https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg"},
                    "min_pixels": 3072,
                    "max_pixels": 8388608
                },
                {"type": "text", "text": "Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image. You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?). Return the data in JSON format as follows: {\'invoice_number\': \'xxx\', \'departure_station\': \'xxx\', \'arrival_station\': \'xxx\', \'departure_date_and_time\':\'xxx\', \'seat_number\': \'xxx\',\'ticket_price\':\'xxx\', \'id_card_number\': \'xxx\', \'passenger_name\': \'xxx\'}"}
            ]
        }
    ]
}'
```

## Streaming <span id="h4_f309841f" /> <span id="section_0c639959" />

Set `stream` to `true` to receive results incrementally as the model generates them.

<strong>Python</strong>

```python expandable
import os
from openai import OpenAI

PROMPT_TICKET_EXTRACTION = """
Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image.
You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?).
Return the data in JSON format as follows: {'invoice_number': 'xxx','departure_station': 'xxx', 'arrival_station': 'xxx', 'departure_date_and_time':'xxx', 'seat_number': 'xxx','ticket_price':'xxx', 'id_card_number': 'xxx', 'passenger_name': 'xxx'},
"""

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
    model="qwen-vl-ocr-2025-11-20",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url":"https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg"},
                    "min_pixels": 32 * 32 * 3,
                    "max_pixels": 32 * 32 * 8192
                },
                {"type": "text","text": PROMPT_TICKET_EXTRACTION}
            ]
        }
    ],
    stream=True,
    stream_options={"include_usage": True}
)

for chunk in completion:
    print(chunk.model_dump_json())
```

<strong>Node.js</strong>

```javascript expandable
import OpenAI from 'openai';

const PROMPT_TICKET_EXTRACTION = `
Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image.
You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?).
Return the data in JSON format as follows: {'invoice_number': 'xxx', 'departure_station': 'xxx', 'arrival_station': 'xxx', 'departure_date_and_time':'xxx', 'seat_number': 'xxx','ticket_price':'xxx', 'id_card_number': 'xxx', 'passenger_name': 'xxx'}
`;

const openai = new OpenAI({
  apiKey: process.env.DASHSCOPE_API_KEY,
  baseURL: 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1',
});

async function main() {
  const response = await openai.chat.completions.create({
    model: 'qwen-vl-ocr-2025-11-20',
    messages: [
      {
        role: 'user',
        content: [
          { type: 'text', text: PROMPT_TICKET_EXTRACTION},
          {
            type: 'image_url',
            image_url: {
              url: 'https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg',
            },
              "min_pixels": 32 * 32 * 3,
              "max_pixels": 32 * 32 * 8192
          }
        ]
      }
    ],
    stream: true,
    stream_options:{"include_usage": true}
  });
  let fullContent = ""
  console.log("Streaming output content:")
  for await (const chunk of response) {
    if (chunk.choices[0] && chunk.choices[0].delta.content != null) {
      fullContent += chunk.choices[0].delta.content;
      console.log(chunk.choices[0].delta.content);
    }
  }
  console.log(`Full output content: ${fullContent}`)
}

main();
```

<strong>curl</strong>

```bash
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "qwen-vl-ocr-2025-11-20",
  "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url":"https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg"},
                    "min_pixels": 3072,
                    "max_pixels": 8388608
                },
                {"type": "text", "text": "Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image. You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?). Return the data in JSON format as follows: {\'invoice_number\': \'xxx\', \'departure_station\': \'xxx\', \'arrival_station\': \'xxx\', \'departure_date_and_time\':\'xxx\', \'seat_number\': \'xxx\',\'ticket_price\':\'xxx\', \'id_card_number\': \'xxx\', \'passenger_name\': \'xxx\'}"}
            ]
        }
    ],
    "stream": true,
    "stream_options": {"include_usage": true}
}'
```

## Request parameters <span id="afcd41d2b57zf" /> <span id="f4514ce9072sb" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Required</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>model</code></p></td><td><p>string</p></td><td><p>Yes</p></td><td><p>Model name. See <a href="/en/model-studio/models">Recommended models</a> for supported models.</p></td></tr><tr><td><p><code>messages</code></p></td><td><p>array</p></td><td><p>Yes</p></td><td><p>An array of message objects that provides context to the model.</p></td></tr></tbody></table>

<strong>Message object</strong>

Each message requires a `role` (must be `user`) and a `content` array with these element types:

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Required</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>type</code></p></td><td><p>string</p></td><td><p>Yes</p></td><td><p><code>text</code> for text input, <code>image\_url</code> for image input.</p></td></tr><tr><td><p><code>text</code></p></td><td><p>string</p></td><td><p>No</p></td><td><p>The text prompt. Default: <code>"Please output only the text content from the image without any additional descriptions or formatting"</code>.</p></td></tr><tr><td><p><code>image\_url.url</code></p></td><td><p>string</p></td><td><p>Yes (when <code>type</code> is <code>image\_url</code>)</p></td><td><p>URL or Base64-encoded Data URL of the image. For local files, see <a href="/en/model-studio/qwen-vl-ocr#ea4e1d92dbry2">Text extraction</a>.</p></td></tr><tr><td><p><code>min\_pixels</code></p></td><td><p>integer</p></td><td><p>No</p></td><td><p>Minimum pixel threshold. Images below this value are upscaled. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_e15b177d">Image resolution control</a>.</p></td></tr><tr><td><p><code>max\_pixels</code></p></td><td><p>integer</p></td><td><p>No</p></td><td><p>Maximum pixel threshold. Images above this value are downscaled. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_e15b177d">Image resolution control</a>.</p></td></tr></tbody></table>

<strong>Generation parameters</strong>

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Default</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>stream</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>Set to <code>true</code> to receive incremental responses as the model generates output.</p></td></tr><tr><td><p><code>stream\_options.include\_usage</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>When <code>stream</code> is <code>true</code>, set this to <code>true</code> to include token usage in the last chunk.</p></td></tr><tr><td><p><code>max\_tokens</code></p></td><td><p>integer</p></td><td><p>Varies</p></td><td><p>Maximum tokens in the output. Exceeding this truncates the response. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_bb77eb38">Output token limits</a>.</p></td></tr><tr><td><p><code>temperature</code></p></td><td><p>float</p></td><td><p><code>0.01</code></p></td><td><p>Controls output diversity. Higher values produce more varied text. Range: \[0, 2).</p></td></tr><tr><td><p><code>top\_p</code></p></td><td><p>float</p></td><td><p><code>0.001</code></p></td><td><p>Nucleus sampling threshold. Higher values increase diversity. Range: (0, 1.0]. Set either <code>temperature</code> or <code>top\_p</code>, not both.</p></td></tr><tr><td><p><code>top\_k</code></p></td><td><p>integer</p></td><td><p><code>1</code></p></td><td><p>Limits the candidate token set during sampling. If the value is None or greater than 100, the top\_k policy is not enabled, and only the top\_p policy takes effect. Must be >= 0. Not a standard OpenAI parameter -- pass via <code>extra\_body</code> in the Python SDK: <code>extra\_body=\{"top\_k": xxx}</code>. In the Node.js SDK or HTTP, pass at the top level.</p></td></tr><tr><td><p><code>repetition\_penalty</code></p></td><td><p>float</p></td><td><p><code>1.0</code></p></td><td><p>Penalty for repeated sequences. Values above 1.0 reduce repetition. Not a standard OpenAI parameter -- pass via <code>extra\_body</code> in the Python SDK.</p></td></tr><tr><td><p><code>presence\_penalty</code></p></td><td><p>float</p></td><td><p><code>0.0</code></p></td><td><p>Controls content repetition. Range: \[-2.0, 2.0]. Positive values reduce repetition.</p></td></tr><tr><td><p><code>seed</code></p></td><td><p>integer</p></td><td><p>--</p></td><td><p>Ensures reproducible results when the same value is used with identical parameters. Range: \[0, 2^31 - 1].</p></td></tr><tr><td><p><code>logprobs</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>Set to <code>true</code> to return log probabilities of output tokens.</p></td></tr><tr><td><p><code>top\_logprobs</code></p></td><td><p>integer</p></td><td><p><code>0</code></p></td><td><p>Number of most likely tokens to return per step. Range: \[0, 5]. Only effective when <code>logprobs</code> is <code>true</code>.</p></td></tr><tr><td><p><code>stop</code></p></td><td><p>string or array</p></td><td><p>--</p></td><td><p>Stop words or token IDs. Generation stops when a specified string or <code>token\_id</code> appears. Do not mix strings and <code>token\_id</code>s in the same array.</p></td></tr></tbody></table>

## Response <span id="cd3063363egdc" /> <span id="182c685357r7w" />

## Non-streaming response (`chat.completion`) <span id="h4_bc954da0" /> <span id="section_5971b0a3" />

````json expandable
{
  "id": "chatcmpl-ba21fa91-dcd6-4dad-90cc-6d49c3c39094",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "```json\n{\n    \"seller_name\": \"null\",\n    \"buyer_name\": \"Cai Yingshi\",\n    \"price_excluding_tax\": \"230769.23\",\n    \"organization_code\": \"null\",\n    \"invoice_code\": \"142011726001\"\n}\n```",
        "refusal": null,
        "role": "assistant",
        "annotations": null,
        "audio": null,
        "function_call": null,
        "tool_calls": null
      }
    }
  ],
  "created": 1763283287,
  "model": "qwen3.5-ocr",
  "object": "chat.completion",
  "service_tier": null,
  "system_fingerprint": null,
  "usage": {
    "completion_tokens": 72,
    "prompt_tokens": 1185,
    "total_tokens": 1257,
    "completion_tokens_details": {
      "accepted_prediction_tokens": null,
      "audio_tokens": null,
      "reasoning_tokens": null,
      "rejected_prediction_tokens": null,
      "text_tokens": 72
    },
    "prompt_tokens_details": {
      "audio_tokens": null,
      "cached_tokens": null,
      "image_tokens": 1001,
      "text_tokens": 184
    }
  }
}
````

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /></colgroup><thead><tr><th><p><span><strong>Field</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>id</code></p></td><td><p>string</p></td><td><p>Unique request identifier.</p></td></tr><tr><td><p><code>choices</code></p></td><td><p>array</p></td><td><p>Model-generated content.</p></td></tr><tr><td><p><code>choices\[].finish\_reason</code></p></td><td><p>string</p></td><td><p><code>stop</code> when generation completed normally, <code>length</code> when truncated due to token limit.</p></td></tr><tr><td><p><code>choices\[].index</code></p></td><td><p>integer</p></td><td><p>Position in the <code>choices</code> array.</p></td></tr><tr><td><p><code>choices\[].message.content</code></p></td><td><p>string</p></td><td><p>Extracted text or structured output from the model.</p></td></tr><tr><td><p><code>choices\[].message.role</code></p></td><td><p>string</p></td><td><p>Always <code>assistant</code>.</p></td></tr><tr><td><p><code>choices\[].message.refusal</code></p></td><td><p>string</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>choices\[].message.audio</code></p></td><td><p>object</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>choices\[].message.function\_call</code></p></td><td><p>object</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>choices\[].message.tool\_calls</code></p></td><td><p>array</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>created</code></p></td><td><p>integer</p></td><td><p>UNIX timestamp of the request.</p></td></tr><tr><td><p><code>model</code></p></td><td><p>string</p></td><td><p>Model used.</p></td></tr><tr><td><p><code>object</code></p></td><td><p>string</p></td><td><p>Always <code>chat.completion</code>.</p></td></tr><tr><td><p><code>service\_tier</code></p></td><td><p>string</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>system\_fingerprint</code></p></td><td><p>string</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>usage.completion\_tokens</code></p></td><td><p>integer</p></td><td><p>Output token count.</p></td></tr><tr><td><p><code>usage.prompt\_tokens</code></p></td><td><p>integer</p></td><td><p>Input token count.</p></td></tr><tr><td><p><code>usage.total\_tokens</code></p></td><td><p>integer</p></td><td><p>Sum of <code>prompt\_tokens</code> and <code>completion\_tokens</code>.</p></td></tr><tr><td><p><code>usage.completion\_tokens\_details.text\_tokens</code></p></td><td><p>integer</p></td><td><p>Text output tokens. Other fields in <code>completion\_tokens\_details</code> are always <code>null</code>.</p></td></tr><tr><td><p><code>usage.prompt\_tokens\_details.image\_tokens</code></p></td><td><p>integer</p></td><td><p>Image input tokens.</p></td></tr><tr><td><p><code>usage.prompt\_tokens\_details.text\_tokens</code></p></td><td><p>integer</p></td><td><p>Text input tokens. Other fields in <code>prompt\_tokens\_details</code> are always <code>null</code>.</p></td></tr></tbody></table>

## Streaming response (`chat.completion.chunk`) <span id="e98e6b7aa5nb2" /> <span id="f0b9c155ad0e0" />

When `stream` is `true`, the response is delivered as a series of Server-Sent Event (SSE) chunks. Each chunk follows the same structure as the non-streaming response, with these differences:

- `object` is always `chat.completion.chunk`.
- `choices[].delta` replaces `choices[].message`. The `delta` object has the same fields as `message`.
- `choices[].delta.role` is returned only in the first chunk.
- `finish_reason` is `null` during generation, `stop` on completion, or `length` if truncated.
- When `include_usage` is `true`, the last chunk has an empty `choices` array and includes the `usage` object.

````json
{"id":"chatcmpl-f6fbdc0d-78d6-418f-856f-f099c2e4859b","choices":[{"delta":{"content":"","function_call":null,"refusal":null,"role":"assistant","tool_calls":null},"finish_reason":null,"index":0,"logprobs":null}],"created":1764139204,"model":"qwen3.5-ocr","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
{"id":"chatcmpl-f6fbdc0d-78d6-418f-856f-f099c2e4859b","choices":[{"delta":{"content":"```","function_call":null,"refusal":null,"role":null,"tool_calls":null},"finish_reason":null,"index":0,"logprobs":null}],"created":1764139204,"model":"qwen3.5-ocr","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
{"id":"chatcmpl-f6fbdc0d-78d6-418f-856f-f099c2e4859b","choices":[{"delta":{"content":"json","function_call":null,"refusal":null,"role":null,"tool_calls":null},"finish_reason":null,"index":0,"logprobs":null}],"created":1764139204,"model":"qwen3.5-ocr","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
......
{"id":"chatcmpl-f6fbdc0d-78d6-418f-856f-f099c2e4859b","choices":[{"delta":{"content":"","function_call":null,"refusal":null,"role":null,"tool_calls":null},"finish_reason":"stop","index":0,"logprobs":null}],"created":1764139204,"model":"qwen3.5-ocr","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
{"id":"chatcmpl-f6fbdc0d-78d6-418f-856f-f099c2e4859b","choices":[],"created":1764139204,"model":"qwen3.5-ocr","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":{"completion_tokens":141,"prompt_tokens":513,"total_tokens":654,"completion_tokens_details":{"accepted_prediction_tokens":null,"audio_tokens":null,"reasoning_tokens":null,"rejected_prediction_tokens":null,"text_tokens":141},"prompt_tokens_details":{"audio_tokens":null,"cached_tokens":null,"image_tokens":332,"text_tokens":181}}}
````

## Image resolution control <span id="h3_893bae92" /> <span id="section_e15b177d" />

`min_pixels` and `max_pixels` control image resizing before processing. Token-to-pixel ratio depends on model version:

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "20%" }} /><col style={{ width: "20%" }} /><col style={{ width: "20%" }} /><col style={{ width: "20%" }} /><col style={{ width: "20%" }} /></colgroup><thead><tr><th><p><span><strong>Model</strong></span></p></th><th><p><span><strong>Pixels per token</strong></span></p></th><th><p><code>min\_pixels</code><span><strong>default (minimum)</strong></span></p></th><th><p><code>max\_pixels</code><span><strong>default</strong></span></p></th><th><p><code>max\_pixels</code><span><strong>maximum</strong></span></p></th></tr></thead><tbody><tr><td><p><code>qwen3.5-ocr</code>, <code>qwen-vl-ocr-2025-11-20</code></p></td><td><p>32 x 32 = 1,024</p></td><td><p>3,072 (3 tokens)</p></td><td><p>8,388,608 (8,192 tokens)</p></td><td><p>30,720,000 (30,000 tokens)</p></td></tr><tr><td><p><code>qwen-vl-ocr</code>, and earlier</p></td><td><p>28 x 28 = 784</p></td><td><p>3,136 (4 tokens)</p></td><td><p>6,422,528 (8,192 tokens)</p></td><td><p>23,520,000 (30,000 tokens)</p></td></tr></tbody></table>

<strong>Resizing behavior</strong>:

- If the image pixel count is below `min_pixels`, the image is upscaled until it exceeds `min_pixels`.
- If the image pixel count is within `[min_pixels, max_pixels]`, the original image is used without resizing.
- If the image pixel count exceeds `max_pixels`, the image is downscaled below `max_pixels`.

## Output token limits <span id="h3_bdc8b8e6" /> <span id="section_bb77eb38" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "50%" }} /><col style={{ width: "50%" }} /></colgroup><thead><tr><th><p><span><strong>Model</strong></span></p></th><th><p><span><strong>Default and maximum</strong></span><code>max\_tokens</code></p></th></tr></thead><tbody><tr><td><p><code>qwen3.5-ocr</code>, <code>qwen-vl-ocr-2025-11-20</code>, <code>qwen-vl-ocr-2024-10-28</code></p></td><td><p>Same as the model's maximum output length. See <a href="/en/model-studio/qwen-vl-ocr#f4299b0a1ace4">Model selection</a>.</p></td></tr><tr><td><p><code>qwen-vl-ocr</code>, <code>qwen-vl-ocr-2025-11-20</code></p></td><td><p>4,096</p></td></tr></tbody></table>

> For `qwen-vl-ocr, qwen-vl-ocr-2025-11-20`, `max_tokens` defaults to 4096. To increase it (4097–8192), contact your commercial manager with: your Alibaba Cloud account ID, image type (e.g., documents, e-commerce, contracts), model name, estimated QPS and daily request volume, and the percentage of requests exceeding 4096 output tokens.

---

## DashScope API <span id="69cac67a477k2" /> <span id="a9b7b197e2q2v" />

## Endpoints <span id="h3_0b4e692c" /> <span id="section_ca350aa2" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "50%" }} /><col style={{ width: "50%" }} /></colgroup><thead><tr><th><p><span><strong>Region</strong></span></p></th><th><p><span><strong>HTTP endpoint</strong></span></p></th></tr></thead><tbody><tr><td><p>Singapore</p></td><td><p><code>POST https\://\{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation</code></p></td></tr><tr><td><p>US (Virginia)</p></td><td><p><code>POST https\://\{WorkspaceId}.us-east-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation</code></p></td></tr><tr><td><p>China (Beijing)</p></td><td><p><code>POST https\://\{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation</code></p></td></tr></tbody></table>

<strong>SDK region configuration</strong>:

Python:

```python
import dashscope

client = dashscope.Client(workspace="{WorkspaceId}", region="ap-southeast-1")
```

Java (Method 1 -- constructor):

```java
import com.alibaba.dashscope.protocol.Protocol;
MultiModalConversation conv = new MultiModalConversation(Protocol.HTTP.getValue(), "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");
```

Java (Method 2 -- static block):

```java
import com.alibaba.dashscope.utils.Constants;
Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
```

> For the Python SDK, set `region` to `us-east-1` for the US (Virginia) region or `cn-beijing` for the China (Beijing) region. For the Java SDK, replace the domain with `{WorkspaceId}.us-east-1.maas.aliyuncs.com` or `{WorkspaceId}.cn-beijing.maas.aliyuncs.com` accordingly.

[Get an API key](https://www.alibabacloud.com/help/model-studio/get-api-key) and [set it as an environment variable](/en/model-studio/get-api-key). If you use the DashScope SDK, you must also [install the DashScope SDK](/en/model-studio/install-sdk).

## Built-in tasks <span id="h3_157e9d47" /> <span id="section_df04af68" />

The DashScope API provides built-in OCR tasks via the `ocr_options` parameter. Each task uses an optimized default prompt, eliminating the need for a `text` message.

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /></colgroup><thead><tr><th><p><span><strong>Task</strong></span></p></th><th><p><code>ocr\_options.task</code><span><strong>value</strong></span></p></th><th><p><span><strong>Output format</strong></span></p></th></tr></thead><tbody><tr><td><p>General text recognition</p></td><td><p><code>text\_recognition</code></p></td><td><p>Plain text</p></td></tr><tr><td><p>High-precision recognition</p></td><td><p><code>advanced\_recognition</code></p></td><td><p>Plain text with bounding boxes</p></td></tr><tr><td><p>Information extraction</p></td><td><p><code>key\_information\_extraction</code></p></td><td><p>Structured key-value pairs</p></td></tr><tr><td><p>Table parsing</p></td><td><p><code>table\_parsing</code></p></td><td><p>Table structure</p></td></tr><tr><td><p>Document parsing</p></td><td><p><code>document\_parsing</code></p></td><td><p>Document structure</p></td></tr><tr><td><p>Formula recognition</p></td><td><p><code>formula\_recognition</code></p></td><td><p>LaTeX formulas</p></td></tr><tr><td><p>Multilingual recognition</p></td><td><p><code>multi\_lan</code></p></td><td><p>Multilingual text</p></td></tr></tbody></table>

## High-precision recognition <span id="0b1a49207d6cw" /> <span id="section_60e443e8" />

Returns text with positional data for each recognized line.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
            }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to advanced recognition
    parameters={"ocr_options": {"task": "advanced_recognition"}}
)
# The advanced recognition task returns results as plain text
print(response.output_text)
```

<strong>Java</strong>

```java expandable
// dashscope SDK version >= 2.21.8
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.ADVANCED_RECOGNITION)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "advanced_recognition"
    }
  }
}
'
```

## Information extraction <span id="dad93045030b6" /> <span id="section_728639b0" />

Extracts structured key-value data from images. Specify fields to extract in `task_config.result_schema`.

<strong>Python</strong>

```python expandable
import os
import dashscope

dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'

messages = [
      {
        "role":"user",
        "content":[
          {
              "image":"http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg",
              "min_pixels": 3072,
              "max_pixels": 8388608,
              "enable_rotate": False
          }
        ]
      }
    ]

params = {
  "ocr_options":{
    "task": "key_information_extraction",
    "task_config": {
      "result_schema": {
          "Ride Date": "Corresponds to the ride date and time in the image, in the format YYYY-MM-DD, for example, 2025-03-05",
          "Invoice Code": "Extract the invoice code from the image, usually a combination of numbers or letters",
          "Invoice Number": "Extract the number from the invoice, usually composed of only digits."
      }
    }
  }
}

response = dashscope.MultiModalConversation.call(
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    **params)

print(response.output.choices[0].message.content[0]["ocr_result"])
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.JsonObject;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        JsonObject resultSchema = new JsonObject();
        resultSchema.addProperty("Ride Date", "Corresponds to the ride date and time in the image, in the format YYYY-MM-DD, for example, 2025-03-05");
        resultSchema.addProperty("Invoice Code", "Extract the invoice code from the image, usually a combination of numbers or letters");
        resultSchema.addProperty("Invoice Number", "Extract the number from the invoice, usually composed of only digits.");

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.KEY_INFORMATION_EXTRACTION)
                .taskConfig(OcrOptions.TaskConfig.builder().resultSchema(resultSchema).build())
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("ocr_result"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "key_information_extraction",
      "task_config": {
        "result_schema": {
          "Ride Date": "Corresponds to the ride date and time in the image, in the format YYYY-MM-DD, for example, 2025-03-05",
          "Invoice Code": "Extract the invoice code from the image, usually a combination of numbers or letters",
          "Invoice Number": "Extract the number from the invoice, usually composed of only digits."
        }
      }
    }
  }
}
'
```

## Table parsing <span id="dc5cd323ea8z7" /> <span id="section_cd80e20d" />

Extracts table structure from images.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "http://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/doc_parsing/tables/photo/eng/17.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
           }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to table parsing
    parameters={"ocr_options": {"task": "table_parsing"}}
)
# The table parsing task returns results in HTML format
print(response.output_text)
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/doc_parsing/tables/photo/eng/17.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.TABLE_PARSING)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "http://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/doc_parsing/tables/photo/eng/17.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "table_parsing"
    }
  }
}
'
```

## Document parsing <span id="4f214b167905s" /> <span id="section_8c8fe6e1" />

Extracts the structural layout and text from documents.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
            }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to document parsing
    parameters={"ocr_options": {"task": "document_parsing"}}
)
# The document parsing task returns results in LaTeX format
print(response.output_text)
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.DOCUMENT_PARSING)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "document_parsing"
    }
  }
}
'
```

## Formula recognition <span id="7231f794b7wjj" /> <span id="section_66608810" />

Extracts mathematical formulas from images and returns them in LaTeX format.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "http://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/formula_handwriting/test/inline_5_4.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
            }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to formula recognition
    parameters={"ocr_options": {"task": "formula_recognition"}}
)
# The formula recognition task returns results in LaTeX format
print(response.output_text)
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "http://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/formula_handwriting/test/inline_5_4.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.FORMULA_RECOGNITION)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "http://duguang-llm.oss-cn-hangzhou.aliyuncs.com/llm_data_keeper/data/formula_handwriting/test/inline_5_4.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "formula_recognition"
    }
  }
}
'
```

## General text recognition <span id="ac8b08b939ozd" /> <span id="section_1c024b79" />

Extracts plain text from images without structural formatting.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
        }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to text recognition
    parameters={"ocr_options": {"task": "text_recognition"}}
)
# The text recognition task returns results as plain text
print(response.output_text)
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.TEXT_RECOGNITION)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/ctdzex/biaozhun.jpg",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "text_recognition"
    }
  }
}
'
```

## Multilingual recognition <span id="674a2bba0fnuf" /> <span id="section_fff9d079" />

Recognizes text in multiple languages from images.

<strong>Python</strong>

```python
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [{
            "role": "user",
            "content": [{
                "image": "https://img.alicdn.com/imgextra/i2/O1CN01VvUMNP1yq8YvkSDFY_!!6000000006629-2-tps-6000-3000.png",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192}]
            }]

response = client.multimodal.chat.create(
    model='qwen-vl-ocr-2025-11-20',
    messages=messages,
    # Set the built-in task to multi-language recognition
    parameters={"ocr_options": {"task": "multi_lan"}}
)
# The multi-language recognition task returns results as plain text
print(response.output_text)
```

<strong>Java</strong>

```java expandable
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.aigc.multimodalconversation.OcrOptions;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://img.alicdn.com/imgextra/i2/O1CN01VvUMNP1yq8YvkSDFY_!!6000000006629-2-tps-6000-3000.png");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        map.put("enable_rotate", false);

        OcrOptions ocrOptions = OcrOptions.builder()
                .task(OcrOptions.Task.MULTI_LAN)
                .build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map
                        )).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .ocrOptions(ocrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '
{
  "model": "qwen-vl-ocr-2025-11-20",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "image": "https://img.alicdn.com/imgextra/i2/O1CN01VvUMNP1yq8YvkSDFY_!!6000000006629-2-tps-6000-3000.png",
            "min_pixels": 3072,
            "max_pixels": 8388608,
            "enable_rotate": false
          }
        ]
      }
    ]
  },
  "parameters": {
    "ocr_options": {
      "task": "multi_lan"
    }
  }
}
'
```

## Streaming (DashScope) <span id="h3_9fa1e04b" /> <span id="section_b3959f1a" />

Enable streaming output to receive results incrementally. The method varies by SDK:

- <strong>Python SDK</strong>: Set `stream=True`.
- <strong>Java SDK</strong>: Use the `streamCall` interface.
- <strong>HTTP</strong>: Set the `X-DashScope-SSE: enable` header.

<strong>Python</strong>

```python expandable
import os
import dashscope

# The following configuration is for the Singapore (ap-southeast-1) region. Replace {WorkspaceId} with your actual workspace ID. The region value varies by region.
# For the US (Virginia) region, set region to us-east-1.
client = dashscope.Client(
    # If you have not set an environment variable, replace the following line with your Model Studio API key: api_key="sk-xxx",
    # API keys are region-specific. To get an API key, see https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

PROMPT_TICKET_EXTRACTION = """
Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image.
You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?).
Return the data in JSON format as follows: {'invoice_number': 'xxx','departure_station': 'xxx', 'arrival_station': 'xxx', 'departure_date_and_time':'xxx', 'seat_number': 'xxx','ticket_price':'xxx', 'id_card_number': 'xxx', 'passenger_name': 'xxx'},
"""

messages = [
    {
        "role": "user",
        "content": [
            {
                "image": "https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg",
                # Minimum pixel threshold for the input image: images smaller than this are enlarged until the total pixels exceed min_pixels
                "min_pixels": 32 * 32 * 3,
                # Maximum pixel threshold for the input image: images larger than this are shrunk until the total pixels fall below max_pixels
                "max_pixels": 32 * 32 * 8192,
            },
            # When no built-in task is set, you can pass a prompt in the text field; if omitted, the default prompt is used: Please output only the text content from the image without any additional descriptions or formatting.
            {
                "type": "text",
                "text": PROMPT_TICKET_EXTRACTION
            }
        ]
    }
]
stream = client.multimodal.chat.create(
    model="qwen-vl-ocr-2025-11-20",
    messages=messages,
    stream=True,
    # Streaming output is incremental by default: each chunk contains only the newly generated content.
)

full_content = ""
print("Streaming output content:")
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content)
        full_content += delta.content
print(f"Full content: {full_content}")
```

<strong>Java</strong>

```java expandable
import java.util.*;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", "https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg");
        map.put("max_pixels", 8388608);
        map.put("min_pixels", 3072);
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map,
                        Collections.singletonMap("text", "Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image. You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?). Return the data in JSON format as follows: {\'invoice_number\': \'xxx\', \'departure_station\': \'xxx\', \'arrival_station\': \'xxx\', \'departure_date_and_time\':\'xxx\', \'seat_number\': \'xxx\',\'ticket_price\':\'xxx\', \'id_card_number\': \'xxx\', \'passenger_name\': \'xxx\'"))).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-ocr-2025-11-20")
                .message(userMessage)
                .incrementalOutput(true)
                .build();
        Flowable<MultiModalConversationResult> result = conv.streamCall(param);
        result.blockingForEach(item -> {
            try {
                List<Map<String, Object>> contentList = item.getOutput().getChoices().get(0).getMessage().getContent();
                if (!contentList.isEmpty()){
                    System.out.println(contentList.get(0).get("text"));
                }//
            } catch (Exception e){
                System.exit(0);
            }
        });
    }

    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}
```

<strong>curl</strong>

```bash expandable
curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--header 'X-DashScope-SSE: enable' \
--data '
{
    "model": "qwen-vl-ocr-2025-11-20",
    "input": {
        "messages": [
            {
              "role": "user",
              "content": [
                  {
                      "image": "https://img.alicdn.com/imgextra/i2/O1CN01ktT8451iQutqReELT_!!6000000004408-0-tps-689-487.jpg",
                      "min_pixels": 3072,
                      "max_pixels": 8388608
                  },
                  {"type": "text", "text": "Please extract the invoice number, train number, departure station, arrival station, departure date and time, seat number, seat class, ticket price, ID card number, and passenger name from the train ticket image. You must accurately extract the key information. Do not omit or fabricate information. Replace any single character that is blurry or obscured by strong light with an English question mark (?). Return the data in JSON format as follows: {\'invoice_number\': \'xxx\', \'departure_station\': \'xxx\', \'arrival_station\': \'xxx\', \'departure_date_and_time\':\'xxx\', \'seat_number\': \'xxx\',\'ticket_price\':\'xxx\', \'id_card_number\': \'xxx\', \'passenger_name\': \'xxx\'}"}
              ]
            }
        ]
    },
    "parameters": {
        "incremental_output": true
    }
}'
```

## Request parameters <span id="2a1c410015otp" /> <span id="2ed5ee7377fum" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Required</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>model</code></p></td><td><p>string</p></td><td><p>Yes</p></td><td><p>Model name. See <a href="/en/model-studio/models">Recommended models</a> for supported models.</p></td></tr><tr><td><p><code>input.messages</code></p></td><td><p>array</p></td><td><p>Yes</p></td><td><p>An array of message objects.</p></td></tr></tbody></table>

<strong>Message object</strong>

Each message requires a `role` (must be `user`) and a `content` field (string or array). Use a string for text-only input. Use an array if the input includes image data, with these fields:

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Required</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>image</code></p></td><td><p>string</p></td><td><p>No</p></td><td><p>URL, Base64 Data URL, or local path of the image. See <a href="/en/model-studio/qwen-vl-ocr#ea4e1d92dbry2">Passing local files</a>.</p></td></tr><tr><td><p><code>text</code></p></td><td><p>string</p></td><td><p>No</p></td><td><p>The text prompt. Default: <code>"Please output only the text content from the image without any additional descriptions or formatting"</code>. Not required when using a built-in task.</p></td></tr><tr><td><p><code>enable\_rotate</code></p></td><td><p>boolean</p></td><td><p>No</p></td><td><p>Set to <code>true</code> to correct skewed images. Default: <code>false</code>.</p></td></tr><tr><td><p><code>min\_pixels</code></p></td><td><p>integer</p></td><td><p>No</p></td><td><p>Minimum pixel threshold. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_e15b177d">Image resolution control</a>.</p></td></tr><tr><td><p><code>max\_pixels</code></p></td><td><p>integer</p></td><td><p>No</p></td><td><p>Maximum pixel threshold. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_e15b177d">Image resolution control</a>.</p></td></tr></tbody></table>

<strong>Generation parameters</strong>

Set these in the `parameters` object for HTTP calls.

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Default</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>max\_tokens</code></p></td><td><p>integer</p></td><td><p>Varies</p></td><td><p>Maximum tokens in the output. See <a href="/en/model-studio/qwen-vl-ocr-api-reference#section_bb77eb38">Output token limits</a>. In the Java SDK, use <code>maxTokens</code>.</p></td></tr><tr><td><p><code>stream</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>Enable streaming output. Python SDK only. For Java, use <code>streamCall</code>. For HTTP, set <code>X-DashScope-SSE: enable</code>.</p></td></tr><tr><td><p><code>incremental\_output</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>When <code>true</code> (recommended), each chunk contains only new content. When <code>false</code>, each chunk contains the full sequence so far. In the Java SDK, use <code>incrementalOutput</code>.</p></td></tr><tr><td><p><code>temperature</code></p></td><td><p>float</p></td><td><p><code>0.01</code></p></td><td><p>Controls output diversity. Range: \[0, 2).</p></td></tr><tr><td><p><code>top\_p</code></p></td><td><p>float</p></td><td><p><code>0.001</code></p></td><td><p>Nucleus sampling threshold. Range: (0, 1.0]. Set either <code>temperature</code> or <code>top\_p</code>, not both.</p></td></tr><tr><td><p><code>top\_k</code></p></td><td><p>integer</p></td><td><p><code>1</code></p></td><td><p>Limits the candidate token set during sampling. If the value is None or greater than 100, the top\_k policy is not enabled, and only the top\_p policy takes effect. Must be >= 0.</p></td></tr><tr><td><p><code>repetition\_penalty</code></p></td><td><p>float</p></td><td><p><code>1.0</code></p></td><td><p>Penalty for repeated sequences. Values above 1.0 reduce repetition.</p></td></tr><tr><td><p><code>presence\_penalty</code></p></td><td><p>float</p></td><td><p><code>0.0</code></p></td><td><p>Controls content repetition. Range: \[-2.0, 2.0].</p></td></tr><tr><td><p><code>seed</code></p></td><td><p>integer</p></td><td><p>--</p></td><td><p>Ensures reproducible results. Range: \[0, 2^31 - 1].</p></td></tr><tr><td><p><code>logprobs</code></p></td><td><p>boolean</p></td><td><p><code>false</code></p></td><td><p>Set to <code>true</code> to return log probabilities. Supported models: <code>qwen-vl-ocr-2025-11-20</code> and later. In the Java SDK, use the same name. For HTTP, place in <code>parameters</code>.</p></td></tr><tr><td><p><code>top\_logprobs</code></p></td><td><p>integer</p></td><td><p><code>0</code></p></td><td><p>Number of most likely tokens per step. Range: \[0, 5]. Only effective when <code>logprobs</code> is <code>true</code>. In the Java SDK, use <code>topLogprobs</code>. For HTTP, place in <code>parameters</code>.</p></td></tr><tr><td><p><code>stop</code></p></td><td><p>string or array</p></td><td><p>--</p></td><td><p>Stop words or token IDs. Generation stops when a specified string or <code>token\_id</code> appears. Do not mix strings and <code>token\_id</code>s in the same array.</p></td></tr></tbody></table>

<strong>Built-in task parameters (</strong>`ocr_options`<strong>)</strong>

When using a built-in task, pass `ocr_options` in `parameters` (HTTP), as a keyword argument (Python SDK), or via the `OcrOptions` builder (Java SDK).

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /><col style={{ width: "25%" }} /></colgroup><thead><tr><th><p><span><strong>Parameter</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Required</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>ocr\_options.task</code></p></td><td><p>string</p></td><td><p>Yes</p></td><td><p>Built-in task name. Valid values: <code>text\_recognition</code>, <code>key\_information\_extraction</code>, <code>document\_parsing</code>, <code>table\_parsing</code>, <code>formula\_recognition</code>, <code>multi\_lan</code>, <code>advanced\_recognition</code>.</p></td></tr><tr><td><p><code>ocr\_options.task\_config</code></p></td><td><p>object</p></td><td><p>No</p></td><td><p>Configuration for <code>key\_information\_extraction</code>.</p></td></tr><tr><td><p><code>ocr\_options.task\_config.result\_schema</code></p></td><td><p>object</p></td><td><p>No</p></td><td><p>JSON object specifying fields to extract. Keys are field names, values are optional descriptions for improved accuracy. Supports up to three nesting levels.</p></td></tr></tbody></table>

`result_schema`<strong>example</strong>:

```json
"result_schema": {
     "invoice_number": "The unique identification number of the invoice, usually a combination of numbers and letters.",
     "issue_date": "The date the invoice was issued. Extract it in YYYY-MM-DD format, for example, 2023-10-26.",
     "seller_name": "The full company name of the seller shown on the invoice.",
     "total_amount": "The total amount on the invoice, including tax. Extract the numerical value and keep two decimal places, for example, 123.45."
}
```

> In the Java SDK, this parameter is `OcrOptions`. The minimum DashScope Python SDK version is 2.0.1. The minimum Java SDK version is 2.18.4. For `advanced_recognition`, Java SDK >= 2.21.8 is required.

## Response <span id="0e1c44902ea1e" /> <span id="f619aef49a7vf" />

The DashScope API uses identical response format for streaming and non-streaming output.

> The following is the raw response returned by the HTTP API. On call failure, the Python SDK raises a `DashScopeError` exception; you can retrieve error details from the exception properties `e.status_code`/`e.code`/`e.message`/`e.request_id`. The Java SDK throws an exception on failure, with `status_code` and `message` in the exception message.

````json expandable
{
  "request_id": "8f8c0f6e-6805-4056-bb65-d26d66080a41",
  "output": {
    "text": null,
    "finish_reason": null,
    "choices": [
      {
        "finish_reason": "stop",
        "message": {
          "role": "assistant",
          "content": [
            {
              "ocr_result": {
                "kv_result": {
                  "price_excluding_tax": "230769.23",
                  "invoice_code": "142011726001",
                  "organization_code": "null",
                  "buyer_name": "Cai Yingshi",
                  "seller_name": "null"
                }
              },
              "text": "```json\n{\n    \"price_excluding_tax\": \"230769.23\",\n    \"invoice_code\": \"142011726001\",\n    \"organization_code\": \"null\",\n    \"buyer_name\": \"Cai Yingshi\",\n    \"seller_name\": \"null\"\n}\n```"
            }
          ]
        }
      }
    ],
    "audio": null
  },
  "usage": {
    "input_tokens": 926,
    "output_tokens": 72,
    "characters": 0,
    "image_tokens": 754,
    "input_tokens_details": {
      "image_tokens": 754,
      "text_tokens": 172
    },
    "output_tokens_details": {
      "text_tokens": 72
    },
    "total_tokens": 998
  }
}
````

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /><col style={{ width: "33.333333%" }} /></colgroup><thead><tr><th><p><span><strong>Field</strong></span></p></th><th><p><span><strong>Type</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>request\_id</code></p></td><td><p>string</p></td><td><p>Unique request identifier. In the Java SDK, this is <code>requestId</code>.</p></td></tr><tr><td><p><code>output.text</code></p></td><td><p>string</p></td><td><p>Always <code>null</code>.</p></td></tr><tr><td><p><code>output.finish\_reason</code></p></td><td><p>string</p></td><td><p><code>null</code> during generation, <code>stop</code> when complete, <code>length</code> when truncated.</p></td></tr><tr><td><p><code>output.choices\[].finish\_reason</code></p></td><td><p>string</p></td><td><p>Same values as <code>output.finish\_reason</code>.</p></td></tr><tr><td><p><code>output.choices\[].message.role</code></p></td><td><p>string</p></td><td><p>Always <code>assistant</code>.</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].text</code></p></td><td><p>string</p></td><td><p>Extracted text or formatted output from the model.</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result</code></p></td><td><p>object</p></td><td><p>Returned for built-in tasks (<code>key\_information\_extraction</code>, <code>advanced\_recognition</code>).</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result.kv\_result</code></p></td><td><p>object</p></td><td><p>Key-value extraction results (for <code>key\_information\_extraction</code>).</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result.words\_info</code></p></td><td><p>array</p></td><td><p>Text line results with positional data (for <code>advanced\_recognition</code>).</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result.words\_info\[].rotate\_rect</code></p></td><td><p>array</p></td><td><p><code>\[center\_x, center\_y, width, height, angle]</code> -- rotated bounding rectangle.</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result.words\_info\[].location</code></p></td><td><p>array</p></td><td><p><code>\[x1, y1, x2, y2, x3, y3, x4, y4]</code> -- four vertices clockwise from the top-left.</p></td></tr><tr><td><p><code>output.choices\[].message.content\[].ocr\_result.words\_info\[].text</code></p></td><td><p>string</p></td><td><p>Content of the text line.</p></td></tr><tr><td><p><code>output.choices\[].message.logprobs</code></p></td><td><p>object</p></td><td><p>Log probability information, returned when <code>logprobs</code> is <code>true</code>.</p></td></tr><tr><td><p><code>usage.input\_tokens</code></p></td><td><p>integer</p></td><td><p>Input token count.</p></td></tr><tr><td><p><code>usage.output\_tokens</code></p></td><td><p>integer</p></td><td><p>Output token count.</p></td></tr><tr><td><p><code>usage.characters</code></p></td><td><p>integer</p></td><td><p>Fixed to 0.</p></td></tr><tr><td><p><code>usage.total\_tokens</code></p></td><td><p>integer</p></td><td><p>Sum of <code>input\_tokens</code> and <code>output\_tokens</code>.</p></td></tr><tr><td><p><code>usage.image\_tokens</code></p></td><td><p>integer</p></td><td><p>Tokens corresponding to the image input.</p></td></tr><tr><td><p><code>usage.input\_tokens\_details.image\_tokens</code></p></td><td><p>integer</p></td><td><p>Image input tokens.</p></td></tr><tr><td><p><code>usage.input\_tokens\_details.text\_tokens</code></p></td><td><p>integer</p></td><td><p>Text input tokens.</p></td></tr><tr><td><p><code>usage.output\_tokens\_details.text\_tokens</code></p></td><td><p>integer</p></td><td><p>Text output tokens.</p></td></tr></tbody></table>

## Supported models <span id="h2_00ee57d9" /> <span id="section_dd5c1d57" />

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "50%" }} /><col style={{ width: "50%" }} /></colgroup><thead><tr><th><p><span><strong>Model</strong></span></p></th><th><p><span><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p><code>qwen3.5-ocr</code></p></td><td><p>Based on the Qwen3.5 architecture. Faster, more accurate. Major improvements in information extraction, text positioning, and multi-turn conversation support. Context length extended to 128K.</p></td></tr><tr><td><p><code>qwen-vl-ocr-2025-11-20</code></p></td><td><p>Latest dated snapshot.</p></td></tr><tr><td><p><code /></p></td><td><p>Previous version.</p></td></tr><tr><td><p><code>qwen-vl-ocr-2025-11-20</code></p></td><td><p>Previous version.</p></td></tr><tr><td><p><code>qwen-vl-ocr-2024-10-28</code></p></td><td><p>Previous version.</p></td></tr><tr><td><p><code>qwen-vl-ocr</code></p></td><td><p>Base model.</p></td></tr></tbody></table>

## Error codes <span id="97e145aeabbwf" /> <span id="7d37b25732sjf" />

If a model call returns an error, see [Error messages](https://www.alibabacloud.com/help/model-studio/error-code) to resolve the issue.
