Bulk File Downloader - URLs to Files and ZIP
Pricing
from $0.70 / 1,000 files
Bulk File Downloader - URLs to Files and ZIP
Download files from a list of URLs, web pages or another Actor's dataset: images, PDFs, video, audio. Fast and resumable, with SHA-256, image size, duplicates removed and optional ZIP. You pay only for files stored.
Pricing
from $0.70 / 1,000 files
Rating
0.0
(0)
Developer
Shivam Prajapati
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
16 hours ago
Last modified
Categories
Security
Limited permissionsShare
Download files in bulk from a list of URLs, from web pages, or from the dataset of another Actor. Images, PDFs, videos, audio and archives are streamed to disk, stored in your key-value store (and packed into ZIP parts on request), and reported in one table with size, content type, SHA-256, image width and height, redirects and tries. Same content is stored once, broken downloads continue where they stopped, and you pay only for files that were stored: failed and skipped addresses are free. No proxy, no login, no browser.
Actively maintained. Last update: 2026-11-07. Every release passes 100+ automated tests, and Apify test-runs it every day.
What can you use it for?
- Turn scraper output into files. Another scraper gave you 5,000 image or PDF links. Give this Actor the dataset id and get the files.
- Back up media. Download all images, videos and documents from a list of pages in one run, with a ZIP at the end.
- Product image libraries. Name every image by a template such as
{host}_{filename}and keep one ZIP per run. - Archive and prove. Every file comes with its SHA-256, size and server headers (
etag,lastModified), ready for audits and deduplication. - Feed AI and data pipelines. Hand the stored file links and image sizes to the next step.
What data do you get?
One row per stored file. Failed addresses are not rows: they are in the FAILED_URLS record, with the reason.
| Field | What it is |
|---|---|
url, finalUrl | The address you gave, and where it led after redirects |
status | downloaded, or duplicate when an earlier file in the run has the same content |
fileName, key, storageUrl | The file's name, its record key and the link to the stored file |
contentType, fileType, extension | Server content type, image, document, video, audio, archive or other, and the extension |
bytes, sha256 | Size and SHA-256 of the content |
width, height | Image size in pixels (PNG, JPEG, GIF, WebP, BMP) |
duplicateOf | For a duplicate: the key of the file with the same content |
httpStatus, lastModified, etag | Server answer and headers |
sourcePage | The page the file was found on (page scans) |
zipPart | The ZIP part the file is in, e.g. files-part-001.zip |
redirects, attempts, downloadMs | Redirects followed, tries needed and time taken |
fetchedAt | When the file was downloaded (UTC) |
Example result
{"url": "https://upload.wikimedia.org/wikipedia/commons/a/a9/Example.jpg","finalUrl": null,"status": "downloaded","fileName": "Example.jpg","key": "6a1f0c3e-Example.jpg","storageUrl": "https://api.apify.com/v2/key-value-stores/xxxx/records/6a1f0c3e-Example.jpg","contentType": "image/jpeg","fileType": "image","extension": "jpg","bytes": 12345,"sha256": "3b1c...","width": 275,"height": 297,"duplicateOf": null,"httpStatus": 200,"sourcePage": null,"zipPart": null,"redirects": 0,"attempts": 1,"downloadMs": 180,"fetchedAt": "2026-11-07T12:00:00Z"}
How to use it
- Paste file links into File URLs, or list pages in Or web pages to scan for files, or give a dataset id.
- Pick the kinds of files you want, a ZIP option and a file name template if you like.
- Set Maximum files and press Start. Files appear in the key-value store as they arrive.
Input options
| Input | What it does |
|---|---|
urls | File links to download: one by one, pasted (one per line) or from a text file. Objects with url and fileName work through the API |
pageUrls | Web pages to scan for images, video, audio, documents and archives (each page is read once) |
datasetId, urlFields | Download every file link in the rows of another Actor's dataset; name the fields or let the Actor find them |
fileTypes | Keep only some kinds of files; others are skipped for free |
sameHostOnly, maxFilesPerPage | Page scans: stay on the page's site, and cap the files taken from each page |
saveFiles, zip, zipPartMb | Store each file, pack ZIP parts (none, single, byHost), and the part size |
fileNameTemplate, uniqueFileNames | The record key: {filename} {name} {ext} {host} {urlhash} {sha} {type} {index}, with a short address code in front |
maxFileSizeMb, maxRetries, timeoutSeconds | Size limit, retries and the wait for the server's next bytes |
maxPerHost, maxConcurrency | Downloads at once from one site and in total |
headers, userAgent, referer | Extra request headers, for files you are allowed to download |
acceptHtml | Save an address that returns a web page as a file instead of a failure |
keyValueStoreName | Save into a named key-value store that does not expire |
onlyNew | Skip addresses that earlier runs of this same input already returned |
maxItems | Stop after this many stored files |
How much does it cost?
You pay per stored file, nothing else. Failed downloads, skipped files, wrong kinds and too-large files are free and do not count toward the maximum. The first Apify plan includes free monthly credit to try it.
| Plan | Price per 1,000 files |
|---|---|
| Free | $1.00 |
| Bronze | $0.90 |
| Silver | $0.80 |
| Gold | $0.70 |
Use it via API, on a schedule, or with your tools
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("pshivam/bulk-file-downloader-scraper").call(run_input={"datasetId": "<DATASET_ID_OF_ANOTHER_RUN>","fileTypes": ["image"],"zip": "single","maxItems": 1000,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["fileName"], row["bytes"], row["width"], row["height"], row["storageUrl"])
Schedule it in the Apify Console (Schedules) and turn on Only new files to download only what earlier runs did not. Connect the result to Google Sheets, Make, Zapier, n8n or your own app with Apify's integrations.
Good to know
- Files are streamed to disk and uploaded in parallel. Memory stays flat, so a 100 MB video and a 5,000-image list run on the same 256 MB.
- Interrupted downloads continue. When a connection drops and the server supports byte ranges, the download resumes from the last byte.
- Same content is stored once. A second file with the same SHA-256 gets a
duplicaterow that points to the first. - Private networks are refused. Addresses that lead to internal or private IP addresses fail with
blocked_address. - Web pages are read once. Page scans do not crawl further and do not run JavaScript. Images that a page loads with JavaScript need a browser scraper first.
- Some links expire. Links from social media and CDNs often stop working after hours. Run the download soon after the scrape.
- Streaming sites are not file links. An address that returns a web page (a YouTube watch page, for example) is a failure
html_instead_of_file, not a saved page. - Files are kept as your run's records. Run records expire after your plan's retention time. Use
keyValueStoreNamefor a store that stays.
FAQ
How do I download many files from a list of URLs?
Paste the links into File URLs (one per line) or load a text file, set Maximum files, and press Start. Each stored file is a record in the key-value store and a row in the results table.
Can it download all images from a web page?
Yes. Put the page in Or web pages to scan for files and pick the image kind. It finds img tags (the sharpest srcset size), picture sources, video posters, icons and og:image links.
Can I download the files of another Actor's results?
Yes. Give the dataset id of the other run. Fields such as imageUrl, images, pdf and video are found on their own, or name them in Dataset fields with the links.
Can I get everything as a ZIP?
Yes. Choose One ZIP (in parts). Parts close at the size you set and appear as files-part-001.zip and so on. Turn off Store each file to get only the ZIP.
What happens to failed downloads?
They are not charged and not counted toward the maximum. The FAILED_URLS record lists each address with the reason (not_found, forbidden, timeout, html_instead_of_file, too_large and more).
Does it work with login-protected files?
It sends the headers you give in Extra request headers, for example an Authorization header or a Cookie, for files you are allowed to download. It does not log in and does not bypass blocks.
Is it legal to download files?
The Actor fetches the addresses you give, like a download manager. You are responsible for having the right to download and keep the files and for following the terms of the sites you download from.
How do I download only new files every day?
Turn on Only new files and schedule the Actor. It remembers what it returned in your key-value store.