Skip to main content
Sail accepts image inputs on multimodal base models. Images can be supplied as base64 data URIs or as HTTP(S) URLs.

Supported models

ModelMultimodal
moonshotai/Kimi-K2.5
Requesting a non-multimodal model with image blocks returns 400 with model '<id>' does not support image input. See Supported Models for the full list and capabilities.

Limits

  • Max 20 images per request.
  • Max 20 MB per image. This is the size of the image bytes, not the base64-encoded length.
  • Formats: JPEG, PNG, WebP, GIF.
  • No pixel-dimension limit. The 20 MB byte cap is the effective bound; very large dimensions may be resized or tiled by the model before decoding.
  • URL images must be on http:// or https:// and must be reachable from the public internet. If Sail can’t fetch a URL within 10 s, the request fails with 400.

Responses API

Pass an input_image block inside a message’s content array. The image_url value can be a data URI or a public URL.
from openai import OpenAI

client = OpenAI(base_url="https://api.sailresearch.com/v1", api_key="YOUR_KEY")

response = client.responses.create(
    model="moonshotai/Kimi-K2.5",
    input=[
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": "What's in this image?"},
                {
                    "type": "input_image",
                    "image_url": "https://example.com/cat.jpg",
                },
            ],
        }
    ],
    background=True,
)
Equivalent with a base64 data URI:
import base64, pathlib

b64 = base64.b64encode(pathlib.Path("cat.jpg").read_bytes()).decode()
data_uri = f"data:image/jpeg;base64,{b64}"

response = client.responses.create(
    model="moonshotai/Kimi-K2.5",
    input=[
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": "What's in this image?"},
                {"type": "input_image", "image_url": data_uri},
            ],
        }
    ],
    background=True,
)
detail ("auto", "low", "high") is supported.

Chat Completions API

Use OpenAI’s standard image_url content part.
response = client.chat.completions.create(
    model="moonshotai/Kimi-K2.5",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/cat.jpg",
                        "detail": "auto",
                    },
                },
            ],
        }
    ],
)
Data URIs are accepted in the same url field:
"image_url": {"url": f"data:image/jpeg;base64,{b64}"}

Messages API (Anthropic)

Use the Anthropic image content block. Both base64 and url source types are supported.
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.sailresearch.com",
    api_key="YOUR_KEY",
)

# URL source
response = client.messages.create(
    model="moonshotai/Kimi-K2.5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {"type": "url", "url": "https://example.com/cat.jpg"},
                },
                {"type": "text", "text": "What's in this image?"},
            ],
        }
    ],
)

# Base64 source
response = client.messages.create(
    model="moonshotai/Kimi-K2.5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": b64,  # raw base64 string, no data: prefix
                    },
                },
                {"type": "text", "text": "What's in this image?"},
            ],
        }
    ],
)

Error cases

ConditionStatusMessage
model is not multimodal400model '<id>' does not support image input
More than 20 images in one request400too many images: maximum 20 images per request
Image larger than 20 MB decoded400image too large: exceeds maximum of ... bytes
Unsupported MIME type400unsupported image type ...
URL scheme not http/https400unsupported URL scheme ...
URL not reachable from the public internet400blocked: ...
URL returns non-200 or times out (10 s)400failed to download image: ...
Data URI declared MIME does not match actual bytes400declared type ... does not match detected type ...

Notes

  • If you already have the image bytes, sending them as a base64 data URI is typically faster than a URL.
  • Image bytes are not cached across requests.
  • LoRA adapters and image inputs can be combined on a multimodal base model that also supports LoRA (see LoRA Adapters).