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

# Upload File

POST https://api.captain.dev/v3/parse/uploads
Content-Type: multipart/form-data

Uploads a file from local disk so it can be parsed. Returns a `captain://` id to pass as `input` to Parse Document or Parse Spreadsheet. Files that already sit behind a direct download link do not need this step.

Uploads are limited to 100 MB, can be parsed any number of times, and are deleted after 24 hours. Uploading is not billed.

Reference: https://docs.captain.dev/reference/v3/parse/uploads

## Request

### Headers

- `authorization` (string, optional)

### Body (multipart/form-data)

This endpoint expects a multipart form containing a file.

- `file` (file, required) — The file to upload, up to 100 MB.

## Response

### 200

The upload.

- `file_id` (string, required) — Pass this as `input` to Parse Document or Parse Spreadsheet.
- `expires_at` (string, required) — The upload is deleted 24 hours after it was created. After that the id no longer works.

## Errors

### 400 Bad Request Error

The file is empty (`empty_file`).

- `error` (string, required)
- `message` (string, required)
- `path` (string, optional)

### 401 Unauthorized Error

Missing or invalid API key.

- `error` (string, optional)
- `message` (string, optional)

### 413 Content Too Large Error

The file is larger than 100 MB (`file_too_large`).

- `error` (string, required)
- `message` (string, required)
- `path` (string, optional)

### 503 Service Unavailable Error

Parse is not available right now. Nothing was stored. Retry later.

- `error` (string, required)
- `message` (string, required)
- `path` (string, optional)

## Examples

**Response**

```json
{
  "file_id": "captain://upl_5d41402abc4b2a76b9719d911017c592",
  "expires_at": "2026-10-02T15:03:50Z"
}
```

**SDK Code**

```python
import requests

BASE_URL = "https://api.captain.dev"
API_KEY = "your_api_key"

with open("ledger.xlsx", "rb") as f:
    upload = requests.post(
        f"{BASE_URL}/v3/parse/uploads",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files={"file": f},
        timeout=120,
    ).json()

print(upload["file_id"])
```

```typescript
import { readFile } from "node:fs/promises";

const BASE_URL = "https://api.captain.dev";
const API_KEY = "your_api_key";

const form = new FormData();
form.append("file", new Blob([await readFile("ledger.xlsx")]), "ledger.xlsx");

const response = await fetch(`${BASE_URL}/v3/parse/uploads`, {
  method: "POST",
  headers: { Authorization: `Bearer ${API_KEY}` },
  body: form,
});

const upload = await response.json();
console.log(upload.file_id);
```