Vision

Send an image alongside your prompt and read documents, forms and handwriting through the same chat endpoint.

Vision is not a separate endpoint. It is POST /v1/chat/completions with an image attached to the message — the same request shape you already use for text, with one more content part.

Sending an image

A message's content becomes an array with two parts: one "type": "text" for your instruction, one "type": "image_url" for the image. It is the same shape OpenAI's vision API uses, so a client library you already have knows how to build it.

Only base64, not a remote URL
image_url.url has to be a data: URI — data:image/png;base64,…. This deployment refuses a remote https:// URL: the request fails with a 502 from the upstream vision server instead of reading the image. Fetch the image yourself and inline it.
POST/v1/chat/completions
Reading a document
IMG=$(base64 -w0 document.png)   # macOS: base64 -i document.png

curl -s https://api.data.larsima.com/v1/chat/completions \
  -H "Authorization: Bearer $DATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"data-auto\",
    \"max_tokens\": 600,
    \"reasoning_effort\": \"none\",
    \"messages\": [{
      \"role\": \"user\",
      \"content\": [
        {\"type\": \"text\", \"text\": \"Read the article number and the amount in this document. Reply as JSON only.\"},
        {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/png;base64,$IMG\"}}
      ]
    }]
  }"

Which model reads the image

data-general carries the vision tower and is what actually reads the pixels. data-auto looks at every message for an image and, when it finds one, sends the whole conversation to data-general — regardless of what the text says. Call data-general directly if you want the vision path without going through the router.

Formats and limits

ConstraintValueNote
FormatsPNG, JPEGEncoded and inlined as a data: URI; other common web formats generally decode the same way.
Request size~32 MBThe whole request body, enforced at the edge — your prompt plus the base64 image, which runs about a third larger than the original file.
Model context262,144 tokensdata-general's context window. A multi-page scan encodes to a lot of tokens, so this is headroom you will rarely touch with one page.

Keep the answer, skip the thinking

The underlying model reasons before it answers, so a plain call spends its first tokens on a reasoning_content preamble you probably don't want. Set "reasoning_effort": "none" for extraction work — read the number, don't think about it — and give the call enough max_tokens to clear a full page.

There is no gateway cap on max_tokens: a request for 30,000 returned 28,893 completion tokens. Set it yourself to a sensible ceiling for a page of text so one runaway generation can't hold the GPU — an internal OCR test once reached 28,382 tokens before it was caught.

OCR accuracy, measured

Printed text is not the hard part. English, Persian and Spanish pages, cleanly rendered, come back at roughly 0–4% word error rate with no special handling.

Persian handwriting is not there yet
Measured against 1,599 words across three real handwritten Persian pages: 63.0% word error rate, ranging from 24.1% on a tidy page to 99.8% on a hard one. That's not a rounding gap — most words come back wrong. Tell a customer who is relying on handwritten intake, and route it to a person or ask them to type it instead.
↑↓ Navigate ↵ Open esc Close