Skip to main content
Tool calling

PDF understanding

PDF understanding enables the model to parse and comprehend PDF documents, extracting text and images for analysis. You can pass PDF files via URL or Base64 encoding.

Parse text and images in PDF documents with Chat Completions, the Responses API, DashScope, or the Anthropic-compatible API.

Supported models

qwen4-max-preview (Token Plan only), qwen3.8-max, qwen3.8-max-0902, qwen3.8-flash, qwen3.8-27b qwen3.8-27b supports PDF understanding only through Chat Completions or DashScope in China North 2 (Beijing).

Quick start

Run the following code to send a PDF file to the model. Get a QwenCloud API key and configure it as an environment variable.
  • OpenAI compatible
  • DashScope
  • Responses API
from openai import OpenAI
import os

client = OpenAI(
    # If the environment variable is not configured, replace it with your QwenCloud API key: api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Singapore (ap-southeast-1). For another region, replace ap-southeast-1 in the URL.
    # API keys are region-specific. See https://docs.qwencloud.com/developer-guides/getting-started/regions
    base_url="https://ap-southeast-1.maas.qwencloudapi.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "file",
                    "file": {
                        "file_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20260616/qmycjl/1506.02640v5.pdf"
                    }
                },
                {
                    "type": "text",
                    "text": "Summarize this PDF document"
                }
            ]
        }
    ],
    stream=True,
    stream_options={"include_usage": True},
    extra_body={"include_tool_usage": True}
)

for chunk in completion:
    if not chunk.choices:
        print(f"\nUsage: {chunk.usage}")
        continue
    delta = chunk.choices[0].delta
    if hasattr(delta, "content") and delta.content:
        print(delta.content, end="", flush=True)

Base64 input

If you cannot provide a file URL, you can also pass the PDF file as a Base64-encoded string. When using file_data, the filename field is required.
Base64 encoding increases the data size by about 1/3. For example, a 150 MB file becomes roughly 200 MB after encoding, which exceeds the request body size limit. For large files, pass the file by URL instead.
  • OpenAI compatible
  • DashScope
  • Anthropic
Python
import base64
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Singapore (ap-southeast-1). For another region, replace ap-southeast-1 in the URL.
    # API keys are region-specific. See https://docs.qwencloud.com/developer-guides/getting-started/regions
    base_url="https://ap-southeast-1.maas.qwencloudapi.com/compatible-mode/v1",
)

# Read and encode the PDF file
with open("report.pdf", "rb") as f:
    pdf_base64 = base64.b64encode(f.read()).decode("utf-8")

completion = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "file",
                    "file": {
                        "file_data": f"data:application/pdf;base64,{pdf_base64}",
                        "filename": "report.pdf"
                    }
                },
                {
                    "type": "text",
                    "text": "What are the key findings in this report?"
                }
            ]
        }
    ]
)

print(completion.choices[0].message.content)

Request parameters

The following parameter table applies to Chat Completions. The Responses API uses type: "input_file" and file_url. The Anthropic-compatible API uses type: "document" and sets type: "base64", media_type: "application/pdf", and data (a Base64 string without the Data URI prefix) in source. DashScope passes the file as an element containing file_url or file_data in the content array.
The URL field in the protocol only accepts a string. A list (array) of URLs is not supported.
OpenAI-compatible format:
ParameterTypeRequiredDescription
file_urlstringOne of the two requiredThe download URL of the PDF file. Mutually exclusive with file_data.
file_datastringOne of the two requiredBase64-encoded PDF input in the format data:application/pdf;base64,xxx. Mutually exclusive with file_url.
filenamestringConditionally requiredThe file name. Required when using file_data.
file_formatstringNoThe file format. Currently only pdf is supported. Defaults to pdf.

Limits

ItemLimit
Maximum file size150 MB
Maximum page count256 pages
PDF parsing may take longer than a regular text request. The first-token timeout is up to 300 seconds. We recommend using streaming output to get results in real time and avoid long waits.

Billing

Billing involves the following:
  • Model input tokens: Text and images parsed from the PDF are counted as input tokens, billed at the model's standard input token rate. For per-model input and output token prices, see Pricing.
  • Document parsing fee: Charged per page of the PDF document parsed, corresponding to the metering item document_parsing (pdf). Unit prices vary by region: China North 2 (Beijing) $0.003 per page, Singapore $0.0033 per page.

View PDF page count

For Chat Completions and the Responses API, pass include_tool_usage: true at the top level of the request body and read the page count from usage.x_tools.pdf_page_parser.count. For DashScope, read it from usage.plugins.pdf_page_parser.count. The Anthropic-compatible API returns the page count at the top level of the response in x_tools.pdf_page_parser.count. If the parse count is not returned, it does not mean that no parsing fee was incurred.
// Returned only when "include_tool_usage": true is passed at the top level of the request body.
// For the OpenAI Python SDK, pass it via extra_body={"include_tool_usage": True}.
// When using HTTP/curl directly, place it at the top level — do not nest it inside extra_body or stream_options.
{
    "usage": {
        "x_tools": {
            "pdf_page_parser": {
                "count": 10,
                "strategy": "normal"
            }
        }
    }
}

Error codes

If a call fails, see Error messages.
PDF understanding - QwenCloud