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

# Chat with files

> Ask lume-omni about a PDF.

A chat request can read a PDF on `lume-omni`. Attach a file you already uploaded, or send the PDF in the request. The reply is still text, in `choices[0].message.content`.

[Managing files](/files/managing-files) is the upload. The other models take text. Messages does not accept a PDF block. That call is HTTP 400, and the message is `Unsupported content block type`.

## A file you uploaded

`POST /v1/chat/completions` needs the scope `chat:completions`. A `file_id` also needs `files:read`. Send the ID inside a `file` content part, with the question in the same user message.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.overcontrolgroup.com/v1/chat/completions \
    -H "Authorization: Bearer $OVERCONTROL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "lume-omni",
      "max_tokens": 256,
      "messages": [
        {
          "role": "user",
          "content": [
            {"type": "text", "text": "What is this document about?"},
            {"type": "file", "file": {"file_id": "file-0123456789abcdef0123456789abcdef"}}
          ]
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import os
  from openai import OpenAI

  client = OpenAI(
      api_key=os.environ["OVERCONTROL_API_KEY"],
      base_url="https://api.overcontrolgroup.com/v1",
  )

  response = client.chat.completions.create(
      model="lume-omni",
      max_tokens=256,
      messages=[
          {
              "role": "user",
              "content": [
                  {"type": "text", "text": "What is this document about?"},
                  {
                      "type": "file",
                      "file": {"file_id": "file-0123456789abcdef0123456789abcdef"},
                  },
              ],
          }
      ],
  )

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

  ```javascript Node.js theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    apiKey: process.env.OVERCONTROL_API_KEY,
    baseURL: "https://api.overcontrolgroup.com/v1",
  });

  const response = await client.chat.completions.create({
    model: "lume-omni",
    max_tokens: 256,
    messages: [
      {
        role: "user",
        content: [
          { type: "text", text: "What is this document about?" },
          {
            type: "file",
            file: { file_id: "file-0123456789abcdef0123456789abcdef" },
          },
        ],
      },
    ],
  });

  console.log(response.choices[0].message.content);
  ```
</CodeGroup>

The success body is a normal chat completion. `finish_reason` is `stop` when the model finishes inside `max_tokens`. The response includes `X-Request-Id`.

A request can name up to five file IDs. Together they can be at most 25 MiB. One stored file over 25 MiB, or a set that adds up past that, comes back as HTTP 400. The messages are `File input is too large` and `Combined file inputs are too large`.

If the ID is missing, expired, or on another account, you'll get HTTP 404. The message is `File not found`. An ID in the wrong shape is HTTP 400, with `Invalid file ID`.

```json theme={null}
{
  "error": {
    "message": "File not found",
    "type": "invalid_request_error",
    "param": "messages.0.content.1.file.file_id",
    "code": "file_not_found"
  }
}
```

On a model other than `lume-omni`, the same part is HTTP 400. The message is `Parameter 'messages.0.content.1.file.file_id' is not supported for model 'lume-3.5'`, and the code is `unsupported_feature`.

## A PDF in the request

You can skip the upload and send the PDF as `file_data`. Use that or `file_id`, not both. Raw base64 needs `filename`, and the name ends in `.pdf`. A data URL starts with `data:application/pdf;base64,` and does not send a filename.

```python theme={null}
import base64
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["OVERCONTROL_API_KEY"],
    base_url="https://api.overcontrolgroup.com/v1",
)

with open("notes.pdf", "rb") as handle:
    file_data = base64.b64encode(handle.read()).decode("ascii")

response = client.chat.completions.create(
    model="lume-omni",
    max_tokens=256,
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is this document about?"},
                {
                    "type": "file",
                    "file": {"filename": "notes.pdf", "file_data": file_data},
                },
            ],
        }
    ],
)

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

Each inline PDF can be up to 25 MiB. A larger one is HTTP 413, with the message `File input is too large`. The whole request body is still capped at 40 MiB.

## Next

<CardGroup cols={2}>
  <Card title="Managing files" icon="file" href="/files/managing-files">
    Upload the PDF and keep the ID.
  </Card>

  <Card title="Generate text" icon="message" href="/text/generate">
    Continue the conversation from here.
  </Card>
</CardGroup>


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