Claude API Image Input: Vision Capabilities Guide
Claude's API supports image input alongside text, letting you send photos, screenshots, charts, diagrams, and scanned documents directly in a message and get back a text response. This is called vision capability, and it works through the same Messages endpoint you already use for text — you just add an image content block to the request instead of (or in addition to) a text block.
If you're trying to figure out whether Claude can "see" images, how to format the request, what file types and sizes are supported, and what it's actually good at, this article covers all of it with working examples.
How image input works in the Messages API
Images are passed as content blocks inside a message, the same way you'd structure a multi-part prompt. Each image block needs a type of image, a source object describing how the image is encoded, and you can mix image blocks with text blocks in any order within a single message.
There are two ways to provide the image data:
- Base64-encoded bytes embedded directly in the request body
- A URL pointing to a publicly accessible image (support for this varies by provider — check your integration's docs before relying on it)
Here's a base64 example using curl:
IMG_B64=$(base64 -i screenshot.png)
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "'"$IMG_B64"'"
}
},
{
"type": "text",
"text": "What error is shown in this screenshot, and how do I fix it?"
}
]
}
]
}'
The model reads the image and the accompanying text instruction together, so you get a response grounded in what's actually in the picture rather than a generic guess.
If you're routing requests through SubToAPI, the request shape is identical — same content array, same image block structure — you just point at https://api.subtoapi.app/v1/messages and authenticate with your sub_live_... key instead of a raw Anthropic key. See the messages docs for the exact payload format.
Supported formats and limits
Claude accepts standard web image formats: JPEG, PNG, GIF, and WebP. A few practical constraints to keep in mind:
- File size: keep individual images well under the per-request payload limit — large base64 strings inflate your request body significantly, so resize or compress large screenshots before sending them.
- Resolution: extremely high-resolution images are downscaled internally before processing, so sending a 20-megapixel photo won't improve accuracy over a reasonably sized version — it just wastes bandwidth and tokens.
- Multiple images per request: you can include several image blocks in one message, which is useful for comparisons ("what changed between these two screenshots?") or multi-page documents.
- Token cost: images consume input tokens based on their dimensions. A rough rule of thumb is that larger, more detailed images cost more tokens — factor this into your usage and billing estimates, especially if you're on a usage-based pricing model.
Sending multiple images in one request
A common pattern is comparing two images or walking through a sequence. You just add more image blocks to the same content array:
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{ type: "image", source: { type: "base64", media_type: "image/png", data: beforeImageB64 } },
{ type: "image", source: { type: "base64", media_type: "image/png", data: afterImageB64 } },
{ type: "text", text: "Compare these two UI screenshots and list every visual difference." }
]
}
]
})
});
const data = await response.json();
console.log(data.content[0].text);
This is the same pattern you'd use for before/after bug reports, design review tools, or diffing rendered PDF pages.
Practical use cases worth building
Vision input is genuinely useful for a specific class of problems rather than a general-purpose replacement for OCR or computer vision models:
- UI and screenshot debugging — paste in a screenshot of a broken layout or stack trace and ask Claude to explain what's wrong.
- Document and form understanding — read scanned invoices, receipts, or ID cards and extract structured fields as JSON.
- Chart and diagram interpretation — summarize what a graph shows, or convert a hand-drawn architecture diagram into a written description.
- Accessibility tooling — generate alt text or detailed descriptions of images for content pipelines.
- Visual QA for content moderation — flag or describe image content as part of a review workflow.
Where it's less suited: pixel-perfect object detection with bounding boxes, real-time video frame analysis, or tasks that require guaranteed exact OCR transcription of dense small text — those are better handled by dedicated OCR or vision models, sometimes used as a pre-processing step before handing a cleaned-up image or extracted text to Claude.
Combining vision with tool use
Image understanding gets more powerful when paired with tool calls. For example, Claude can look at a screenshot of a form, extract the fields, and then call a function to submit that data to your backend — all in one conversation turn. If you're building this kind of pipeline, the tool use docs cover how to define functions the model can invoke based on what it reads from an image.
Getting started
If you want to add image input to an existing integration without managing separate credentials for every environment or teammate, SubToAPI gives you a single sub_live_... key, streaming support, and per-key usage visibility on top of your existing Claude access. Check the quickstart to get a key working in a few minutes, or compare plans on the pricing page — every plan starts with a free trial at signup.
questions
Does the Claude API support PDFs with embedded images, not just standalone image files? Yes, but PDFs are typically handled as a separate document input type rather than a raw image block — if you only need the visual content, converting pages to PNG/JPEG first works reliably with the image API.
Can I send an image URL instead of base64 data? Some integrations support URL-based image sources, but base64 is the most consistently supported method across the Messages API and is the safer default for production code.
How many images can I include in a single request? There's no strict fixed count, but every image adds to your input token usage and request payload size, so in practice you should limit requests to the number of images actually needed for the task — a handful is typical for comparisons or multi-page documents.