DeepSeek Vision API Caps Every Image at 384 Tokens
My notes
Summary
DeepSeek’s deepseek-v4-flash-vision-exp model accepts images via three methods, inline base64, external URL, or a pre-uploaded Files API reference, across OpenAI-compatible, Anthropic-compatible, and Responses API endpoints. Image cost is capped regardless of resolution: every image is resized toward roughly 800x800 pixels before inference, so a 2000x2000 and a 5000x5000 image consume the same fixed 384 tokens.
Key Insight
-
Flat token cost per image is the standout detail. Because resizing targets roughly 800x800 px pre-inference, image cost is capped at 384 tokens no matter the original resolution. Multi-image requests don’t get a discount or penalty; each image is counted independently under the same rule. This makes cost prediction trivial versus providers that scale tokens with resolution or tiling.
-
Three ingestion paths, each with different limits, not just convenience variants:
- Inline base64: simplest, but counts toward the 48 MiB total request body limit; capped at 32 MiB per image.
- External URL: the model fetches it; URL max 8192 chars, file max 32 MiB, download must finish in 60 seconds.
- Files API
file_id: the only path that supports images up to 64 MiB and isn’t checked against the 32 MiB per-image cap; best when reusing the same image across many requests (avoids re-upload).
-
Hard ceilings worth knowing before hitting them in production: max 600 images per request; max total image payload 64 MiB without
file_id(up to 200 MiB if usingfile_idreferences); max image dimension 8192 px per side, but that drops to 4096 px per side once a request contains 15+ images. -
Format detection is content-based, not filename or MIME-based. A mislabeled file still gets parsed correctly (or rejected) based on actual bytes.
-
Images are restricted to
usermessages only. Putting an image in asystemorassistantmessage returns a400error, and only the vision-tagged model accepts images at all (other models 400 with “This model does not support image”). -
The
detailfield (low/high/original/auto) only matters forimage_urlinputs.lowdownsamples to 512x512 before inference (cheaper and faster when detail doesn’t matter); it’s silently ignored when the image comes viafile_id. -
The Anthropic-compatible endpoint (
/anthropicbase path) mirrors the same three methods but reshapes them asimageblocks with asource.typeofbase64,url, orfile. Thefilevariant requires theanthropic-beta: files-api-2025-04-14header.