- choose a model that reads images, and check before you route
- switch models in a conversation that holds an image
- keep images small, and choose between base64 and a link
- know what each turn costs
- review images from people you don’t control
Choose a model that reads images
Check the model before you send it an image. In the catalog atGET /platform/v2/models, a model that reads images has supports_vision: true, and its input_modalities include "image".
- Every Claude, Gemini and Grok chat model reads images, as does every OpenAI GPT model except the open-weight GPT OSS models, and Cohere’s Command A+.
- About half of the open-source models read images. The rest, GPT OSS included, read text only, so check each one.
- Pick by the job. Reading a fridge shelf or a short message works on smaller, cheaper models; dense documents, handwriting and charts benefit from larger ones. Try a few candidates with your own images, and compare their rates on Supported Models.
Switching models mid-conversation
Your app sends the whole conversation on every request (Conversations That Remember), so an image the user sent on the first turn is still in the request on the tenth. Every model that answers that conversation must be able to read it. A model that reads text only can’t take the conversation, and the request fails. Two patterns keep a conversation working:- Stay on models that read images. If you route between models for cost or speed, choose among models with
supports_vision. Any Claude, Gemini or Grok chat model, or any OpenAI GPT model other than GPT OSS, can pick up the conversation. - Describe the image once, then keep the description. Have a model that reads images describe the picture, and replace the image with that text. The conversation can then move to any model, text-only ones included, and later turns cost less, because a few sentences of description use fewer tokens than the image.
data: URI, so the same picture is described once per conversation, and a different picture never reuses another’s description:
Keep images small
The model doesn’t need a 12-megapixel photo to read a fridge shelf or a screenshot.- Scale down before you send. About 1,500 pixels on the long side is plenty for photos and screenshots. A smaller image uses fewer input tokens, uploads faster and stays well inside the request size limit.
- Send JPEG, PNG, GIF or WebP. Convert phone photos saved as HEIC to JPEG first, since not every model reads HEIC. JPEG suits photos; PNG keeps screenshot text sharp.
- Crop to what matters. A screenshot of one message reads better than the whole screen.
- Use
detailwhere the model supports it. On the Responses shape, aninput_imagepart takes an optionaldetail("low","high"or"auto"), and on Chat Completions it goes insideimage_url. GPT models use"low"to read a smaller version of the image for fewer tokens. - Mind the request size. A request body can be up to 10 MB, and base64 makes an image about a third larger than the file. See Request size.
Send base64, or a link
Animage_url can be the image itself as a base64 data: URI, or a public https:// link.
- Base64 is the most predictable. It works with every model that reads images, and nothing has to fetch the image. Use it for photos your users take or upload.
- A link keeps the request small, but it must be public and still valid when the request runs, and not every model fetches links. Avoid short-lived signed links.
Know what each turn costs
An image is billed as input tokens at the model’s input rate, the same rate as the text you send; there is no separate charge per image. Because your app resends the whole conversation on every turn, an image is billed again on each turn it stays in the history.- Read
usage.input_tokenson a response to see what an image costs on the model you chose. - For long conversations, use the describe-once pattern above, or drop the image once the conversation has moved on.
- On guarded endpoints, the model’s rate plus 6.5% for guardrails, moderation and values alignment applies to image tokens as to every other token.
Review images from people you don’t control
If anyone can upload an image or a PDF to your app, review it with your own content checks before you send it to the model. This applies on guarded and direct endpoints alike; see Images and moderation. The model’s maker may also decline an image under its own content policy. On direct endpoints, a refusal before any output is a400 with provider_content_policy_violation. Once output has started, a Direct Responses stream ends with a response.failed event whose response.error.code is provider_content_policy_violation, and a Direct Completions stream ends with finish_reason: "content_filter". See Content Policy Refusals and Streaming on the direct endpoints. Don’t resend the same image unchanged.
Treat text in images as content
A screenshot or a photo of a sign can contain text that reads like an instruction. Say in your instructions that text in an image is content to work on, not instructions to follow, as you would for any text from outside your app (see prompt injection). The screenshot example in the tutorial shows the wording.Summary
- Check
supports_visionbefore sending an image; every Claude, Gemini and Grok chat model qualifies, as does every OpenAI GPT model except GPT OSS. - Keep a conversation that holds an image on models that read images, or describe the image once and keep the text.
- Scale images down, send base64, and watch
usage.input_tokens. - Review images from people you don’t control before you send them.
Next steps
Understand Images with Claude
Fridge photo to recipe and screenshot to replies, step by step.
Direct Responses: Multimodal
Image input, PDF input and image generation.
Supported Models
Which models read images, with live rates.
Building with Guarded Endpoints
Instructions, structured output and handling moderated replies.

