# Vision and files

> Send images and PDFs to vision models by URL or as base64, in OpenAI and Anthropic formats. Which models accept images, how they are billed, and size limits.

Source: https://oneaiapikey.com/docs/vision

Vision models read images (and some read PDFs) as part of the prompt. You send them as content parts next to the text, either as a public URL or inline as base64.

## Models that accept images

| Model id | Input / 1M | Output / 1M |
| --- | --- | --- |
| [claude-opus-5-5](https://oneaiapikey.com/models/claude-opus-5-5) | $4.40 | $22 |
| [claude-sonnet-5](https://oneaiapikey.com/models/claude-sonnet-5) | $2.20 | $11 |
| [claude-haiku-4-5](https://oneaiapikey.com/models/claude-haiku-4-5) | $1.10 | $5.50 |
| [gpt-6.1-sol](https://oneaiapikey.com/models/gpt-6-1-sol) | $2.20 | $11 |
| [gpt-5.6-sol](https://oneaiapikey.com/models/gpt-5-6-sol) | $5.50 | $33 |
| [gpt-5.6-terra](https://oneaiapikey.com/models/gpt-5-6-terra) | $2.20 | $13.20 |
| [grok-4.6](https://oneaiapikey.com/models/grok-4-6) | $2.20 | $6.60 |
| [claude-sonnet-5-5](https://oneaiapikey.com/models/claude-sonnet-5-5) | $2.20 | $11 |
| [grok-4.7](https://oneaiapikey.com/models/grok-4-7) | $2.20 | $6.60 |

Models not in this list are text only: an image part sent to them fails or is ignored, depending on the provider.

## Send an image

In the OpenAI format, `content` becomes a list of parts. An image is an `image_url` part whose `url` is either an `https://` link or a `data:` URL with base64 data.

curl:

```bash
curl https://api.oneaiapikey.com/v1/chat/completions \
  -H "Authorization: Bearer $RELAYKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 500,
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "What is in this picture? One sentence."},
        {"type": "image_url", "image_url": {"url": "https://upload.wikimedia.org/wikipedia/commons/3/3f/Fronalpstock_big.jpg"}}
      ]
    }]
  }'
```

Python:

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

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

with open("receipt.png", "rb") as f:
    data_url = "data:image/png;base64," + base64.b64encode(f.read()).decode()

reply = client.chat.completions.create(
    model="claude-opus-5-5",
    max_tokens=500,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "List the items and the total on this receipt."},
            {"type": "image_url", "image_url": {"url": data_url}},
        ],
    }],
)
print(reply.choices[0].message.content)
```

Node:

```js
import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.oneaiapikey.com/v1", apiKey: process.env.RELAYKIT_API_KEY });
const dataUrl = "data:image/png;base64," + (await readFile("receipt.png")).toString("base64");

const reply = await client.chat.completions.create({
  model: "claude-opus-5-5",
  max_tokens: 500,
  messages: [{
    role: "user",
    content: [
      { type: "text", text: "List the items and the total on this receipt." },
      { type: "image_url", image_url: { url: dataUrl } },
    ],
  }],
});
console.log(reply.choices[0].message.content);
```

- **By URL**: the image must be publicly reachable without cookies or a login. For Claude models the gateway downloads it and sends it inline; for other models the provider fetches it.
- **As base64**: works for private files and is the more reliable choice. Use the right MIME type (`image/png`, `image/jpeg`, `image/webp`, `image/gif`).
- `detail` (`low`, `high`, `auto`) is passed to models that support it.
- Several images can go in one message. Put the question after the images for best results.

## PDFs

Claude models read PDFs, page text and images together. In the OpenAI format, send a `file` part with a base64 `data:application/pdf` URL; the gateway passes it to Claude as a document block.

PDF in the OpenAI format:

```python
with open("contract.pdf", "rb") as f:
    pdf_data = "data:application/pdf;base64," + base64.b64encode(f.read()).decode()

reply = client.chat.completions.create(
    model="claude-sonnet-5-5",
    max_tokens=1000,
    messages=[{
        "role": "user",
        "content": [
            {"type": "file", "file": {"filename": "contract.pdf", "file_data": pdf_data}},
            {"type": "text", "text": "Summarise the termination clauses."},
        ],
    }],
)
```

`file_id` references do not work: the gateway does not offer a Files API. Always send the file data. Other providers’ PDF support varies; for them, extract the text yourself and send it as text.

## Anthropic format

On [`/v1/messages`](https://oneaiapikey.com/docs/anthropic-messages), use Anthropic’s `image` and `document` blocks with a `base64` or `url` source.

Anthropic image and document blocks:

```python
message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=500,
    messages=[{
        "role": "user",
        "content": [
            {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": png_base64}},
            {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": pdf_base64}},
            {"type": "text", "text": "Does the chart in the image match the numbers in the PDF?"},
        ],
    }],
)
```

## Cost and limits

- Images and PDF pages are billed as **input tokens** at the model’s normal input rate. How many tokens an image uses depends on its size and on the model; the provider counts them and the count is in `usage.prompt_tokens`.
- Shrink large images before sending. A phone photo at full resolution costs more and rarely reads better than one scaled to about 1,500 px on the long side.
- A request body can be up to 128 MB at the gateway. Providers apply their own, smaller limits on image size, image count and PDF pages, and reject requests that go over them.
- Images sent again in later turns are billed again. Drop them from the history once the model has answered about them.

> **Personal data in images:** Screenshots and scans often contain names, addresses or card numbers. Crop or redact them before sending, as you would for text.

## Related

- [Models](https://oneaiapikey.com/docs/models#current-models): context windows and prices.
- [Cost control](https://oneaiapikey.com/docs/cost-control): keeping input tokens down.
