Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Vision (image input)

POST /v1/chat/completions accepts OpenAI’s content-parts message shape, so a user message can carry text and image parts in one array. It is opt-in per model: a model only accepts image parts once its config declares the image modality (modalities = ["text", "image"]; the default is ["text"]). GET /v1/models reflects the opt-in back as "modalities": ["text","image"] per model.

{
  "model": "gpt-4o",
  "messages": [{
    "role": "user",
    "content": [
      { "type": "text", "text": "What is this?" },
      { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KG..." } },
      { "type": "image_url", "image_url": { "url": "https://example.com/cat.png" } }
    ]
  }]
}

image_url.url is either a data:<media-type>;base64,<payload> inline URI or a remote http(s) URL.

Pre-flight

Sending an image part to a model whose modalities lack "image" is rejected with LM-2003 (400) before any upstream call. The check inspects the whole fallback chain, not just the primary, so a fallback missing the image modality is caught up front too.

Per-provider handling

OpenAI-family kinds, vllm and azure forward image parts verbatim - both data: URIs and remote URLs. anthropic and cohere translate both forms into their own schema (both upstreams fetch a remote URL themselves). google, vertex_ai and bedrock translate only inline data: URIs into their own schema; a remote http(s) URL routed to any of the three is rejected pre-flight with LM-2004 (400), since none of them fetches a URL itself and the gateway never fetches a chat image URL on the caller’s behalf (an SSRF vector it deliberately avoids). Full per-kind table in Providers - Vision.

Provider-native sources

Two provider-native reference forms are recognised in image_url.url, for callers whose images are already uploaded to the provider: an Anthropic Files API reference (anthropic-file:<file_id>) and a Gemini-native reference (gs://bucket/object, or a Gemini Files API URI under https://generativelanguage.googleapis.com/). A reference routed to a model whose primary provider does not match the reference’s own provider is rejected pre-flight with LM-2008 (400) instead of surfacing as a confusing upstream failure. Details, including the gs:// / Developer API caveat, are in Providers - Vision.

Token accounting

Upstream-reported usage is authoritative and already folds in image tokens. When an upstream reports no usage at all, the local estimation fallback counts each image content part with a flat per-image heuristic (85 tokens at "detail": "low", 765 tokens otherwise) rather than counting it as zero, and the response is still flagged "estimated": true. See Token accounting.