> ## Documentation Index
> Fetch the complete documentation index at: https://docs.naga.ac/llms.txt
> Use this file to discover all available pages before exploring further.

# Images and files

> Send images, PDFs and audio to a model together with your text, by link or as base64.

A user message can carry images, PDFs and audio next to its text, and the model reads them together. You send each one as a link or as base64 data.

> [tab] Responses
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> response = client.responses.create(
>     model="deepseek-v4.1-flash",
>     input=[{
>         "role": "user",
>         "content": [
>             {"type": "input_text", "text": "What is in this image? One sentence."},
>             {"type": "input_image", "image_url": "https://docs.naga.ac/static/img/playground-chat.png"},
>         ],
>     }],
> )
>
> print(response.output_text)
> ```
>
> ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import OpenAI from "openai";
>
> const client = new OpenAI({ baseURL: "https://api.naga.ac/v1", apiKey: process.env.NAGA_API_KEY });
>
> const response = await client.responses.create({
>   model: "deepseek-v4.1-flash",
>   input: [{
>     role: "user",
>     content: [
>       { type: "input_text", text: "What is in this image? One sentence." },
>       { type: "input_image", image_url: "https://docs.naga.ac/static/img/playground-chat.png" },
>     ],
>   }],
> });
>
> console.log(response.output_text);
> ```

> [tab] Chat Completions
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> completion = client.chat.completions.create(
>     model="deepseek-v4.1-flash",
>     messages=[{
>         "role": "user",
>         "content": [
>             {"type": "text", "text": "What is in this image? One sentence."},
>             {"type": "image_url", "image_url": {"url": "https://docs.naga.ac/static/img/playground-chat.png"}},
>         ],
>     }],
> )
>
> print(completion.choices[0].message.content)
> ```
>
> ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import OpenAI from "openai";
>
> const client = new OpenAI({ baseURL: "https://api.naga.ac/v1", apiKey: process.env.NAGA_API_KEY });
>
> const completion = await client.chat.completions.create({
>   model: "deepseek-v4.1-flash",
>   messages: [{
>     role: "user",
>     content: [
>       { type: "text", text: "What is in this image? One sentence." },
>       { type: "image_url", image_url: { url: "https://docs.naga.ac/static/img/playground-chat.png" } },
>     ],
>   }],
> });
>
> console.log(completion.choices[0].message.content);
> ```
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> curl https://api.naga.ac/v1/chat/completions \
>   -H "Authorization: Bearer $NAGA_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "model": "deepseek-v4.1-flash",
>     "messages": [{
>       "role": "user",
>       "content": [
>         {"type": "text", "text": "What is in this image? One sentence."},
>         {"type": "image_url", "image_url": {"url": "https://docs.naga.ac/static/img/playground-chat.png"}}
>       ]
>     }]
>   }'
> ```

> [tab] Messages
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import os
> from anthropic import Anthropic
>
> client = Anthropic(base_url="https://api.naga.ac", api_key=os.environ["NAGA_API_KEY"])
>
> message = client.messages.create(
>     model="claude-haiku-4.5",
>     max_tokens=1024,
>     messages=[{
>         "role": "user",
>         "content": [
>             {"type": "image", "source": {"type": "url", "url": "https://docs.naga.ac/static/img/playground-chat.png"}},
>             {"type": "text", "text": "What is in this image? One sentence."},
>         ],
>     }],
> )
>
> print(message.content[0].text)
> ```
>
> ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import Anthropic from "@anthropic-ai/sdk";
>
> const client = new Anthropic({ baseURL: "https://api.naga.ac", apiKey: process.env.NAGA_API_KEY });
>
> const message = await client.messages.create({
>   model: "claude-haiku-4.5",
>   max_tokens: 1024,
>   messages: [{
>     role: "user",
>     content: [
>       { type: "image", source: { type: "url", url: "https://docs.naga.ac/static/img/playground-chat.png" } },
>       { type: "text", text: "What is in this image? One sentence." },
>     ],
>   }],
> });
>
> for (const block of message.content) {
>   if (block.type === "text") console.log(block.text);
> }
> ```

The model answers with one sentence about the picture.

## Check what the model reads

`architecture.input_modalities` of each model in [`/v1/models`](https://docs.naga.ac/get-started/models) lists what it reads: `text`, `image`, `audio` and `file`. Check it before you send anything other than text. NagaAI refuses a part the model can't read with `400 unsupported_modality` before the request reaches a provider.

## Parts in each format

| | Responses | Chat Completions | Messages |
| - | - | - | - |
| Image | `{"type": "input_image", "image_url"}` | `{"type": "image_url", "image_url": {"url"}}` | `{"type": "image", "source"}` with a `url` or `base64` source |
| File or PDF | `{"type": "input_file", "filename", "file_data"}` or `file_url` | `{"type": "file", "file": {"filename", "file_data"}}` or `file_url` | `{"type": "document", "source"}` with a `base64`, `url` or `text` source |
| Audio | `{"type": "input_audio", "input_audio": {"data", "format"}}` | `{"type": "input_audio", "input_audio": {"data", "format"}}` | Not available |

An image link is an `https` URL or a data URI. In Responses and Chat Completions, `detail` sets how closely the model looks at the image: `low`, `high` or `auto`.

One inline image, file or audio part can be up to 20 MiB, and the whole request up to 32 MiB.

## Files and PDFs

Send a file as base64 data or as an `https` link. NagaAI has no Files API, so it can't resolve a `file_id`. Some providers of a model that reads files have no file input. NagaAI sends such a provider the text of the file instead.

> [tab] Responses
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import base64
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> with open("report.pdf", "rb") as f:
>     pdf = base64.b64encode(f.read()).decode()
>
> response = client.responses.create(
>     model="claude-haiku-4.5",
>     input=[{
>         "role": "user",
>         "content": [
>             {"type": "input_text", "text": "Summarize this document in two sentences."},
>             {"type": "input_file", "filename": "report.pdf", "file_data": f"data:application/pdf;base64,{pdf}"},
>         ],
>     }],
> )
>
> print(response.output_text)
> ```

