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

# Upload File

> Upload a file to a collection for conversion and indexing.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.doctly.ai/api/v1/collections/{collection_id}/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@quarterly-report.pdf" \
    -F "path=2026/reports/quarterly-report.pdf"
  ```
</RequestExample>

**POST** `/api/v1/collections/{collection_id}/files`

Uploads a file, converts it to text, and indexes it for retrieval. Files up to **100 MB** are supported; larger uploads return `413`.

The upload is **idempotent and versioned** by `path`:

* Re-uploading the same path with identical content returns the existing file unchanged.
* Re-uploading the same path with new content creates a new version and re-indexes it.

Supported formats include PDF, DOCX, spreadsheets, HTML, images, and plain text. Unsupported formats are stored as-is (status `stored`) without indexing.

## Path Parameters

<ParamField path="collection_id" type="string" required>
  The collection's UUID.
</ParamField>

## Body Parameters

<ParamField body="file" type="file" required>
  The file to upload, as `multipart/form-data`.
</ParamField>

<ParamField body="path" type="string">
  Logical path within the collection (e.g. `2026/reports/q1.pdf`). Defaults to the uploaded filename. The path is the file's stable identity for versioning.
</ParamField>

## Response

Returns a [file object](#the-file-object) with `status: "pending"`. Poll [Get File](/api-reference/collection-files/get) until the status becomes `ready` (or `failed`).

## The File object

<ResponseField name="id" type="string">
  Unique identifier (UUID) for the file. Use this ID in citations and file filters.
</ResponseField>

<ResponseField name="path" type="string">
  Logical path within the collection — the file's stable identity.
</ResponseField>

<ResponseField name="filename" type="string">
  Base filename.
</ResponseField>

<ResponseField name="status" type="string">
  Processing status: `pending` → `processing` → `ready` | `failed`. Unsupported formats are `stored`.
</ResponseField>

<ResponseField name="version" type="integer">
  Version number, incremented each time new content is uploaded to the same path.
</ResponseField>

<ResponseField name="source_file_size" type="integer">
  File size in bytes.
</ResponseField>

<ResponseField name="page_count" type="integer">
  Number of pages, when applicable.
</ResponseField>

<ResponseField name="last_error" type="string">
  Failure reason when `status` is `failed`.
</ResponseField>

<ResponseField name="indexed_at" type="string">
  Timestamp when indexing completed.
</ResponseField>

```json Response theme={null}
{
  "id": "3c9d2f6e-6a5b-4a37-9f0d-2e8a7d4c1b90",
  "path": "2026/reports/quarterly-report.pdf",
  "filename": "quarterly-report.pdf",
  "status": "pending",
  "version": 1,
  "source_file_size": 1048576,
  "page_count": null,
  "last_error": null,
  "indexed_at": null,
  "created_at": "2026-07-30T02:10:00Z",
  "updated_at": "2026-07-30T02:10:00Z"
}
```
