Skip to main content
More

Upload a file and get a temporary URL

Upload a local file to free temporary storage and get an oss:// URL for multimodal, image, video, or audio models.

When you call multimodal, image, video, or audio models, you often need to pass a file URL. QwenCloud provides free temporary storage: upload a local file, get a URL, and use that URL in the model call. The URL is valid for 48 hours.
Temporary storage is available in Singapore (ap-southeast-1), China North 2 (Beijing) (cn-beijing), and China (Hong Kong) (cn-hongkong).

Usage limits

  • Files are bound to a model: You must specify a model name when uploading, and the model must be the same model you call later. Different models cannot share a file. Each model also has its own file size limit; a file that exceeds the limit fails to upload.
  • Files are bound to an account: The API key used for upload and the API key used for the model call must belong to the same QwenCloud account. The uploaded file can be used only by that account and that model. Other accounts and other models cannot read it.
  • Files expire after 48 hours: Uploaded files are deleted automatically after 48 hours. Finish your model calls within that window.
  • Uploaded files are write-only: After upload, you cannot query, modify, or download the file. It can be used only as a URL parameter in a model call.
  • Upload policy rate limit: The upload policy endpoint is limited to 100 QPS per account and model. Requests above the limit fail.
  • A temporary URL expires after 48 hours and cannot be renewed. Do not use it in production.
  • The upload policy endpoint is limited to 100 QPS without quota increases. Do not use it for production workloads, high concurrency, or load testing.
  • For production, use durable storage such as Alibaba Cloud OSS so that files remain available and rate limits do not apply.

How it works

  1. Get a temporary URL: Upload an image, video, or audio file as described in Step 1, and get a URL that starts with oss://.
  2. Call the model: Pass the temporary URL as described in Step 2. This step is required; otherwise the request fails.

Step 1: Get a temporary URL

  • Option 1: Upload with code
  • Option 2: Upload with the CLI
The Python and Java samples below handle the upload for you. Specify the model and the file, and the sample returns the temporary URL.PrerequisitesGet an API key, then set the API key as an environment variable.

Sample code

  • Python
  • Java
Environment
  • Python 3.8 or later is recommended.
  • Install the dependencies:
pip install -U requests
Input parameters
  • api_key: QwenCloud API key.
  • model_name: The model that will use the file, such as qwen3-vl-plus.
  • file_path: Path to the local file to upload (image, video, or audio).
import os
import requests
from pathlib import Path
from datetime import datetime, timedelta

# 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"

def get_upload_policy(api_key, model_name):
  """Get an upload policy."""
  url = f"{BASE_URL}/api/v1/uploads"
  headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
  }
  params = {
    "action": "getPolicy",
    "model": model_name
  }

  response = requests.get(url, headers=headers, params=params)
  if response.status_code != 200:
    raise Exception(f"Failed to get upload policy: {response.text}")

  return response.json()['data']

def upload_file_to_oss(policy_data, file_path):
  """Upload the file to temporary OSS storage."""
  file_name = Path(file_path).name
  key = f"{policy_data['upload_dir']}/{file_name}"

  with open(file_path, 'rb') as file:
    files = {
      'OSSAccessKeyId': (None, policy_data['oss_access_key_id']),
      'Signature': (None, policy_data['signature']),
      'policy': (None, policy_data['policy']),
      'x-oss-object-acl': (None, policy_data['x_oss_object_acl']),
      'x-oss-forbid-overwrite': (None, policy_data['x_oss_forbid_overwrite']),
      'key': (None, key),
      'success_action_status': (None, '200'),
      'file': (file_name, file)
    }

    response = requests.post(policy_data['upload_host'], files=files)
    if response.status_code != 200:
      raise Exception(f"Failed to upload file: {response.text}")

  return f"oss://{key}"

def upload_file_and_get_url(api_key, model_name, file_path):
  """Upload a file and return its temporary URL."""
  # 1. Get an upload policy. This endpoint is rate-limited.
  policy_data = get_upload_policy(api_key, model_name)
  # 2. Upload the file to OSS.
  oss_url = upload_file_to_oss(policy_data, file_path)

  return oss_url

# Example
if __name__ == "__main__":
  api_key = os.getenv("DASHSCOPE_API_KEY")
  if not api_key:
    raise Exception("Set the DASHSCOPE_API_KEY environment variable.")

  model_name = "qwen3-vl-plus"

  # Replace with the path to your file.
  file_path = "/tmp/cat.png"

  try:
    public_url = upload_file_and_get_url(api_key, model_name, file_path)
    expire_time = datetime.now() + timedelta(hours=48)
    print(f"File uploaded. It expires in 48 hours at {expire_time.strftime('%Y-%m-%d %H:%M:%S')}.")
    print(f"Temporary URL: {public_url}")
    print("When you use an oss:// URL over HTTP, add the X-DashScope-OssResourceResolve: enable request header.")

  except Exception as e:
    print(f"Error: {str(e)}")
