Bulk File & Image Downloader – URLs / Dataset to ZIP
Pricing
from $0.60 / 1,000 file downloadeds
Bulk File & Image Downloader – URLs / Dataset to ZIP
Bulk image and file downloader: paste URLs or point at an Apify dataset field, save each file to Key-Value storage, optional ZIP. Image-only filter, custom Referer/User-Agent for hotlink-protected assets, retries. Failed downloads free. $1 per 1,000 files.
Pricing
from $0.60 / 1,000 file downloadeds
Rating
0.0
(0)
Developer
Chris Elder
Maintained by CommunityActor stats
0
Bookmarked
8
Total users
7
Monthly active users
21 hours ago
Last modified
Categories
Share
Bulk File & Image Downloader – Download URLs to ZIP
Bulk File Downloader is a bulk image downloader and general file downloader: it downloads images, PDFs and other files from a list of URLs (or an Apify dataset) 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, product-image archives, 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(optionalfileNameFieldfor SKU-style names) - 🖼️ Images only –
onlyImageskeeps image responses and skips the rest free (ideal bulk image downloader mode) - 🔗 Hotlink-friendly headers – set
refereranduserAgentfor CDNs that block naked image requests - 🔁 Retries – transient 429/5xx and network errors retried (default 2)
- 🗂️ Key-Value store output – each file saved under a stable key
- 📦 Optional ZIP –
OUTPUT.zipwith 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, non-images (when filtered) and blocked hosts are listed and not charged
Use cases
- Scraper users – point
datasetIdat 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 – bulk download product images from a URL column; turn on
onlyImagesand setrefererto your store URL if the CDN blocks hotlinks
📄 Downloading PDFs to read their text? You can skip the download. Paste the same PDF links into our PDF to Markdown & Text Converter and get clean Markdown and plain text back (scanned pages are OCR'd automatically) for $3 per 1,000 PDFs. Keep this Actor for archiving the original files as a ZIP.
How to use it
- Click Try for free – the prefill downloads a tiny PDF and a PNG (2 files ≈ $0.0025 including the start fee).
- Paste your URL list into
urls. - Leave
createZipon to getOUTPUT.zipin the Key-Value store. - 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: onlyImages, referer, userAgent, maxRetries, fileNameField, 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 itsdefaultDatasetId). The Actor gets read-only access to that one dataset only.urlField– the field holding the URL (defaulturl). 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
urlsanddatasetIdin one run; duplicates are removed. In the Console form the 2 sample URLs are ignored automatically when a dataset is given.
Bulk image downloader mode
{"urls": ["https://httpbin.org/image/png","https://httpbin.org/image/jpeg","https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],"onlyImages": true,"referer": "https://www.example.com/","createZip": true}
With onlyImages: true, the PDF row is recorded as skipped (errorCode: NOT_IMAGE) and not charged. referer / userAgent are sent on every request for hosts that require them.
Filenames from a dataset column
{"datasetId": "YOUR_DATASET_ID","urlField": "imageUrl","fileNameField": "sku","onlyImages": true,"createZip": true}
Example: 2 URLs in → 2 files + a ZIP out
| Input URL | What you get |
|---|---|
https://www.w3.org/.../dummy.pdf | Key-Value record file-0000-3eba3cf786-dummy.pdf (13,264 bytes, application/pdf) |
https://httpbin.org/image/png | Key-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?
| Event | Free / Bronze | Silver | Gold+ |
|---|---|---|---|
| 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.
| Job | Approx. 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 ApifyClientclient = 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.
Is it legal?
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. For a bulk image downloader workflow set onlyImages: true so non-images are skipped free.
My product images return 403. Set referer to the store page that normally embeds them (and optionally a browser userAgent). This Actor does not bypass logins or paywalls.
Can I name files from a SKU column? Yes – with datasetId, set fileNameField to that column.
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, onlyImages non-matches 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
More use cases (FAQ)
- How do I download all images from a list of URLs at once? Paste the URLs, or point the Actor at a dataset from another scraper. Every file goes to a key-value store with a public download link.
- Can I bulk download PDFs for AI/RAG pipelines? Yes. Chain it with PDF to Markdown.
- Does it work with Make, Zapier or n8n? Yes. Trigger it through the Apify API and read the output dataset.