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

# Upload

> Upload documents to Reducto using the JavaScript SDK

The `upload` method uploads files to Reducto's servers and returns a file reference that you can use with other endpoints.

***

## Basic Usage

```javascript theme={null}
import Reducto from 'reductoai';
import fs from 'fs';

const client = new Reducto();

// Upload a file
const upload = await client.upload({ 
  file: fs.createReadStream("document.pdf") 
});

// Use the file_id in other operations
console.log(upload.file_id);  // "reducto://abc123def456.pdf"
```

***

## Method Signature

```typescript theme={null}
upload(params?: {
  file?: Uploadable | null;
  extension?: string | null;
}, options?: RequestOptions): Promise<Upload>
```

### Parameters

| Parameter   | Type                 | Required | Description                                                                                             |
| ----------- | -------------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `file`      | `Uploadable \| null` | No       | The file to upload. Can be a `File`, `fs.ReadStream`, `fetch Response`, or result of `toFile()` helper. |
| `extension` | `string \| null`     | No       | File extension hint (e.g., "pdf"). Usually auto-detected from filename.                                 |

### Returns

`Promise<Upload>` with the following fields:

* `file_id` (string): The file reference to use with other endpoints (format: `reducto://...`)

***

## Upload Options

### From File Stream

The most common way to upload:

```javascript theme={null}
import fs from 'fs';

const upload = await client.upload({ 
  file: fs.createReadStream("invoice.pdf") 
});
```

### From Buffer

```javascript theme={null}
import Reducto, { toFile } from 'reductoai';
import fs from 'fs';

const fileBuffer = fs.readFileSync("document.pdf");
const file = await toFile(fileBuffer, "document.pdf");
const upload = await client.upload({ file });
```

### From File Object

```javascript theme={null}
import Reducto, { toFile } from 'reductoai';

// Convert various formats to File
const file = await toFile(new Uint8Array([0, 1, 2]), "file.pdf");
const upload = await client.upload({ file });
```

### From URL (Presigned URLs)

For large files, you can generate a presigned URL and pass it directly to parse/extract endpoints without uploading:

```javascript theme={null}
// For files > 100MB, use presigned URLs
// See: /upload/large-files for details

// You can pass presigned URLs directly to parse/extract
const result = await client.parse.run({ 
  input: "https://bucket.s3.amazonaws.com/doc.pdf?X-Amz-..." 
});
```

***

## File Size Limits

* **Direct upload**: Up to 100MB
* **Presigned URLs**: Up to 5GB

For files larger than 100MB, use presigned URLs instead of the upload endpoint.

<Card title="Large File Upload Guide" icon="file-arrow-up" href="/upload/large-files">
  Complete guide to uploading large files using presigned URLs.
</Card>

***

## Supported File Types

The SDK accepts any file type that Reducto supports. Common formats include:

* **Documents**: PDF, DOCX, DOC, RTF
* **Images**: PNG, JPEG, TIFF, BMP
* **Spreadsheets**: XLSX, XLS, CSV
* **Presentations**: PPTX, PPT

<Card title="Supported File Formats" icon="file" href="/upload/overview#supported-file-types">
  Complete list of supported file formats.
</Card>

***

## Error Handling

```javascript theme={null}
import Reducto, { APIError, BadRequestError } from 'reductoai';

try {
  const upload = await client.upload({ 
    file: fs.createReadStream("document.pdf") 
  });
} catch (error) {
  if (error instanceof BadRequestError) {
    console.error(`Invalid file: ${error.status} - ${error.message}`);
  } else if (error instanceof APIError) {
    console.error(`Upload failed: ${error.status} - ${error.message}`);
  }
}
```

Common errors:

* **File not found**: The file path doesn't exist
* **File too large**: File exceeds 100MB limit (use presigned URLs)
* **Invalid file type**: File format not supported
* **Network error**: Connection issues during upload

***

## Examples

### Upload and Parse

```javascript theme={null}
import Reducto from 'reductoai';
import fs from 'fs';

const client = new Reducto();

// Upload
const upload = await client.upload({ 
  file: fs.createReadStream("invoice.pdf") 
});

// Parse immediately
const result = await client.parse.run({ input: upload.file_id });
```

### Batch Upload

```javascript theme={null}
import Reducto from 'reductoai';
import fs from 'fs';

const client = new Reducto();
const files = ["doc1.pdf", "doc2.pdf", "doc3.pdf"];

const uploads = [];
for (const filePath of files) {
  const upload = await client.upload({ 
    file: fs.createReadStream(filePath) 
  });
  uploads.push(upload);
  console.log(`Uploaded ${filePath}: ${upload.file_id}`);
}
```

### Upload with Extension Hint

```javascript theme={null}
import Reducto from 'reductoai';
import fs from 'fs';

const client = new Reducto();

// Upload with an extension hint (useful when filename is missing)
const upload = await client.upload({
  file: fs.createReadStream("document"),
  extension: "pdf"
});

console.log(upload.file_id);
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Use File Streams" icon="file">
    Prefer `fs.createReadStream()` for large files to avoid loading entire file into memory.
  </Card>

  <Card title="Handle Large Files" icon="file-arrow-up">
    For files > 100MB, use presigned URLs instead of direct upload.
  </Card>

  <Card title="Reuse File IDs" icon="repeat">
    File IDs can be reused across multiple operations without re-uploading.
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation">
    Always wrap uploads in try/catch blocks for production code.
  </Card>
</CardGroup>

***

## Next Steps

* Learn about [parsing documents](/sdk/javascript/parse) after upload
* Explore [extracting data](/sdk/javascript/extract) from uploaded files
* Check out [large file uploads](/upload/large-files) for files > 100MB