Output
File uploaded. It expires in 48 hours at 2026-10-24 17:36:15.
Temporary URL: oss://dashscope-instant/xxx/2026-10-22/xxx/cat.png
When you use an oss:// URL over HTTP, add the X-DashScope-OssResourceResolve: enable request header.
When you call a model over HTTP with a temporary URL, you must add the X-DashScope-OssResourceResolve: enable request header. See Call over HTTP.

Step 2: Call a model with the temporary URL

Requirements

  • File format: The URL must be generated as described above and must start with oss://.
  • File not expired: The URL must be used within 48 hours of upload.
  • Same model: The model you call must be exactly the model you specified during upload.
  • Same account: The API key used for the model call must belong to the same QwenCloud account as the API key used for upload.

Option 1: Call over HTTP

When you call the API with curl, Postman, or any other HTTP client, follow these rules:
  • With a temporary URL, you must add X-DashScope-OssResourceResolve: enable to the request headers.
  • Without this header, the service cannot resolve the oss:// URL and the request fails. For the error message, see Error codes.
  • Request example
  • Response example
This example calls qwen3-vl-plus to describe an image.
Replace oss://... with your temporary URL, or the request fails.
# 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
curl -X POST https://ap-southeast-1.maas.qwencloudapi.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-OssResourceResolve: enable' \
-d '{
  "model": "qwen3-vl-plus",
  "messages": [{
      "role": "user",
      "content":
      [{"type": "text","text": "What is in this image?"},
       {"type": "image_url","image_url": {"url": "oss://dashscope-instant/xxx/2026-10-22/xxxx/cat.png"}}]
    }]
}'

Option 2: Call with the DashScope SDK

You can also use the DashScope Python or Java SDK.
  • Pass the URL directly: Pass the oss:// URL as the file parameter in the SDK call.
  • No header handling: The SDK adds the required header automatically.
Not every model supports SDK calls. Check the model's API reference. The OpenAI SDK is not supported.
  • Python
  • Java
PrerequisitesInstall DashScope Python SDK version 1.24.0 or later.Sample codeThis example calls qwen3-vl-plus to describe an image. The code applies to the qwen-vl and omni model families.
  • Request example
  • Response example
Replace oss://... in the image parameter with your temporary URL, or the request fails.
import os
import dashscope

# 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
dashscope.base_http_api_url = "https://ap-southeast-1.maas.qwencloudapi.com/api/v1"

messages = [
  {
    "role": "system",
    "content": [{"text": "You are a helpful assistant."}]
  },
  {
    "role": "user",
    "content": [
      {"image": "oss://dashscope-instant/xxx/2026-10-22/xxxx/cat.png"},
      {"text": "What is in this image?"}]
  }]

# If the environment variable is not set, replace the next line with api_key="sk-xxx".
api_key = os.getenv('DASHSCOPE_API_KEY')

response = dashscope.MultiModalConversation.call(
  api_key=api_key,
  model='qwen3-vl-plus',
  messages=messages
)

print(response)

Appendix: API details

The code samples and CLI above perform the following three steps for you. This section documents each step.

Step 1: Get an upload policy

Prerequisites Get an API key and set it as an environment variable. Request The following uses the Singapore (ap-southeast-1) endpoint. For another region, replace ap-southeast-1 and use an API key from that region. See Regions and endpoints.
GET https://ap-southeast-1.maas.qwencloudapi.com/api/v1/uploads
The upload policy endpoint is limited to 100 QPS per QwenCloud account and model, and temporary storage cannot be expanded. For production or high-concurrency workloads, use a storage service such as Alibaba Cloud OSS.
Request parameters
LocationFieldTypeRequiredDescriptionExample
HeaderContent-TypestringYesRequest content type: application/json.application/json
HeaderAuthorizationstringYesQwenCloud API key, prefixed with Bearer.Bearer sk-ws-xxx
QueryactionstringYesAction to perform. Use getPolicy.getPolicy
QuerymodelstringYesName of the model that will use the file.qwen3-vl-plus
Response parameters
FieldTypeDescriptionExample
request_idstringUnique request identifier.7574ee8f-...-11c33ab46e51
dataobjectUpload policy.-
data.policystringUpload policy.eyJl...1ZSJ9XX0=
data.signaturestringSignature of the upload policy.g5K...d40=
data.upload_dirstringDirectory for the uploaded file.dashscope-instant/xxx/2026-10-22/xxxx
data.upload_hoststringHost to which the file is uploaded.https://dashscope-file-mgr-prod.oss-ap-southeast-1.aliyuncs.com
data.expire_in_secondsstringPolicy validity in seconds. After it expires, call this endpoint again for a new policy.300
data.max_file_size_mbstringMaximum file size in MB. The value depends on the model.1024
data.capacity_limit_mbstringDaily upload capacity for the account, in MB.999999999
data.oss_access_key_idstringAccess key used for the upload.LTAxxx
data.x_oss_object_aclstringAccess control for the uploaded file. private means private.private
data.x_oss_forbid_overwritestringWhether a file with the same name can be overwritten. true means it cannot.true
Request example
# 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
curl --location 'https://ap-southeast-1.maas.qwencloudapi.com/api/v1/uploads?action=getPolicy&model=qwen3-vl-plus' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json'
If the API key is not set as an environment variable, replace $DASHSCOPE_API_KEY with the key, for example --header "Authorization: Bearer sk-ws-xxx".
Response example
{
  "request_id": "52f4383a-c67d-9f8c-xxxxxx",
  "data": {
    "policy": "eyJl...1ZSJ=",
    "signature": "eWy...=",
    "upload_dir": "dashscope-instant/xxx/2026-10-22/xxx",
    "upload_host": "https://dashscope-file-mgr-prod.oss-ap-southeast-1.aliyuncs.com",
    "expire_in_seconds": 300,
    "max_file_size_mb": 1024,
    "capacity_limit_mb": 999999999,
    "oss_access_key_id": "LTA...",
    "x_oss_object_acl": "private",
    "x_oss_forbid_overwrite": "true"
  }
}

