Tuna.ai

Image Input

Models with image input can read images as well as text. You can send screenshots, photos, charts, scanned documents, and other images in a chat completion, and ask about them in the same message.

Send an Image

Make the message's content a list of parts instead of a string. A text part has type: "text", and an image part has type: "image_url":

Request body
{
  "model": "tuna-us/example-lab/example-model-id",
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "What does this chart show?"},
        {"type": "image_url", "image_url": {"url": "https://example.com/chart.png"}}
      ]
    }
  ]
}

The url can be:

  • A public https URL. Tuna downloads the image while it handles the request, so the URL has to work without signing in.
  • A data URL with the image in base64, like data:image/png;base64,iVBORw0KG.... Use this for private images, or for files on your own machine. Base64 makes the image about a third larger, so large images can be worth compressing with gzip.
import { readFileSync } from "node:fs";

const image = readFileSync("chart.png").toString("base64");

const response = await client.chat.completions.create({
  model: "tuna-us/example-lab/example-model-id",
  messages: [{
    role: "user",
    content: [
      { type: "text", text: "What does this chart show?" },
      { type: "image_url", image_url: { url: `data:image/png;base64,${image}` } },
    ],
  }],
});
console.log(response.choices[0].message.content);
import base64

with open("chart.png", "rb") as chart:
    image = base64.b64encode(chart.read()).decode()

response = client.chat.completions.create(
    model="tuna-us/example-lab/example-model-id",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What does this chart show?"},
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image}"}},
        ],
    }],
)
print(response.choices[0].message.content)

Use common image formats, such as PNG, JPEG, and WebP.

Limits

A request can have up to 30 images, counting every message in the conversation. A request with more fails with status 400. See Errors.

In a long conversation, earlier images count too. Drop images from old messages when the model no longer needs them.

Check that the model you pick supports image input before you send an image. Sending an image to a text-only model fails.

Billing

The model turns each image into tokens, and those are billed as input tokens at the model's input price. A larger image uses more tokens, and the exact number depends on the model. To pay less, resize images to the smallest size that still shows what the model needs to see.

The usage field of the response includes the image tokens in prompt_tokens. See Billing.

Privacy

Images are part of your prompt, so they get the same Zero Data Retention (ZDR) as text. See Privacy and ZDR.