Bulk File & Image Downloader – Download URLs to ZIP avatar

Bulk File & Image Downloader – Download URLs to ZIP

Pricing

from $0.60 / 1,000 file downloadeds

Go to Apify Store
Bulk File & Image Downloader – Download URLs to ZIP

Bulk File & Image Downloader – Download URLs to ZIP

Download files, images and PDFs from a list of URLs in bulk – paste the URLs or send them from the API, Make or n8n. Each file is saved to the Key-Value store with a status row, plus one optional ZIP. Dedupes, safe filenames, size caps. $1 per 1,000 files; failed downloads are free.

Pricing

from $0.60 / 1,000 file downloadeds

Rating

0.0

(0)

Developer

Chris Elder

Chris Elder

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

3

Monthly active users

12 hours ago

Last modified

Share

Bulk File Downloader downloads files, images and PDFs from a list of URLs in bulk. Each file is saved to the run’s Key-Value store with one status row per URL, and you can get everything as one ZIP. Built for scraper clean-up, dataset exports, creative ops and agent pipelines that need “save these URLs as files”.

Store page: apify.com/chris_elder/bulk-file-downloader

✅ Pay per result: $1 per 1,000 files · 🆓 Failed downloads are never charged · 🔑 No API key

▶ Try it with one click · 📄 Real example output · 💲 Pricing · 🔌 API & integrations · ❓ FAQ · 🛟 Support

What does Bulk File Downloader do?

It is a bulk downloader for a list of file URLs or an Apify dataset (images, PDFs, CSVs, ZIPs, audio – any file type within the size cap). You give it URLs – or a scraper run’s dataset – and it gives you the files.

  • 📥 Bulk download from any http(s) URL list (strings or {url, fileName, key})
  • 🗃️ Download from an Apify dataset – pass datasetId + urlField; no copy-pasting URL columns
  • 🗂️ Key-Value store output – each file saved under a stable key
  • 📦 Optional ZIP – OUTPUT.zip with all successful files
  • 🔁 Deduping & safe names – duplicate URLs skipped; filenames sanitised
  • 🛡️ SSRF guard – private/internal hosts refused (not charged)
  • 📏 Size cap – oversize files skipped free (default 10 MB, max 50 MB)
  • 🆓 Failures free – 404s, timeouts and blocked hosts are listed and not charged

Use cases

  • Scraper users – point datasetId at a scraper run and turn its image/PDF URL column into a ZIP for hand-off
  • Creative / marketing ops – batch-pull assets from a sheet
  • Agents & n8n/Make – “download these links” as one step
  • Developers – archive attachments from an API response list
  • E-commerce / catalogue teams – download product images from a URL column (export the column from your sheet or CSV and paste it as urls)

How to use it

  1. Click Try for free – the prefill downloads a tiny PDF and a PNG (2 files ≈ $0.0025 including the start fee).
  2. Paste your URL list into urls.
  3. Leave createZip on to get OUTPUT.zip in the Key-Value store.
  4. Download individual keys or the ZIP from the run storage.

Input example

{
"urls": [
"https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
{ "url": "https://httpbin.org/image/png", "fileName": "sample.png" }
],
"createZip": true,
"maxFiles": 100
}

Other options: maxFileBytes, zipKey, dedupe, maxConcurrency, requestDelayMs, timeoutSecs.

Download files from an Apify dataset

Already scraped the URLs with another Actor? Skip the copy-paste and point this Actor at that dataset:

{
"datasetId": "YOUR_DATASET_ID",
"urlField": "imageUrl",
"createZip": true,
"maxFiles": 500
}
  • datasetId – a dataset ID or name (for a scraper run, use its defaultDatasetId). The Actor gets read-only access to that one dataset only.
  • urlField – the field holding the URL (default url). Dots reach nested fields (file.url); a field holding a list of URLs (e.g. images) downloads each one.
  • Rows with a missing or blank URL are skipped and never charged; the count is in RUN_SUMMARY (skippedMissingUrl). Failed downloads stay free as usual.
  • You can combine urls and datasetId in one run; duplicates are removed. In the Console form the 2 sample URLs are ignored automatically when a dataset is given.

Example: 2 URLs in → 2 files + a ZIP out

