Vision
Vision lets a user message include pictures. The model can describe them, read text in them, compare them, or answer questions about charts, screenshots, receipts and photos. Images sit next to text in the same message, as content parts.
When to use it
- Reading receipts, forms and labels.
- Answering questions about charts, diagrams and UI screenshots.
- Checking product photos against a description.
- As the base for computer use, where the model reads screenshots.
Vision is not suited to precise measurement, counting many small objects, or identifying real people from their faces (the model will not do the last).
Endpoint and auth
POST https://app.syntic.ai/v1/chat/completions (and Messages as image blocks), Authorization: Bearer sk_live_.... The model must have capabilities.vision: true in /v1/models.
Request fields
content on a user message becomes an array of parts:
| Part | Fields | Details |
|---|---|---|
{"type":"text"} | text | Ordinary text. |
{"type":"image_url"} | image_url.url | An https:// URL or a data: URL (data:image/png;base64,...). |
image_url.detail | auto (default), low or high. See cost. | |
{"type":"image_file"} | image_file.file_id | An image uploaded with the Files API (purpose: "vision"). |
A plain string content still works and means one text part.
Accepted images
| Rule | Value |
|---|---|
| Formats | PNG, JPEG, WebP, GIF (first frame only) |
| Size per image | 20 MB via URL or file, 5 MB as a data: URL |
| Images per request | 100 |
| Largest side | Images over 2,048 px on the long side are scaled down before the model sees them |
| Remote URLs | Public https only. Fetched once, with a 10-second timeout, through Syntic’s address checks (no private or internal addresses). |
Put images before the question about them for the best results, and label several images (“Image 1:”, “Image 2:”) when you compare them.
Response
Unchanged: the answer is text in choices[0].message.content. Images count as input tokens in usage.prompt_tokens; the breakdown is in usage.prompt_tokens_details.image_tokens.
Cost
Images are billed as input tokens at the model’s input rate:
detail | Tokens |
|---|---|
low | 85 flat, image scaled to fit 512 × 512 |
high / auto | 85 + 170 per 512 × 512 tile after scaling to fit 2,048 × 2,048 and then the short side to 768 |
A 1,024 × 1,024 photo at high becomes 768 × 768 = 4 tiles, so 85 + 680 = 765 tokens. Use token counting to check before sending.
Examples
curl https://app.syntic.ai/v1/chat/completions \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Amara S1.2",
"stream": false,
"messages": [{
"role": "user",
"content": [
{ "type": "image_url", "image_url": { "url": "https://example.com/receipts/4471.jpg" } },
{ "type": "text", "text": "List each line item and the total as a table." }
]
}]
}'Errors
| Status | code | param | Cause |
|---|---|---|---|
| 400 | vision_not_supported | model | The model cannot read images. |
| 400 | unsupported_image_type | messages[i].content[j] | Not PNG, JPEG, WebP or GIF, or the bytes do not match the declared type. |
| 400 | image_too_large | messages[i].content[j] | Over the size limit. |
| 400 | too_many_images | messages | More than 100 images. |
| 400 | image_fetch_failed | messages[i].content[j] | The URL timed out, returned an error, or is not public https. |
| 400 | image_url_blocked | messages[i].content[j] | The URL points at a private or internal address. |
| 404 | file_not_found | ...image_file.file_id | Unknown file, or one from another organisation. |
Privacy
Images sent inline or by URL are handled like any other request content and follow your organisation’s retention settings. Syntic does not keep fetched remote images after the request.
Build notes for the platform team
- Fetch through the shared outbound URL checks; resolve DNS once and pin the address to block rebinding.
- Sniff the real type from bytes; never trust the extension or
Content-Type. - Add
supports_visiontochat.modelsand check it before billing.