Image input

Send an image to a chat model as a content part. The model answers in text. The part has the shape of the API that you use, so an unchanged client works.

curl https://router.inference.ai.exchange/v1/chat/completions \
  -H "Authorization: Bearer sk-liquid-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-120b",
    "messages": [{
      "role": "user",
      "content": [
        { "type": "text", "text": "what is in this picture?" },
        {
          "type": "image_url",
          "image_url": { "url": "data:image/png;base64,iVBOR…", "detail": "high" }
        }
      ]
    }]
  }'

Put the text part first, then the images.

Examples

Read a chart. Send a screenshot of a chart and ask for its numbers.

{
  "role": "user",
  "content": [
    { "type": "text", "text": "List the value of each bar as a table." },
    {
      "type": "image_url",
      "image_url": { "url": "data:image/png;base64,iVBOR…", "detail": "high" }
    }
  ]
}

Use detail: "high" for small text. It costs more tiles.

Compare two photos. Send more than one image in one message. Each image is a part, and the cap counts all of them.

{
  "role": "user",
  "content": [
    { "type": "text", "text": "What changed between these two photos of the shelf?" },
    { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,/9j/4AAQ…" } },
    { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,/9j/4BBR…" } }
  ]
}

Check max_references in input_modalities. An offer can limit the number of images.

Send an image

API Part Source
Chat Completions image_url with url and detail https:// URL or data: URL
Responses input_image with image_url https:// URL or data: URL
Messages image block with a source base64 or url

Accepted formats are image/png, image/jpeg, image/webp and image/gif. An offer can accept fewer.

detail is auto, low or high. The exchange sends it to the provider without change.

URL or base64

The exchange does not fetch an image that you give as a URL. It prices the image at 1,200 tokens and never sees its media type. So an offer that limited the formats or the sources to base64 cannot serve it.

If you send the bytes inline, the exchange sets the cap from the real image, and more offers can serve the request. Use a URL only when the image is large and the cap is not a concern.

Cost

The exchange reads the width and height from the header. Each offer converts them to input tokens. Without an offer table, the exchange uses 85 tokens plus 170 for each 512-pixel tile.

Tiles follow the published rule of OpenAI. Fit the long side to 2048 pixels, then the short side to 768, then count 512-pixel tiles. detail: "low" is one tile for all sizes.

The charge is the token count that the provider meters. See What an attachment costs.

Limits

An offer can limit the largest image (max_bytes), the formats, the sources and the number of images in one request (max_references). A request that breaks a limit does not reach that offer. The reason is media_unsupported.

Troubleshooting

Error Cause Fix
400 unsupported_parameter No offer for the model reads images. Pick a model with image in input_modalities.
400 unsupported_content The bytes are not base64, or the header is not an image. Check the encoding and the format.
413 request_too_large The body is over 20 MB. Send a smaller image.
503 no_eligible_offer Offers read images, but none takes this image. Read eligibility.excluded.

Next steps