Input URLWhat you get
https://www.w3.org/.../dummy.pdfKey-Value record file-0000-3eba3cf786-dummy.pdf (13,264 bytes, application/pdf)
https://httpbin.org/image/pngKey-Value record file-0001-e10e7241ca-png.png (8,090 bytes, image/png)
(both)OUTPUT.zip with both files (21,560 bytes) + RUN_SUMMARY {"saved": 2, "failed": 0}

Output example (from a real public run)

Public run data (no login needed): dataset JSON · dataset CSV · OUTPUT.zip · RUN_SUMMARY

One dataset row per URL:

{
"index": 0,
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"ok": true,
"key": "file-0000-3eba3cf786-dummy.pdf",
"fileName": "dummy.pdf",
"contentType": "application/pdf; qs=0.001",
"bytes": 13264,
"statusCode": 200,
"finalUrl": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
}

Failed rows include ok: false, error, errorCode and are not charged. A RUN_SUMMARY record counts saved/failed files and ZIP size.

How much does it cost to download files?

EventFree / BronzeSilverGold+
Actor start (× memory GB)$0.0005$0.0005$0.0005
File downloaded$0.001$0.0008$0.0006

Failed, blocked and oversize downloads are free.

JobApprox. cost
Prefill (2 successful files)≈ $0.002 + $0.0005 start
1,000 files$1.00
10,000 files (Gold)$6.00

Large files also consume Apify data-transfer / storage from your plan quota – keep maxFileBytes tight. Use Max cost per run to cap PPE spend.

Integrations (API, AI agents, Make, Zapier)

curl -X POST "https://api.apify.com/v2/acts/chris_elder~bulk-file-downloader/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://httpbin.org/image/png"],"createZip":true}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("chris_elder/bulk-file-downloader").call(run_input={
"urls": ["https://httpbin.org/image/png", "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"createZip": True,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["ok"], row["url"], row.get("key"))
zip_url = f"https://api.apify.com/v2/key-value-stores/{run['defaultKeyValueStoreId']}/records/OUTPUT.zip"

MCP (AI agents): https://mcp.apify.com/?tools=chris_elder/bulk-file-downloader

Make / Zapier / n8n: use the Apify Run Actor module with chris_elder/bulk-file-downloader, map your URL list into urls (or pass the previous Actor run’s defaultDatasetId as datasetId), then read the dataset rows or fetch OUTPUT.zip from the run’s Key-Value store.

Limits and good to know

  • Only http/https URLs; private/localhost/cloud-metadata hosts are refused.
  • Default size cap 10 MB per file (max 50 MB). Raise memory if you ZIP many large files.
  • You must have the right to download and use each file.
  • ZIP uses store-only (no compression) for speed and simplicity.

This Actor downloads URLs you supply. It does not bypass paywalls, logins or bot protection. You are responsible for having rights to the files and for complying with site terms and copyright law. See Apify’s legal overview.

FAQ

Can it download images and PDFs? Yes – any file type, within the size cap.

Where is the ZIP? In the run’s Key-Value store under OUTPUT.zip (or your zipKey).

Why was a file free? HTTP errors, timeouts, SSRF blocks, oversize files and dataset rows with no URL are not charged.

Does it scrape websites for images? No – pass explicit file URLs only. To get image URLs from pages first, use a scraper, then pass its run’s dataset ID as datasetId with the URL column as urlField.

Can I download files from an Apify dataset? Yes – set datasetId and urlField. Rows without a URL are skipped free.

How do I download files from a Google Sheet or CSV? Copy the URL column into urls (one URL per item), or send it as a JSON array through the API, Make or n8n.

How do I download all the files in one go? Leave createZip on and download OUTPUT.zip from the run’s storage.

Support, reliability and feature requests

  • Failed downloads are free.
  • Every release is tested on real public URLs; the one-click example works.
  • Issues answered within 2 business days via the Actor Issues tab.
  • Breaking input or price changes are announced in this README first.

Built by Chris Elder with AI-assisted development; every release is reviewed and tested.

Need the data done for you?

If you'd rather not set up runs yourself, the UK company behind these tools (GPT Shop Ltd) offers a fixed-price done-for-you scrape. Tell us the website and the fields you need, and you get a clean CSV or Google Sheet within 48 hours of the confirmed brief, up to 5,000 rows, for £149 or $179. If we can't get the data, you're refunded in full. See the done-for-you scraper service

More tools by Chris Elder

Dataset Transformer · Sitemap URL Extractor · PDF to Markdown · Image to Text OCR · HTTP Request Sender · Multi-ATS Jobs API · all tools