Skip to main content
Photos, screenshots and scanned pages make many apps more useful: a picture of a fridge becomes a recipe, a screenshot of a text message becomes a suggested reply. Every Claude, Gemini and Grok chat model on Gloo AI reads images, as does every OpenAI GPT model except the open-weight GPT OSS models, through the same Responses and Chat Completions requests you already send. This page covers how to do it well in production.
New to image input? Images In and Out explains the concepts, and the Understand Images with Claude tutorial builds two working examples step by step.
This guide covers how to:
  • 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 at GET /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.
Read the catalog once when your app starts, and check the model before each request that carries an image:

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:
  1. 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.
  2. 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.
The second pattern in code. It describes each image once, keeps the description with that conversation, and sends descriptions in place of images only when the next model can’t read them. Descriptions are keyed by a SHA-256 hash of the image’s data: URI, so the same picture is described once per conversation, and a different picture never reuses another’s description:
A description holds only what the describing model wrote down. If later questions may need details it left out, such as small print, keep the conversation on models that read images instead.

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 detail where the model supports it. On the Responses shape, an input_image part takes an optional detail ("low", "high" or "auto"), and on Chat Completions it goes inside image_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.
Gloo AI sets no limit of its own on the number of images or their format; the limits of the model’s maker apply. An image_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_tokens on 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.
See Cost and Speed for how a request is priced. Generated images are billed differently; see How image generation is billed.

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 a 400 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_vision before 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.