Claude API — Base64 Image Input
Claude's Messages API takes images as raw Base64 (no data: prefix) inside an image content block: source.type: "base64", a media_type, and the encoded data. Drop an image below to get the exact block, plus copy-paste Python and TypeScript. Encoded locally — your image is never uploaded.
How to send a Base64 image to Claude
Drop an image above (or click to browse). The tool reads it locally, Base64-encodes the bytes, and fills in two things: the raw Base64 payload, and a ready-to-paste image content block with the correct media_type already set from the file. Copy the block into a user message's content array — alongside a text block with your question — and call the Messages API. In code, you encode the file yourself and drop the string into source.data, exactly as the Python and TypeScript examples below show.
The image content block
Claude images live inside a content block of type: "image". The source uses type: "base64", a media_type, and the encoded data:
{
"type": "image",
"source": { "type": "base64", "media_type": "image/jpeg", "data": "<BASE64>" }
}
Two details trip people up. First, the data is raw Base64 — not a data:image/jpeg;base64,… URL. This is a very common mistake, especially coming from OpenAI, which uses the data: URL form. Second, the media_type must match the actual bytes: declare image/png only if the file really is a PNG. The tool above fills both correctly for you.
Python and TypeScript
With the official anthropic Python SDK, encode the file with base64.standard_b64encode and drop the string into the image block:
import anthropic, base64
data = base64.standard_b64encode(open("image.jpg", "rb").read()).decode("utf-8")
client = anthropic.Anthropic()
msg = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=[{"role": "user", "content": [
{"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": data}},
{"type": "text", "text": "What's in this image?"},
]}],
)
print(msg.content[0].text)
With the @anthropic-ai/sdk TypeScript SDK, read the file and call .toString("base64"):
import Anthropic from "@anthropic-ai/sdk";
import { readFileSync } from "fs";
const data = readFileSync("image.jpg").toString("base64");
const client = new Anthropic();
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
messages: [{ role: "user", content: [
{ type: "image", source: { type: "base64", media_type: "image/jpeg", data } },
{ type: "text", text: "What's in this image?" },
]}],
});
Tip: claude-opus-4-8 is used here as the current model id — swap it for whichever Claude model you're targeting. Match media_type to your real file type, and paste the encoded string from the box above into data when it's long.
Supported formats and size
Claude accepts four image formats: image/jpeg, image/png, image/gif, and image/webp. Each image is capped at roughly 5 MB per image through the API. Claude also resizes large images internally, so sending a huge original wastes tokens without adding detail — downscale first to save tokens and latency. Whatever format you send, the media_type in the block must name that exact format.
Common errors
- media_type mismatch — the declared
media_typedoesn't match the actual bytes (e.g. you wroteimage/pngbut the file is really a JPEG). Setmedia_typefrom the true file type; the tool above does this automatically. - could not process image — usually you included a
data:prefix (Claude wants raw Base64 only) or the Base64 itself is wrong or truncated. Copy the raw Base64 box above, not a data URI.
Is this private?
Yes. Encoding happens entirely client-side in JavaScript — your image is read into memory in the browser and Base64-encoded locally. It is never sent to a server (not even to Anthropic — that only happens when you run your own code). You can confirm in DevTools → Network: adding an image fires no upload request.
Frequently asked questions
How do I send a Base64 image to Claude?
Base64-encode the image bytes, then put them in a user message's content array as an image block: { "type": "image", "source": { "type": "base64", "media_type": "image/jpeg", "data": "<BASE64>" } }. Add a text block with your question in the same array and call the Messages API. Use raw Base64 with no data: prefix.
Do I include the data: prefix for Claude?
No. Unlike OpenAI's data-URL format, Claude's Messages API expects raw Base64 in source.data — just the encoded payload, with no data:image/jpeg;base64, prefix. Including the prefix causes a "could not process image" error.
What image formats does Claude support?
Claude accepts image/jpeg, image/png, image/gif, and image/webp. The media_type you declare in the image block must match the actual bytes you send.
Why do I get a media_type mismatch error?
A media_type mismatch means the media_type you declared (e.g. image/png) doesn't match the real format of the bytes (e.g. an actual JPEG). Set media_type from the true file type — this tool reads it from the file automatically.
What's the max image size for the Claude API?
Each image is capped at roughly 5 MB per image via the API. Claude also resizes very large images, so downscaling before you send saves tokens and latency without losing detail Claude can use.
Need text, files, or URL-safe Base64?
The main base64.dev tool handles text, files, and URL-safe mode with auto-detect.
Open base64.dev →