> ## 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.

# Managing files

> Upload, list, download, and delete a PDF.

A file on this API is a PDF. You upload it, then attach the ID to a chat request. The file stays on your account until you delete it, or until an expiry you set has passed. [Chat with files](/files/chat-with-files) is how `lume-omni` reads it.

## Upload

`POST /v1/files` needs the scope `files:write`. The body is multipart. `purpose` is `user_data`, and the file name ends in `.pdf`.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.overcontrolgroup.com/v1/files \
    -H "Authorization: Bearer $OVERCONTROL_API_KEY" \
    -F purpose=user_data \
    -F file=@notes.pdf
  ```

  ```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",
  )

  with open("notes.pdf", "rb") as handle:
      uploaded = client.files.create(file=handle, purpose="user_data")

  print(uploaded.id)
  ```

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

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

  const uploaded = await client.files.create({
    file: fs.createReadStream("notes.pdf"),
    purpose: "user_data",
  });

  console.log(uploaded.id);
  ```
</CodeGroup>

The response is the file object. `id` is what you send on the chat request. It is `file-` followed by 32 characters, using letters, digits, `_`, and `-`. `status` is `processed`. The response includes `X-Request-Id`.

```json theme={null}
{
  "id": "file-0123456789abcdef0123456789abcdef",
  "object": "file",
  "bytes": 28416,
  "created_at": 1789430400,
  "filename": "notes.pdf",
  "purpose": "user_data",
  "status": "processed"
}
```

A file can be up to 25 MiB, which is 25 × 1024 × 1024 bytes. Above that, the response is HTTP 413 and the message is `File is too large`. The name has to end in `.pdf`, and the bytes have to be a PDF. `purpose` accepts `user_data`.

You can keep up to 1,000 files, and 100,000,000 bytes in total. An account can create 10 files a minute, and 1,000 files or 1 GiB on a UTC day. Past those limits, you'll get HTTP 429. `error.type` is `rate_limit_error`. The code is `rate_limit_exceeded` with the message `Create rate exceeded`, `storage_quota_exceeded` with `Storage quota exceeded`, or `ingestion_quota_exceeded` with `Ingestion quota exceeded`.

```json theme={null}
{
  "error": {
    "message": "Create rate exceeded",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limit_exceeded"
  }
}
```

To give a file an expiry, send `expires_after[anchor]` as `created_at` and `expires_after[seconds]` together. Seconds run from 3,600 through 30 days. The file object then includes `expires_at`. After that time the file is gone. Leave both fields out and the file stays until you delete it.

## List, retrieve, and download

`GET /v1/files` needs the scope `files:read`. `order` is `desc` or `asc`, and it defaults to `desc`. `limit` defaults to 10,000, which is also the maximum. Pass `after` as a file ID from the page you already have. The body has `object` `list`, `data`, `first_id`, `last_id`, and `has_more`.

`GET /v1/files/{file_id}` returns the same file object. `GET /v1/files/{file_id}/content` returns the PDF bytes, with `Cache-Control: private, no-store`.

If the ID is missing, or it belongs to another account, you'll get HTTP 404. The body does not say which of those it was.

```json theme={null}
{
  "error": {
    "message": "File not found",
    "type": "invalid_request_error",
    "param": null,
    "code": "file_not_found"
  }
}
```

An ID that does not match the `file-` pattern is HTTP 400, with the message `Invalid file ID`.

## Delete

`DELETE /v1/files/{file_id}` needs the scope `files:delete`.

```json theme={null}
{
  "id": "file-0123456789abcdef0123456789abcdef",
  "object": "file",
  "deleted": true
}
```

## Next

<CardGroup cols={2}>
  <Card title="Chat with files" icon="message" href="/files/chat-with-files">
    Ask lume-omni about a PDF.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    See the files scopes on a key.
  </Card>
</CardGroup>


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