Deepseek.ai is an independent website and is not affiliated with, sponsored by, or endorsed by Hangzhou DeepSeek Artificial Intelligence Co., Ltd.

    API guide · August 23, 2026 · Independent Guide

    DeepSeek Vision API: Sending Images to deepseek-v4-flash-vision-exp

    By the Deep Seek AI editorial desk · August 23, 2026 · 8 min read

    Last verified: August 23, 2026Reviewed by deepseek.ai editorial desk

    In short: DeepSeek's vision model deepseek-v4-flash-vision-exp accepts images alongside text through the same OpenAI-compatible Chat Completions endpoint you already use. Three input methods, a hard ceiling of 384 tokens per image, and up to 600 images per request.

    One model only — and it is experimental

    Images work exclusively with deepseek-v4-flash-vision-exp. Any other DeepSeek model returns a 400 with "This model does not support image". The -exp suffix signals experimental status, so keep the model string in configuration, not scattered through your code.

    What DeepSeek vision can do

    The vision model takes images in the same message as your text prompt, which makes the obvious workloads immediately available: describing photographs, reading text out of screenshots, and analysing charts and diagrams. Image format is detected from the actual file content — JPEG, PNG, GIF and WebP — not from the extension or the declared MIME type, so a mislabelled upload still works as long as the bytes are valid.

    The interesting part for anyone building a pipeline is the batch ceiling: a single request may carry up to 600 images. Combined with the flat token cap per image, document triage and screenshot classification become genuinely cheap rather than merely possible.

    The three ways to send an image

    All three use the standard OpenAI-compatible Chat Completions format, where content is an array of blocks instead of a plain string. The same three methods exist in the Responses API, where images travel in input_image content parts. Base URL for everything below: https://api.deepseek.com.

    1. Base64 inline (local files)

    Encode the file and embed it as a data: URL. Simplest option for local images; the encoded bytes count toward the 48 MiB request body limit.

    import base64
    from openai import OpenAI
    
    client = OpenAI(api_key="<DeepSeek API Key>", base_url="https://api.deepseek.com")
    
    with open("image.jpg", "rb") as f:
        b64 = base64.b64encode(f.read()).decode("utf-8")
    
    response = client.chat.completions.create(
        model="deepseek-v4-flash-vision-exp",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": "What is in this image?"},
                    {
                        "type": "image_url",
                        "image_url": {"url": f"data:image/jpeg;base64,{b64}"},
                    },
                ],
            }
        ],
    )
    print(response.choices[0].message.content)

    2. External image URL

    Pass a publicly reachable http(s) link and DeepSeek downloads the image for you. The URL must be at most 8,192 characters, the file at most 32 MiB, and the download must finish inside 60 seconds — otherwise fall back to base64 or the Files API.

    response = client.chat.completions.create(
        model="deepseek-v4-flash-vision-exp",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": "Describe this image."},
                    {
                        "type": "image_url",
                        "image_url": {"url": "https://example.com/image.jpg"},
                    },
                ],
            }
        ],
    )

    3. Files API reference

    Upload once, reference the returned file_id (shaped file-api-…) as often as you like. This is the right choice for reused images, and the only route for images above 32 MiB — Files API images may reach 64 MiB and skip the per-image inline check.

    response = client.chat.completions.create(
        model="deepseek-v4-flash-vision-exp",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": "What is in this image?"},
                    {"type": "file", "file_id": "file-api-xxxxxxxxxxxxxxxx"},
                ],
            }
        ],
    )

    A file block can alternatively carry the image inline as base64 through file_data plus filename. file_data and file_id are mutually exclusive.

    Detail levels: the cheapest knob you have

    For image_url inputs you can set an optional detail field that controls how the image is processed before inference.

    ValueBehaviour
    lowThe image is downscaled to 512×512 before inference. Faster and cheaper when fine visual detail does not matter.
    highKeeps the original image. Provided for OpenAI compatibility; equivalent to original.
    originalKeeps the original image.
    autoAutomatic selection. Currently equivalent to original.

    If your task is coarse recognition — "is this a receipt or an invoice?" — set detail: "low" and let DeepSeek downscale to 512×512. Keep original for small print, dense tables and OCR-style work.

    Token usage: 384 tokens per image, maximum

    Images become tokens based on their dimensions, billed together with your text tokens. Before inference every image is resized automatically: below roughly 384×384 total pixels it is scaled up preserving aspect ratio; larger images are scaled down preserving aspect ratio to roughly the pixel count of an 800×800 image.

    The practical consequence is an upper bound of 384 tokens per image. A 2000×2000 photo and a 5000×5000 scan cost the same, so there is no billing reason to downscale before upload — only a bandwidth one. In multi-image requests each image is counted independently under exactly the same rule; there is no separate multi-image formula.

    Every documented limit

    LimitValue
    Supported image formatsJPEG, PNG, GIF, WebP (detected from file content, not the file name or MIME type)
    External URL length8,192 characters
    Request body size48 MiB
    Max single image (base64 or external URL)32 MiB
    Max single image (Files API file_id)64 MiB
    Max images per request600
    Max total image size per request64 MiB without file_id images; up to 200 MiB including file_id images
    Max image dimension8,192 px per side — drops to 4,096 px per side when a request contains 15 or more images
    External image download timeout60 seconds

    Restrictions that will bite you

    • User messages only. An image inside a system or assistant message returns a 400. If you replay conversation history containing assistant-side images, strip them.
    • Vision model only. Non-vision models reject images with a 400 and "This model does not support image".
    • Reserved placeholder token. User text containing the reserved image placeholder token is rejected with a 400.
    • Dimension cliff at 15 images. The 8,192 px per-side maximum drops to 4,096 px per side as soon as a request contains 15 or more images — a surprisingly easy way to break a working batch job by adding one more page.

    Using images through the Anthropic-compatible endpoint

    If your stack already speaks Anthropic, point base_url at https://api.deepseek.com/anthropic and use the /messages shape. The only difference is the image block: instead of image_url, Anthropic uses an image block with a source object whose type is base64, url or file — the three variants mirroring the OpenAI methods above.

    import anthropic
    
    # ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic
    client = anthropic.Anthropic()
    
    message = client.messages.create(
        model="deepseek-v4-flash-vision-exp",
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": "What is in this image?"},
                    {
                        "type": "image",
                        "source": {
                            "type": "base64",
                            "media_type": "image/jpeg",
                            "data": "<BASE64_DATA>",
                        },
                    },
                ],
            }
        ],
    )
    print(message.content)

    A sane default configuration

    • Batch, but stay under 15 images per request unless you are certain every page is within 4,096 px per side.
    • Prefer the Files API for anything reused — the same invoice template re-uploaded 500 times is pure wasted bandwidth.
    • Default to detail: "low" for classification and routing; escalate to original only on the pages that need reading.
    • Budget 384 input tokens per image as a worst case — it is the actual ceiling, so your estimate can never be short.

    Frequently asked questions

    Only deepseek-v4-flash-vision-exp accepts images. Every other DeepSeek model returns a 400 error with the message 'This model does not support image'. The 'exp' suffix means the vision model is still experimental, so pin it in configuration rather than hardcoding it across your codebase.

    There are three ways, all through the OpenAI-compatible Chat Completions endpoint at https://api.deepseek.com: a base64 data: URL inline in an image_url block, a publicly reachable http(s) link in an image_url block, or a file block that references a file_id returned by the Files API. In each case the message content becomes an array of blocks instead of a plain string.

    Images are billed as tokens based on their dimensions after an automatic resize. Anything under roughly 384×384 pixels is scaled up preserving aspect ratio; anything larger is scaled down to roughly the pixel count of an 800×800 image. The result is a hard ceiling of 384 tokens per image, so a 2000×2000 image and a 5000×5000 image cost exactly the same. Each image in a multi-image request is counted independently under the same rule.

    Use the Files API when a single request would exceed the 48 MiB body limit, when one image is larger than 32 MiB (only possible via Files API, which allows up to 64 MiB), or when you reference the same image across multiple requests and want to avoid re-uploading it each time.

    No. Images are supported in user messages only. An image inside a system or assistant message returns a 400 error. User text containing the reserved image placeholder token is also rejected with a 400.

    Yes. Point base_url at https://api.deepseek.com/anthropic and use the Anthropic /messages shape: instead of image_url, send an image block with a source object whose type is base64, url or file. The three source variants mirror the three OpenAI methods.

    Practical, verified use cases from the documentation: describing photographs, reading text out of screenshots, and analyzing charts and diagrams. Because it accepts up to 600 images per request, batch document and screenshot pipelines are the strongest fit — paired with the low detail level when you only need coarse recognition.

    Image tokens are billed together with your text tokens at the model's normal rate, so cost follows the V4-Flash rate card. With the 384-token ceiling per image, a thousand images adds at most ~384K input tokens — cheap compared to most vision APIs. Check our pricing page for the live per-million rate before you budget.

    This is an independent, fan-run guide. It is not affiliated with, endorsed by or operated by DeepSeek. Values above are taken from DeepSeek's official vision documentation on the date shown — verify against the official docs before shipping.