# Bulk File & Image Downloader (URLs to ZIP) (`rsiddiq95/bulk-file-downloader`) Actor

Download any list of file or image URLs into Apify storage with file name, type, size and SHA-256 for each, duplicate detection, type and size filters, and an optional ZIP of everything.

- **URL**: https://apify.com/rsiddiq95/bulk-file-downloader.md
- **Developed by:** [Rafiullah Siddiq](https://apify.com/rsiddiq95) (community)
- **Categories:** Developer tools, Automation, E-commerce
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 file storeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bulk File & Image Downloader (URLs to ZIP)

Download **any list of file URLs** (images, PDFs, documents, audio, video, anything) into Apify storage in one run, and get **one ZIP with everything**. Each file gets a row with its **file name, type, size, SHA-256 hash** and a direct download link. Identical files are stored once, and you can keep only the types and sizes you want.

Paste URLs, or point it at the **dataset of another Actor** (a product, real-estate or social media scraper, for example) to download every image it found.

### What can this bulk downloader do?

- 📥 **Any file type:** JPG, PNG, WebP, AVIF, SVG, GIF, PDF, Word, Excel, CSV, ZIP, MP3, MP4 and more.
- 🗜️ **One ZIP of everything:** `ALL_FILES.zip` in the run's key-value store, ready to download (up to 200 MB of files).
- 🔗 **URLs from other Actors:** give a dataset ID and the fields to read (`images`, `imageUrl`, `url`...). Lists of URLs and objects with a `url` work too.
- 🧬 **Duplicate detection:** files with identical content are stored once, even from different URLs. Duplicates are free.
- 🎯 **Filters:** only certain types (`image/`, `pdf`, `jpg`, `video/mp4`), and a maximum file size.
- 🏷️ **Proper names and types:** names come from the server or the URL, and the type is checked against the file's own bytes, so a JPG served as "application/octet-stream" still gets `.jpg`.
- 🔁 **Retries** on timeouts, rate limits and server errors, and runs resume where they stopped after a migration.

### Who uses it?

- **E-commerce teams** downloading product images found by a store scraper.
- **Researchers and analysts** saving PDFs, reports and datasets from a list of links.
- **Marketers and agencies** backing up creatives and media libraries.
- **AI and ML teams** collecting image datasets, with SHA-256 for de-duplication and integrity.

### How to download files in bulk

1. Paste **File URLs**, one per line, or enter a **dataset ID** from another Actor run.
2. Optionally set **File types**, **Max file size** and whether to **Create a ZIP**.
3. Click **Start**. Open the **Storage → Key-value store** tab for the files and `ALL_FILES.zip`, or the **Output** tab for the list.

### Input example

```json
{
    "urls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", "https://httpbin.org/image/png"],
    "datasetId": "",
    "fileTypes": ["image/", "pdf"],
    "maxFileSizeMb": 25,
    "deduplicate": true,
    "createZip": true
}
```

### Output example

```json
{
    "resultType": "file",
    "url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
    "finalUrl": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
    "fileName": "dummy.pdf",
    "contentType": "application/pdf",
    "sizeBytes": 13264,
    "sha256": "3df79d34abbca99308e79cb94461c1893582604d68329a41fd4bec1885e6adb4",
    "httpStatus": 200,
    "status": "downloaded",
    "key": "dummy.pdf",
    "fileUrl": "https://api.apify.com/v2/key-value-stores/<store-id>/records/dummy.pdf",
    "downloadedAt": "2026-11-09T12:00:00.000Z"
}
```

Every URL gets a row. `status` is `downloaded`, `duplicate` (with `duplicateOf`), `skipped` (too large or filtered out, with the reason) or `failed` (with the HTTP status or error).

### Use it from AI agents (Claude, ChatGPT, Cursor)

AI assistants can run this Actor as a tool through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp):

```
https://mcp.apify.com?tools=rsiddiq95/bulk-file-downloader
```

### How much does it cost?

Pay per file stored, plus a small amount per full megabyte for large files (files under 1 MB pay nothing extra). See the **Pricing** tab. Failed, skipped and duplicate URLs are free.

### Limitations

- Direct file links only. Pages that need a login, a browser or a bot check are not supported; you can pass your own headers (for example a token for your own storage) in **Request headers**.
- Files are kept in the run's key-value store for your plan's data retention period. Download the ZIP or copy the files elsewhere if you need them longer.
- The ZIP holds up to 200 MB of files; any beyond that are still stored individually and the log says so.
- Maximum single file size is 500 MB.

### FAQ

**Where are my files?**
In the run's **Storage → Key-value store**. Each row's `fileUrl` links straight to its file.

**Something isn't working.**
Open an issue on the **Issues** tab with your input.

# Actor input Schema

## `urls` (type: `array`):

Direct links to images, PDFs, documents, audio, video or any other file, one per line.

## `datasetId` (type: `string`):

A dataset from another Actor run (for example a product or image scraper). URLs are read from the fields below.

## `urlFields` (type: `array`):

Fields of the dataset items that hold file URLs. A field can hold one URL, a list of URLs, or objects with a url.

## `fileTypes` (type: `array`):

Keep only these types, for example image/, pdf, jpg or video/mp4. Leave empty for every type. Other files are skipped for free.

## `maxFileSizeMb` (type: `number`):

Larger files are skipped for free. Decimals work, for example 0.5.

## `deduplicate` (type: `boolean`):

Files with identical content (same SHA-256), even from different URLs, are stored once. Duplicates are free.

## `createZip` (type: `boolean`):

Also save ALL_FILES.zip in the key-value store (up to 200 MB of files).

## `headers` (type: `object`):

Optional HTTP headers sent with every download, for example {"Referer": "https://example.com/"} or an API token for your own files.

## `maxConcurrency` (type: `integer`):

How many files to download at the same time.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com/img/apify-logo/logomark-32x32.svg",
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ],
  "urlFields": [
    "url",
    "imageUrl",
    "images",
    "downloadUrl",
    "fileUrl"
  ],
  "fileTypes": [],
  "maxFileSizeMb": 100,
  "deduplicate": true,
  "createZip": true,
  "headers": {},
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://apify.com/img/apify-logo/logomark-32x32.svg",
        "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rsiddiq95/bulk-file-downloader").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        "https://apify.com/img/apify-logo/logomark-32x32.svg",
        "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("rsiddiq95/bulk-file-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://apify.com/img/apify-logo/logomark-32x32.svg",
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ]
}' |
apify call rsiddiq95/bulk-file-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rsiddiq95/bulk-file-downloader"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/lzUOpt7rRsgfO3V7C/builds/nDZhsbNEIyvEqB3pL/openapi.json