> [tab] Chat Completions
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import base64
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> with open("report.pdf", "rb") as f:
>     pdf = base64.b64encode(f.read()).decode()
>
> completion = client.chat.completions.create(
>     model="claude-haiku-4.5",
>     messages=[{
>         "role": "user",
>         "content": [
>             {"type": "text", "text": "Summarize this document in two sentences."},
>             {"type": "file", "file": {"filename": "report.pdf", "file_data": f"data:application/pdf;base64,{pdf}"}},
>         ],
>     }],
> )
>
> print(completion.choices[0].message.content)
> ```

> [tab] Messages
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import base64
> import os
> from anthropic import Anthropic
>
> client = Anthropic(base_url="https://api.naga.ac", api_key=os.environ["NAGA_API_KEY"])
>
> with open("report.pdf", "rb") as f:
>     pdf = base64.b64encode(f.read()).decode()
>
> message = client.messages.create(
>     model="claude-haiku-4.5",
>     max_tokens=1024,
>     messages=[{
>         "role": "user",
>         "content": [
>             {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": pdf}},
>             {"type": "text", "text": "Summarize this document in two sentences."},
>         ],
>     }],
> )
>
> print(message.content[0].text)
> ```
>
> ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import fs from "node:fs";
> import Anthropic from "@anthropic-ai/sdk";
>
> const client = new Anthropic({ baseURL: "https://api.naga.ac", apiKey: process.env.NAGA_API_KEY });
>
> const pdf = fs.readFileSync("report.pdf").toString("base64");
>
> const message = await client.messages.create({
>   model: "claude-haiku-4.5",
>   max_tokens: 1024,
>   messages: [{
>     role: "user",
>     content: [
>       { type: "document", source: { type: "base64", media_type: "application/pdf", data: pdf } },
>       { type: "text", text: "Summarize this document in two sentences." },
>     ],
>   }],
> });
>
> for (const block of message.content) {
>   if (block.type === "text") console.log(block.text);
> }
> ```

In Chat Completions, `file_url` is a NagaAI addition to the official format. In Messages, a `document` takes a `base64` PDF with `media_type: "application/pdf"`, a `url` to a PDF, or `text` with `media_type: "text/plain"`. NagaAI drops a document with a `content` source without an error, so the model never sees it.

## Audio

Responses and Chat Completions take audio in an `input_audio` part. `data` is plain base64 without a `data:` prefix, and `format` is one of `wav`, `mp3`, `aiff`, `aac`, `ogg`, `flac`, `m4a`, `pcm16` or `pcm24`. The official API accepts only `wav` and `mp3`.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import base64
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])

with open("question.mp3", "rb") as f:
    audio = base64.b64encode(f.read()).decode()

completion = client.chat.completions.create(
    model="gemini-3.7-flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Transcribe this and answer the question."},
            {"type": "input_audio", "input_audio": {"data": audio, "format": "mp3"}},
        ],
    }],
)

print(completion.choices[0].message.content)
```

## Images in the answer

Models that draw return the picture in the response. In Chat Completions it arrives in `message.images`, a list of `{"type": "image_url", "image_url": {"url": "..."}}` entries next to `content`. The `url` is either a `data:` URI or an `https` link, so handle both. In Responses it's an `image_generation_call` output item with the image in `result` and its type in `mime_type`.

To edit the picture on the next turn, send the assistant message back with its `images`, or the `image_generation_call` item in `input`. The model then changes that picture instead of drawing a new one.

## Troubleshooting

### `400 unsupported_modality`

The model doesn't read this kind of part. Pick a model whose `input_modalities` lists it, or send the content as text.

### `400 file_id_unsupported`

NagaAI has no Files API. Send the file itself in `file_data` or as a link in `file_url`.

### `400` on `input_audio`

`input_audio.data` starts with `data:`. Send the base64 string without the prefix.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.