Send images to vision-capable models using the messages content array.
Vision models on OpenDunes accept images directly in the messages[].content field. Instead of passing content as a plain string, pass an array of typed parts — text and image mixed in any order.
Any model with the vision capability accepts image inputs. Query the catalog:
GET https://opendunes.com/api/models?capability=visionBrowse vision models at /models. Well-known options include anthropic/claude-opus-4.8, anthropic/claude-sonnet-5, and google/gemini-2.5-pro.
Replace the content string with an array of parts. Each part is an object with a type field:
{ "type": "text", "text": "..." } — a text segment{ "type": "image_url", "image_url": { "url": "..." } } — an imageYou can interleave text and images in the same content array.
Pass an HTTPS URL directly:
{
"model": "anthropic/claude-opus-4.8",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/240px-PNG_transparency_demonstration_1.png"
}
},
{
"type": "text",
"text": "Describe this image in detail."
}
]
}
]
}Encode your image as base64 and embed it as a data URI. The format is data:<mime_type>;base64,<data>. Supported MIME types: image/jpeg, image/png, image/gif, image/webp.
{
"type": "image_url",
"image_url": {
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
}import os
from openai import OpenAI
client = OpenAI(
base_url="https://opendunes.com/v1",
api_key=os.environ["OPENDUNES_API_KEY"],
)
resp = client.chat.completions.create(
model="anthropic/claude-opus-4.8",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"url": "https://example.com/chart.png"},
},
{"type": "text", "text": "What does this chart show?"},
],
}
],
max_tokens=512,
)
print(resp.choices[0].message.content)You can pass multiple image parts in a single message. The model processes them all:
{
"role": "user",
"content": [
{ "type": "image_url", "image_url": { "url": "https://example.com/before.png" } },
{ "type": "image_url", "image_url": { "url": "https://example.com/after.png" } },
{ "type": "text", "text": "What changed between these two screenshots?" }
]
}capability=vision in the catalog before choosing a model. Sending an image to a non-vision model will return an invalid_request error.content as a plain string is still valid.Image tokens are billed in DA at the same per-token rate as text. The number of image tokens depends on the model and the image dimensions. Check the model detail page at /models for the exact image token pricing.