## Send images to Claude ### Base64-encoded image example ### URL-based image example ### Files API image example ### Multiple images ## Image limits and costs ### Request limits ### Supported formats ### Resolution and token cost ### Image quality guidance ## Coordinates and bounding boxes ## Limitations ## FAQ ## Next steps
The whole hunk
1369 lines, first recordedThe first capture of this source. The page was already there, and this is what it said.
---
title: Vision
url: https://platform.claude.com/docs/en/build-with-claude/vision
description: Claude's vision capabilities allow it to understand and analyze images, opening up exciting possibilities for multimodal interaction.
---
This guide describes how to send images to Claude, the limits and costs that apply, and where to find guidance for [coordinate-based workflows](https://platform.claude.com/docs/en/build-with-claude/vision-coordinates).
***
## Send images to Claude
Use Claude's vision capabilities through:
* [claude.ai](https://claude.ai/). Upload an image like you would a file, or drag and drop an image directly into the chat window.
* The [Workbench](https://platform.claude.com/playground) in the Claude Console. Add images directly to any User message block.
* API request. See the following examples.
On the API, provide images to Claude as `image` content blocks using one of three source types:
1. A base64-encoded image embedded in the request body
2. A URL reference to an image hosted online
3. A `file_id` returned by the [Files API](https://platform.claude.com/docs/en/build-with-claude/files) (upload once, reference many times)
<Note>
On Amazon Bedrock and Google Cloud, only base64-encoded sources are currently available.
</Note>
<Tip>
Just as [placing long documents before your query](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#long-context-prompting) improves results in text prompts, Claude works best when images come before text. Images placed after text or interpolated with text still perform well, but if your use case allows it, prefer an image-then-text structure.
</Tip>
### Base64-encoded image example
<CodeGroup>
```bash cURL
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 @- <<EOF
{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "$BASE64_IMAGE_DATA"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}
EOF
```
```bash CLI
curl -sSo ./vision-example.jpg \
https://platform.claude.com/docs/images/vision-example.jpg
ant messages create <<'YAML'
model: claude-opus-5
max_tokens: 1024
messages:
- role: user
content:
- type: image
source:
type: base64
media_type: image/jpeg
data: "@./vision-example.jpg"
- type: text
text: Describe this image.
YAML
```
```python Python
image1_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
image1_media_type = "image/png"
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": image1_media_type,
"data": image1_data,
},
},
{"type": "text", "text": "Describe this image."},
],
}
],
)
print(message)
```
```typescript TypeScript
const anthropic = new Anthropic();
const message = await anthropic.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "base64",
media_type: "image/jpeg",
data: imageData // Base64-encoded image data as string
}
},
{
type: "text",
text: "Describe this image."
}
]
}
]
});
console.log(message);
```
```csharp C#
using System.Collections.Generic;
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new();
string imageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
var message = await client.Messages.Create(new MessageCreateParams
{
Model = Model.ClaudeOpus5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new Base64ImageSource()
{
Data = imageData,
MediaType = MediaType.ImagePng,
})
)),
new ContentBlockParam(new TextBlockParam("Describe this image.")),
}),
}
]
});
Console.WriteLine(message);
```
```go Go
client := anthropic.NewClient()
imageData := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(
anthropic.NewImageBlockBase64("image/png", imageData),
anthropic.NewTextBlock("Describe this image."),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message)
```
```java Java
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
String imageData =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
List<ContentBlockParam> contentBlockParams = List.of(
ContentBlockParam.ofImage(
ImageBlockParam.builder()
.source(
Base64ImageSource.builder()
.mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
.data(imageData)
.build()
)
.build()
),
ContentBlockParam.ofText(TextBlockParam.builder().text("Describe this image.").build())
);
Message message = client
.messages()
.create(
MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5)
.maxTokens(1024)
.addUserMessageOfBlockParams(contentBlockParams)
.build()
);
IO.println(message);
```
```php PHP
$client = new Client();
$imageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => [
'type' => 'base64',
'media_type' => 'image/png',
'data' => $imageData,
],
],
['type' => 'text', 'text' => 'Describe this image.'],
],
],
],
model: 'claude-opus-5',
);
echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL;
```
```ruby Ruby
client = Anthropic::Client.new
image_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
message = client.messages.create(
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image_data
}
},
{ type: "text", text: "Describe this image." }
]
}
]
)
puts message
```
</CodeGroup>
### URL-based image example
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
Cut at 300 lines. The page has the rest.