Send an image alongside text when you need a model to inspect a screenshot, diagram, or photo. Choose a model whose catalog capability image_input is true; red-cyber-1 is text-only. The model limits table is the current capability reference.
Send a local image
Images must be base64 data URLs containing PNG, JPEG, or WebP bytes. Remote URLs are not fetched. This complete standard-library example sends a local PNG to glm-5.3-flash, an image-capable catalog model. Set REDROUTER_API_KEY, save the code as inspect_image.py, then run python3 inspect_image.py screenshot.png.
import base64
import json
import os
import sys
from pathlib import Path
from urllib.request import Request, urlopen
encoded = base64.b64encode(Path(sys.argv[1]).read_bytes()).decode("ascii")
body = {
"model": "glm-5.3-flash",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe the visible interface and quote any readable error message."},
{"type": "image_url", "image_url": {
"url": "data:image/png;base64," + encoded,
}},
],
}],
}
payload = json.dumps(body).encode()
if len(payload) > 12000000:
raise ValueError("Encoded JSON exceeds the request-body limit")
request = Request("https://redrouter.org/v1/chat/completions", data=payload, headers={
"Authorization": "Bearer " + os.environ["REDROUTER_API_KEY"],
"Content-Type": "application/json",
})
with urlopen(request, timeout=120) as response:
result = json.load(response)
choice = result["choices"][0]
if choice["finish_reason"] != "stop":
raise RuntimeError("Image answer did not finish normally")
print(choice["message"]["content"])
For JPEG or WebP, use the corresponding media type in the data URL. Format recognition uses image bytes and readable dimensions. Sending an unsupported or malformed image causes omission, so check the resulting answer and preserve a text fallback when the task depends on exact content.
Use the right content shape
The following are content-part fragments. Place them inside the endpoint's message or tool-result content array.
| Interface | Image part |
|---|---|
| Chat Completions | {"type":"image_url","image_url":{"url":"data:image/png;base64,…"}} |
| Responses | {"type":"input_image","image_url":"data:image/png;base64,…"} |
| Messages | {"type":"image","source":{"type":"base64","media_type":"image/png","data":"…"}} |
Chat Completions permits images on user and tool messages. Responses permits user images and images inside function_call_output or custom_tool_call_output. Messages permits user images and images in user tool_result content. Images on other roles are replaced by omission notices.
Keep a direct text instruction beside the image: describe what to inspect and the form of the desired answer. Do not assume text embedded in a small screenshot will be read perfectly. For exact extraction, supply machine-readable source text as well when available.
Understand omission behavior
A text-only model receives an explicit notice in place of each image. Remote URLs, unsupported formats, and images that cannot be parsed are also replaced by a notice. They are not silently treated as visual evidence. The notice currently reads:
[Image omitted: this text-only model cannot inspect it. Ask for a text description.]
That wording is also used for invalid or unsupported image inputs on otherwise image-capable models. An omitted image does not, by itself, cause a content rejection. A request can therefore return a normal text response without the model ever seeing the image. Treat an answer asking for a description as a signal to inspect your input and selected capability.
If an image request is refused before output starts, RedRouter may retry once on the same host with images replaced by omission notices. This can happen even with valid images and an image-capable model. A normal text response therefore does not establish that the model received the images; verify important visual claims against the supplied evidence.
All -rr model IDs are text-only. Use the catalog capability rather than inferring image support from a related model's name. Documents and PDFs are not image inputs: extract their text or render selected pages to supported images yourself. Messages replaces document blocks with a notice and rejects requests containing only unsupported documents.
Body limits, estimates, and billing
The JSON request body is limited to 12000000 bytes, including base64 data and all history. Base64 increases binary size by roughly one third, so a file near the body limit will not fit after encoding. Resize or crop large screenshots before sending them, and avoid repeatedly embedding old images when a text summary is sufficient.
Images count as ordinary input tokens at the selected model's input rate; there is no separate RedRouter image surcharge. Reservation and token-counting estimates use a conservative dimension-based image bound. Final usage uses reported model tokens, which can differ from that estimate. See Billing and Data handling before sending sensitive screenshots.