Step 2: Upload the file to temporary storage

Prerequisites
  • You have an upload policy.
  • The upload policy has not expired. If it has, call Step 1 again for a new policy.
    To check the validity period, read data.expire_in_seconds in the Step 1 response.
Request
POST {data.upload_host}
Replace {data.upload_host} with the data.upload_host value from Step 1.
Request parameters
LocationFieldTypeRequiredDescriptionExample
HeaderContent-TypestringNoForm submissions use multipart/form-data. The browser or HTTP client adds boundary automatically.multipart/form-data; boundary=9431149156168
form-dataOSSAccessKeyIdtextYesThe data.oss_access_key_id value from Step 1.LTAm5xxx
form-datapolicytextYesThe data.policy value from Step 1.g5K...d40=
form-dataSignaturetextYesThe data.signature value from Step 1.Sm/tv7DcZuTZftFVvt5yOoSETsc=
form-datakeytextYesThe data.upload_dir value from Step 1, followed by /<file name>.dashscope-instant/xxx/2026-10-22/xxx/cat.png
form-datax-oss-object-acltextYesThe data.x_oss_object_acl value from Step 1.private
form-datax-oss-forbid-overwritetextYesThe data.x_oss_forbid_overwrite value from Step 1.true
form-datasuccess_action_statustextNoUse 200 so the endpoint returns HTTP 200 after a successful upload.200
form-datafilefileYesThe file or text content. Upload one file per request. file must be the last form field; the other fields can appear in any order.file=@"/tmp/cat.png"
Response A successful call returns no content. Request example
curl --location 'https://dashscope-file-mgr-prod.oss-ap-southeast-1.aliyuncs.com' \
--form 'OSSAccessKeyId="LTAm5xxx"' \
--form 'Signature="Sm/tv7DcZuTZftFVvt5yOoSETsc="' \
--form 'policy="eyJleHBpcmF0aW9 ... ... ... dHJ1ZSJ9XX0="' \
--form 'x-oss-object-acl="private"' \
--form 'x-oss-forbid-overwrite="true"' \
--form 'key="dashscope-instant/xxx/2026-10-22/xxx/cat.png"' \
--form 'success_action_status="200"' \
--form 'file=@"/tmp/cat.png"'

Step 3: Build the file URL

The file URL is oss:// followed by the key you used in Step 2. The URL is valid for 48 hours.
oss://dashscope-instant/xxx/2026-10-22/xxxx/cat.png

Error codes

If a call fails, see Error messages. The following status codes are specific to this feature.
HTTP statusError codeError messageMeaning
400invalid_parameter_errorInternalError.Algo.InvalidParameter: The provided URL does not appear to be valid. Ensure it is correctly formatted.Invalid URL. Check the URL. For a temporary file URL, make sure the request includes the X-DashScope-OssResourceResolve: enable header.
400InvalidParameter.DataInspectionThe media format is not supported or incorrect for the data inspection.Possible causes: (1) the request header is missing X-DashScope-OssResourceResolve: enable; (2) the image format does not meet the model's requirements. For details, see Error messages.
403AccessDeniedInvalid according to Policy: Policy expired.The upload policy expired. Call the upload policy endpoint again for a new policy.
429Throttling.RateQuotaRequests rate limit exceeded, please try again later.The request rate exceeded the limit. The upload policy endpoint allows 100 QPS per account and model. Lower the request rate or move to your own storage service such as OSS.

FAQ

Why does a call with an oss:// URL fail?

Check the following:
  1. Request header: If you call the API over HTTP (curl, Postman), you must add X-DashScope-OssResourceResolve: enable to the headers. Without it, the service cannot resolve the OSS internal protocol. See Call over HTTP.
  2. URL validity: An oss:// URL is temporary. Make sure it was created within the last 48 hours. If it expired, upload the file again.

Can I use different API keys for the upload and the model call?

File storage and access are managed at the QwenCloud account level, and API keys are only credentials for that account. Different API keys under the same account work. API keys from different accounts cannot read the file because accounts are isolated. Make sure the API key used for upload and the API key used for the model call belong to the same QwenCloud account.