Skip to main content
Most mainstream chat models on APIYI can “see” images: extract text (OCR), count objects, describe scenes and compare several images. This page gives the support list from our tests on 2026-10-11 (UTC+8), how many tokens one image costs, which models each of the four request formats can reach, and the most common errors.
Read these three first:
  1. The universal format is the OpenAI-compatible image_url: {"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}} worked on all 22 vision models we tested. The Responses and Anthropic formats only reach some models — see “Which models each format supports”.
  2. Text-only models such as deepseek-v4-pro and glm-5.3 do not accept images: the request still returns 200, but the image is dropped and the model just says it cannot see one. To check whether the image reached the model, look at usage.prompt_tokens in the response.
  3. Prefer Base64: with a public URL the provider has to download the image, which fails if the host is slow, uses hotlink protection, or omits the Content-Length header (Qwen returns 400 in that case).

Image Recognition · APIYI Online Tool

Don’t want to write code? Upload images in the browser (multi-image analysis supported), use built-in templates for general recognition, product titles, five-point descriptions, attribute analysis and OCR, and switch models to compare results — just paste your APIYI key.

Video Understanding API

Need to analyze video? See the video support list and formats.

Let an AI Agent Do the Integration

Copy this prompt and paste it into Codex / Claude Code / Cursor

It first fetches the plain-text version of this page (append .md to any docs URL), then writes code in your project's own stack — the universal image_url format, downscaling large images first, and checking prompt_tokens to confirm the image actually reached the model are already baked into the requirements.

Integrate / troubleshoot vision understanding in this project: send images to a multimodal model for OCR, counting, scene description or multi-image comparison.

Read the docs before you touch code: fetch https://docs.apiyi.com/en/api-capabilities/vision-understanding.md for the plain-text version of this page.

  1. Endpoint and format: by default use the OpenAI-compatible POST https://api.apiyi.com/v1/chat/completions and pass each image as …

9 requirements in total. Use the button below to copy the full prompt.

Supported models

These results come from tests run on 2026-10-11 (UTC+8): every model had to transcribe the same 1200×760 mixed Chinese/English order image (including a table) word for word, count shapes, spot the difference between two images and read public image URLs. A blank image was used as a control to rule out answers produced without looking. gemini-3.1-flash-lite and gpt-5.4-mini can also read images and got the OCR fully right, but they miscount objects (correct in 0 of 3 and 1 of 3 runs respectively), so avoid them for counting tasks. qwen-vl-ocr is a dedicated OCR model that outputs only tables and skips all text outside them, and in multi-image requests it only reads the first image — use it only for pure table / ID-document scenarios.
Model prices are aligned with the official sites and may change with them; the table above is for reference only — the Model Pricing tab in the top navigation is authoritative: Model Pricing.

Models that do not accept images

For other models, check the “Input modalities” row on the model detail page; see Text + image in one API.

Which models each format supports

Use the OpenAI-compatible chat format for new projects — switching models is just a model-name change. Responses suits projects already on the OpenAI Responses SDK; the Anthropic format suits the Claude ecosystem (Claude Code, the Anthropic SDK); Gemini native suits projects already on the google-genai SDK.

Quick start: the universal format (image_url)

Public image URL

Comparing several images

Add one image_url block per image, in order, and refer to them as “image 1” and “image 2” in the prompt:

curl

Why Base64 is recommended: with an image URL the provider downloads the image in real time, which fails if the host is slow, uses hotlink protection or restricts access; Qwen models also require the host to send a Content-Length header (some CDNs use chunked transfer without it, which in our tests returned Missing Content-Length of multimodal url). Base64 puts the image straight into the request body with no external download. Base64 is about 1.33× the original size, so downscale large images before encoding — see “Downscale large images first”.

Other formats

OpenAI Responses (input_image)

For projects already on the OpenAI Responses SDK. It only reaches GPT, Grok, Qwen3.8, Kimi, MiniMax and DeepSeek Vision — Gemini / Claude / Seed return 400.

Anthropic Messages (image)

For the Claude ecosystem (the Anthropic SDK, Claude Code and so on), endpoint https://api.apiyi.com. The base64 source reaches Claude, Gemini, GPT, Qwen, Kimi and MiniMax; the url source only works on Claude (Gemini silently drops the image).

Gemini native format (inline_data)

If your project already uses Google’s official google-genai SDK, just point base_url at https://api.apiyi.com:
REST form: POST https://api.apiyi.com/v1beta/models/gemini-3.8-flash:generateContent with the header x-goog-api-key: YOUR_API_KEY, and the image inside contents[].parts[] as {"inline_data": {"mime_type": "image/png", "data": "<BASE64>"}}. For more native usage see Gemini native format.

Downscale large images first

Providers handle large images very differently. Results for one 9000×6000 JPEG of about 10 MB:
Resize the long side to about 2048 px before uploading: after downscaling the same image to 2048×1365, all 8 models in the table passed with fully correct OCR at roughly 700–3,700 tokens per image, and gpt-6-sol dropped from 63,658 to 3,320. If Claude returns 429, read the error body first — image exceeds means the image is too large, and retrying will not help.

Common errors

Image URL download timeout

If you get this error when passing an image URL:
it means the provider timed out while downloading that image URL — it has nothing to do with the model, key or balance. Typical causes: a slow host or one that is unfriendly to some regions, an oversized image, or a URL behind hotlink protection or a login. Fix: switch to Base64 (recommended — it removes the download step entirely); or use a faster, publicly reachable URL; or compress the image and retry.

Missing Content-Length of multimodal url (Qwen)

Qwen models require the image host to send a Content-Length response header. Some CDNs (Cloudflare, for example) serve images with chunked transfer and no such header, which triggers this error; serve the same image from object storage or send it as Base64 instead.

invalid base64 data (a URL placed in the Base64 field)

If you get a 400 error like this (the key phrase is invalid base64 data; wording varies slightly by model):
it usually means an image URL was pasted into the Base64 data part of a data URI:
Whatever follows the data:image/...;base64, prefix must be the Base64 encoding of the image file itself. The URL form and the Base64 form are mutually exclusive and cannot be mixed:
Self-check: before sending, look at the image source — if the string starts with http, use the URL form; otherwise Base64-encode it and build a data URI. Valid Base64 never contains characters such as :// or ?, so seeing them after base64, almost certainly means a link was pasted in.

Declared image type does not match the actual format (media type mismatch)

If you get a 400 error like this (the key phrase is The image was specified using the image/png media type, but the image appears to be a image/jpeg image):
it means the data URI declares the image as PNG (data:image/png;base64,...), but the provider decoded it, checked the file header and found the actual content is JPEG, so it rejected the request. Common causes: inferring the format from a file extension that was changed, or hard-coding image/png in code.
Whether this is checked depends on the upstream channel the model uses: in our 2026-10-11 (UTC+8) tests, sending a JPEG declared as PNG worked on all 22 vision models, but Claude models served through the Bedrock channel return the error above. Write code on the rule “the declared type must match the content” and you are safe on every channel.
Fix: detect the real format from the file header before building the data URI, or convert everything to JPEG with PIL as in the function under “Downscale large images first”:
file xxx.png (macOS / Linux command line) shows a file’s real format in a second; in Python, Image.open(path).format gives you the same.

Advanced tips

Confirm the image actually reached the model

Check usage.prompt_tokens in the response: a 1200×760 image costs roughly 900–1,300 tokens on most providers (about 570 on DeepSeek Vision); if the count barely grows over a text-only request, or does not grow at all, the image was dropped. This happens on text-only models (deepseek-v4-pro, glm-5.3), on Grok via the Anthropic endpoint, and on Gemini via the Anthropic url source.
A model that received no image may invent an answer. In our tests we asked for “transcribe all text in the image” without attaching any image: gemini-3.8-flash invented an entire table that did not exist in 1 of 6 runs, while every other model said it could not see an image. So in batch pipelines, do not rely on the answer alone — confirm delivery with prompt_tokens first.

The detail parameter

detail: "low" inside image_url is honored only by some models: gpt-5.4-mini (1,147 → 233 tokens, but small text starts being misread) and Seed (1,340 → 602 tokens, OCR still fully correct); GPT-6 / 5.6, Gemini, Claude and Qwen ignore it. A more portable way to save tokens is to downscale the image yourself.

Parameters

On the chat endpoint, max_tokens and temperature work normally on GPT (including GPT-6), Claude and Gemini (temperature=0.3 passed on all of them in our tests). MiniMax-M3 puts its <think>...</think> reasoning in the content, so strip it yourself.

Prompt ideas for common tasks

The same image can drive very different tasks just by changing the prompt — no code changes required:
  • OCR: “Transcribe all text in the image word for word, and output tables as Markdown tables”
  • Counting / structured output: “Count how many of each object there are and output only JSON: {"object": count}”
  • Product analysis: “Identify the product type and brand, and list its main selling points and target audience”
  • Multi-image comparison: “Below are image 1 and image 2 — list every difference”
  • Chart reading: “Read the axes, the data trend and the maximum and minimum values”
Results on medical images, ID documents or anything safety-related are for reference only — have important decisions reviewed by a person, and do not upload images containing sensitive personal information.

FAQ

All 22 vision models tested on this page: Gemini, GPT, Claude, Grok, Seed, Qwen, Kimi, MiniMax and DeepSeek Vision. Text-only models such as deepseek-v4-pro and glm-5.3 cannot. For other models, check the “Input modalities” row on the model detail page.
Check usage.prompt_tokens in the response first: a few dozen tokens means the image never reached the model. Common causes: ① you picked a text-only model; ② you called Grok through the Anthropic endpoint, or Gemini through the Anthropic url source (both silently drop the image); ③ the provider could not download the public URL. Switching to chat image_url with Base64 solves almost all of these.
Most likely you are using the Responses or Anthropic format, which only support some models (see “Which models each format supports”). Switch to the OpenAI-compatible chat image_url format and it works across providers.
Read the error body first. If it says image exceeds 10 MB maximum, the image is too large (measured after Base64 encoding); retrying will not help — resize the long side to about 2048 px and send it again.
The image almost certainly has too many pixels (an original of tens of megapixels). During peak hours the provider queues it for several minutes before rejecting it, or returns patches ... exceeding the limit right away. Retrying will not help; downscale the long side to 2048 px and resend. Test results and how to diagnose: Image Understanding Requests Keep Timing Out — Is the Image Too Large?.
GPT models bill by image tiles, so larger originals cost more tokens: one 9000×6000 image was billed 63,658 input tokens on gpt-6-sol in our tests. After resizing the long side to about 2048 px, the same image dropped to 3,320 tokens on gpt-6-sol and roughly 700–3,700 tokens across providers.
Mainstream formats such as JPEG, PNG, GIF and WebP all work; MPO files from phone cameras (still named .jpg) were also recognized in our tests. The safest approach is to convert everything to JPEG with PIL before sending.

Model Pricing

All models and the latest pricing

Video Understanding API

Video content recognition, scene description and timestamps

Gemini Native Format

Streaming, reasoning budgets and more in the native format

Text + Image in One API

How to tell which input modalities a model supports