A picture reaches the model almost the way text does: you put an image block into the message, then ask about what is in it. Whether the result is good or bad comes down to details.
How to send an image
There are two ways: base64-encode the file and put it into the request body, or give a link to a public URL. Base64 is the safer choice, because it does not depend on whether someone else's server answers at the moment the request is processed.
A Python example with the Anthropic SDK:
import base64
import anthropic
client = anthropic.Anthropic(
api_key="your-codexkey-key",
base_url="https://api.codexkey.online/v1",
)
with open("receipt.jpg", "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
message = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": image_data}},
{"type": "text", "text": "Pull the total, date, and line items from this receipt"},
],
}],
)
JPEG, PNG, GIF and WebP are accepted. The model takes PDF as its own block type, not as an image. That comes in handy when you need to parse a whole document and not the screenshot of a single page.
Resolution and cost
An image is counted in tokens, like text, but by a different rule: the price grows with the area of the picture, and visual complexity does not affect it. A phone shot at maximum resolution and the same shot shrunk to a size where the text is still readable cost different amounts, yet they are often recognized identically.
The takeaway is practical: before sending, reduce the picture to the size the task needs. A side of a bit over a thousand pixels is enough to read the text off a receipt or a screenshot. For fine print, raise the resolution selectively, not for the whole series of requests at once.
Several images in one request are each counted separately, and the total grows linearly. On batches of dozens of pictures that quickly becomes a visible line in the budget, so estimate the cost ahead of time with the calculator on the site.
Where vision does well at OCR
Structured data from receipts, invoices and forms. The model finds the total, the date and the document number even when the layout differs from one receipt to the next: it reads context, and it does not look for a pattern at fixed coordinates.
Tables from screenshots. If the table is readable by eye, the model will usually match rows to columns correctly and return the result as JSON with no extra markup.
Handwriting comes out worse than print. Still, the model recognizes legible handwriting noticeably better than classic OCR built on fixed character templates.
What works poorly
Exact object coordinates. The model will tell you there is a "Submit" button in the photo, but it often names the pixel coordinates of that button inaccurately. For interface automation that needs a precise click, relying on coordinates from the model is risky.
Counting objects in a crowded frame. On a photo with a dozen similar items the model regularly misses the count by one or two, especially when the items partly overlap.
Small text in a low-resolution image or in bad light. A stronger model does not help here. A better scan or photo does.
Comparing two similar images for small differences. The model tends to invent differences that are not there, until you explicitly ask it to be conservative and to admit uncertainty.
How to prepare images before sending
Crop the excess margin around the part you need: the price drops, and the noise that could throw the model off goes away. On scans of text with a light background, raising the contrast often improves accuracy more than raising the resolution.
If the document has several pages, send them one at a time and state the page number in the prompt text. Do not stitch them into one long picture: the model copes worse with very elongated images than with a set of frames of a reasonable size.
How the Anthropic and OpenAI formats differ
At Anthropic an image takes its own block, {"type": "image", "source": {...}}, inside the content array. OpenAI has a different shape: {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}. Both work through codexkey, each on its own set of endpoints. You change the structure of the block, and the logic of the request itself stays the same.
In short
Base64 is safer than links, and it is better to compress a picture to fit the task than to send the original from a phone. With structured OCR (receipts, forms, tables) vision does well, and with exact coordinates and counting objects in a crowded frame it does badly. For small text you need a better shot, not a stronger model.