# Images and vision

> Send images alongside text to multimodal models on sference: which models accept images, the request shapes, limits, and how images are billed.

Source: https://sference.com/docs/guides/vision

Several catalog models accept images alongside text. Send a screenshot, a scanned document, a chart, or a product photo and ask about it — the same request shape works on `/v1/chat/completions`, `/v1/responses`, and `/v1/messages`.

## Which models accept images

| Model | Vision |
| --- | --- |
| `moonshotai/Kimi-K3` | ✅ |
| `zai-org/GLM-5.3-Flash` | ✅ |
| `deepseek-ai/DeepSeek-V4.1-Flash` | ✅ |
| `Cloudflare/clef` | ✅ |
| `zai-org/GLM-5.3`, `zai-org/GLM-5.2` | ❌ text only |
| `deepseek-ai/DeepSeek-V4-Flash`, `-0731` | ❌ text only |

> **Capability comes from the catalog, not the model name**
>
> Send an image to a text-only model and the request fails — the platform does not silently drop it. Check `GET /v1/models`: each entry carries a `capabilities.image_input.supported` flag. Route image requests to a model where it is `true`.

## Sending an image

### Base64 data URL

The portable form — works everywhere, no upload step:

```python
import base64, os
from openai import OpenAI

client = OpenAI(base_url="https://api.sference.com/v1", api_key=os.environ["SFERENCE_API_KEY"])

with open("invoice.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="zai-org/GLM-5.3-Flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What is the total on this invoice?"},
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
        ],
    }],
)
```

### Remote URL

If the image is already reachable over HTTPS, pass the URL directly:

```python
{"type": "image_url", "image_url": {"url": "https://example.com/chart.png"}}
```

### Responses API

On `/v1/responses`, images are content parts of an `input` item:

```python
response = client.responses.create(
    model="zai-org/GLM-5.3-Flash",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Summarize this chart."},
            {"type": "input_image", "image_url": f"data:image/png;base64,{b64}"},
        ],
    }],
)
```

### Anthropic Messages API

On `/v1/messages`, images are Anthropic content blocks:

```python
{
    "role": "user",
    "content": [
        {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": b64}},
        {"type": "text", "text": "What does this show?"},
    ],
}
```

## Practical limits

- **Formats:** PNG, JPEG, WebP, GIF. Convert exotic formats (HEIC, TIFF) before sending.
- **Size:** keep images under ~5 MB. Large images are downscaled before tokenization, so sending a 20 MP photo costs bandwidth without improving accuracy.
- **Resolution and tokens:** an image is converted to tokens, and the count scales with resolution. A full-page screenshot can cost more tokens than a page of text. Downscale to the smallest resolution that still answers your question — for a receipt, 1024 px on the long edge is usually plenty.
- **Multiple images:** supported. Put the text instruction after the images it refers to, or the model may describe them without answering.

## Cost

Images bill as **input tokens** at the model's normal input rate — there is no separate image surcharge. Because token count scales with resolution, image-heavy workloads are sensitive to the resolution you send. See [Pricing](https://sference.com/docs/pricing).

## Common patterns

**Document extraction.** Screenshot or scan → vision model → [structured output](https://sference.com/docs/guides/structured-outputs) with a schema for the fields you need. This is the highest-value use of vision in production: invoices, receipts, forms, IDs.

**UI and screenshot understanding.** Feed a screenshot to an agent so it can reason about layout without a browser tool. Note that coding models in the catalog are text-only — see [Claude Code](https://sference.com/docs/sference-code/claude-code) for how that is handled in an agent loop.

**Chart and table reading.** Works well at moderate resolution; ask for the values explicitly rather than "describe this", and request JSON if you intend to compute on them.

**Quality control.** Compare two images, or an image against a spec, with a yes/no or enum answer.

- [Structured outputs](https://sference.com/docs/guides/structured-outputs): Pair vision with a schema for extraction workloads.
- [Models](https://sference.com/docs/models): Check capabilities.image_input before routing image traffic.
- [Pricing](https://sference.com/docs/pricing): Images bill as input tokens; resolution drives the count.
