How to send image to Claude API in python
messages.create method with the appropriate model.Setup
pip install anthropic ANTHROPIC_API_KEY import os
import base64
import anthropic Examples
Integration steps
- Import the Anthropic SDK and standard libraries for base64 encoding.
- Read the image file in binary mode and encode it as a base64 string.
- Initialize the Anthropic client with the API key from environment variables.
- Create a message including the base64-encoded image string in the content.
- Call the
client.messages.createmethod with the appropriate Claude model. - Extract and handle the response text from Claude.
Full code
import os
import base64
import anthropic
# Read image file and encode to base64
image_path = "./example_image.png"
with open(image_path, "rb") as img_file:
encoded_image = base64.b64encode(img_file.read()).decode("utf-8")
# Initialize Anthropic client
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# Prepare the message content with base64 image
message_content = f"Here is an image encoded in base64:\ndata:image/png;base64,{encoded_image}\nPlease describe the image."
# Call Claude model
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system="You are a helpful assistant that can interpret base64-encoded images.",
messages=[{"role": "user", "content": message_content}]
)
# Print Claude's response
print("Claude's response:")
print(response.content[0].text) Claude's response: This image appears to be a photo of a serene mountain landscape with a clear blue sky and a lake reflecting the mountains.
API trace
{"model": "claude-3-5-sonnet-20241022", "max_tokens": 1024, "system": "You are a helpful assistant that can interpret base64-encoded images.", "messages": [{"role": "user", "content": "Here is an image encoded in base64:\ndata:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."}]} {"id": "chatcmpl-xxx", "object": "chat.completion", "created": 1234567890, "model": "claude-3-5-sonnet-20241022", "choices": [{"index": 0, "message": {"role": "assistant", "content": ["This image appears to be a photo of a serene mountain landscape..."]}}], "usage": {"prompt_tokens": 1500, "completion_tokens": 200, "total_tokens": 1700}} response.content[0].textVariants
Streaming response for image description ›
Use streaming when you want to display Claude's response incrementally for better user experience.
import os
import base64
import anthropic
image_path = "./example_image.png"
with open(image_path, "rb") as img_file:
encoded_image = base64.b64encode(img_file.read()).decode("utf-8")
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
message_content = f"Here is an image encoded in base64:\ndata:image/png;base64,{encoded_image}\nPlease describe the image."
# Streaming call
for chunk in client.messages.stream(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system="You are a helpful assistant that can interpret base64-encoded images.",
messages=[{"role": "user", "content": message_content}]
):
print(chunk.text, end="", flush=True) Async call to send image to Claude ›
Use async calls when integrating Claude API in asynchronous Python applications for concurrency.
import os
import base64
import anthropic
import asyncio
async def send_image_async():
image_path = "./example_image.png"
with open(image_path, "rb") as img_file:
encoded_image = base64.b64encode(img_file.read()).decode("utf-8")
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
message_content = f"Here is an image encoded in base64:\ndata:image/png;base64,{encoded_image}\nPlease describe the image."
response = await client.messages.acreate(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system="You are a helpful assistant that can interpret base64-encoded images.",
messages=[{"role": "user", "content": message_content}]
)
print("Claude's async response:")
print(response.content[0].text)
asyncio.run(send_image_async()) Use smaller Claude model for faster image captioning ›
Use a smaller Claude model for faster, cost-effective image captioning with shorter responses.
import os
import base64
import anthropic
image_path = "./example_image.png"
with open(image_path, "rb") as img_file:
encoded_image = base64.b64encode(img_file.read()).decode("utf-8")
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
message_content = f"Here is an image encoded in base64:\ndata:image/png;base64,{encoded_image}\nPlease describe the image concisely."
response = client.messages.create(
model="claude-3-5-haiku-20241022",
max_tokens=512,
system="You are a helpful assistant that can interpret base64-encoded images.",
messages=[{"role": "user", "content": message_content}]
)
print("Claude's concise response:")
print(response.content[0].text) Performance
- Compress images before base64 encoding to reduce token count.
- Request concise responses to limit completion tokens.
- Avoid sending very large images; resize to reasonable dimensions.
| Approach | Latency | Cost/call | Best for |
|---|---|---|---|
| Standard call with claude-3-5-sonnet-20241022 | ~1.5s | ~$0.003 | Detailed image descriptions |
| Streaming response | Starts in ~1s, streams over time | ~$0.003 | Better UX for long responses |
| Async call | ~1.5s | ~$0.003 | Concurrent or async Python apps |
| Smaller model claude-3-5-haiku-20241022 | ~1s | ~$0.0015 | Faster, concise captions |
Quick tip
Always encode images as base64 strings and prefix with the correct MIME type (e.g., data:image/png;base64,) before sending to Claude.
Common mistake
Beginners often forget to decode the image to base64 or omit the MIME type prefix, causing Claude to not recognize the image input.