> For a complete page index of the Captain API documentation, fetch https://docs.captain.dev/llms.txt?excludeSpec=true

# File Size Limits

> Per-file and per-request size limits for indexing, broken down by how the file reaches Captain (dashboard upload, direct API upload, raw text, or a cloud storage connector) and by file type.

## Agent Quick Reference - File Size Limits

Two independent limits. A file must clear both.

STEP 1, upload (sending Captain the bytes). Depends on the endpoint:

* **Dashboard upload / presigned S3 upload**: 500 MB per file
* **`POST /v2/collections/{name}/index/file`** (direct multipart upload): 100 MB per file, 20 files per request
* **`POST /v2/collections/{name}/index/text`** (raw text body): 10 MB
* **Cloud storage connectors** (S3, GCS, Azure Blob, Cloudflare R2, Supabase Storage, Backblaze B2, Dropbox, Google Drive, SharePoint, OneDrive): NO upload step at all, so no upload limit. Captain reads the file from the source.

STEP 2, indexing (parse, chunk, embed). Depends on the file type, and applies to every file including connector-read ones:

* **Text-based types** (`.json`, `.txt`, `.md`, `.csv`, `.tsv`, `.yaml`, `.yml`, and every source code, markup, and config extension on [Supported File Types](/guides/supported-file-types)): **250 MB per file**, with or without a `parsing_script`.
* **`.json` with a `parsing_script`** also gets a 60s script execution timeout. The string your script returns must fit in V8, roughly 512 MB.
* **PDF, DOCX, XLSX, images, audio, video**: no indexing limit of their own; the upload limit is their only ceiling.
* **Image dimensions**: supported up to 200 megapixels of decoded pixels (roughly 20,000 x 10,000), one limit for every image format (120 MP verified end to end, with or without `mask_pii`). Over the limit fails as a per-file error on the job record without blocking the batch (decompression-bomb guard). With `mask_pii`, OCR upscales images with a short side under 3,000px up to 4x, long side bounded at 4,000px; images with a short side of 3,000px or more run at native resolution; OCR-internal only, redaction boxes land at full precision.

Failure modes: exceeding a STEP 1 limit returns HTTP 400 immediately with the limit in the `detail` field. Exceeding a STEP 2 limit is accepted as a job and fails during indexing, with the error on the job record (`GET /v2/jobs/{job_id}`). Connector jobs always fail the second way.

See [Supported File Types](/guides/supported-file-types) for the full extension list.

## Uploading and indexing limits

A file goes through two stages on the way in, and each one caps size differently. Captain
first takes in the bytes, and how big they can be depends on the endpoint that sent them.
It then parses, chunks, and embeds the file, where the ceiling comes from the file type
instead. A file has to clear both.

Indexing through cloud storage skips the uploading step entirely. Grant Captain read
access to a bucket or drive and it pulls the file straight from the source, so the upload
limit never comes into play. Indexing works the same either way.

For the full list of file types and extensions Captain indexes, see
[Supported File Types](/guides/supported-file-types).

### Step 1. Upload

| Upload method                                      | Upload limit                          |
| -------------------------------------------------- | ------------------------------------- |
| **Dashboard upload** (and any presigned S3 upload) | 500 MB per file                       |
| **`POST /v2/collections/{name}/index/file`**       | 100 MB per file, 20 files per request |
| **`POST /v2/collections/{name}/index/text`**       | 10 MB of text                         |
| **Cloud storage connectors**                       | No upload step, so no upload limit    |

Connectors are available for:

* Amazon S3
* Google Cloud Storage
* Azure Blob Storage
* Cloudflare R2
* Supabase Storage
* Backblaze B2
* Dropbox
* Google Drive
* SharePoint
* OneDrive

The dashboard switches to a multipart upload on its own for anything over 4 MB.

### Step 2. Indexing

These limits apply to every file, including the ones Captain reads from cloud storage.

#### JSON

`.json` files are limited to **250 MB**, whether or not you pass a `parsing_script`.

If you pass a `parsing_script`, the file also has to fit in the sandbox that runs your
script:

| Constraint                        | Limit                          |
| --------------------------------- | ------------------------------ |
| JSON passed to the parsing script | 250 MB                         |
| Script execution time             | 60 seconds                     |
| Returned string                   | Must fit in V8, roughly 512 MB |

Scripts that build large intermediate objects can still run out of memory below that
ceiling.

#### Text, Markdown, CSV, YAML, and code

`.txt`, `.md`, `.csv`, `.tsv`, `.yaml`, `.yml`, and the source code, markup, and config
extensions on [Supported File Types](/guides/supported-file-types) are limited to **250 MB per file**,
the same ceiling as JSON. When the storage provider supports a preflight size check,
files above that limit are rejected before download. Otherwise, they are rejected after download.

Split larger files. Chunking a huge document into per-record or per-section files also
produces better search results than one enormous document.

#### Everything else

PDF, Office documents, images, audio, and video have no indexing limit of their own, so
the upload limit is the only ceiling they have to clear. Very large media files take
longer to process because they are transcribed or analyzed frame by frame.

#### Image dimensions

Images are supported up to 200 megapixels, roughly 20,000 x 10,000, in every format.

The limit guards against decompression bombs, where a small file decodes to an enormous
raster. An image over 200 megapixels fails as a clean per-file error on the job record
and never blocks the rest of the batch.

With `mask_pii` enabled, Captain adjusts image resolution for OCR accuracy before
redaction. Images with a short side under 3,000px are upscaled up to 4x so small text
reads reliably, and the upscaled long side is bounded at 4,000px so a large image never
balloons in memory. Images with a short side of 3,000px or more are processed at native
resolution. These bounds affect OCR internals only; the indexed image keeps its content,
and redaction boxes land at full precision either way.

## What happens when you go over

A file too big for the upload step comes back right away with a `400` naming the limit for
the endpoint it hit. Here is a 180 MB PDF sent to
`POST /v2/collections/{name}/index/file`, which tops out at 100 MB:

```json
{
  "detail": "File 'annual-report.pdf' exceeds maximum size of 100MB"
}
```

That same PDF uploads fine from the dashboard, which takes 500 MB.

A file too big for the indexing step behaves differently. Captain accepts the job, then
fails it while reading the file, since that is the first point where the type limit gets
checked. Cloud storage jobs always fail this way because there is no upload step to catch
them earlier. The error lands on the job record, readable with `GET /v2/jobs/{job_id}`.

## Working with larger files

The right fix depends on which limit is blocking the file.

**A text-based file over 250 MB** is hitting the indexing limit, and splitting it is the
only way through. No upload route gets around that one. Per-record or per-section files
also search better than one enormous document, so this is usually worth doing anyway.

**A PDF, Office doc, image, audio, or video between 100 MB and 500 MB** is only hitting
the upload limit on `POST /v2/collections/{name}/index/file`. Send it from the dashboard
instead, which takes 500 MB, and it indexes normally.

**A non-text file over 500 MB** is past every upload endpoint. Put it in a cloud storage
bucket and index it from there. Captain reads it from the source, so the upload limit
drops out and only the indexing limits are left.