Download Images from URLs: Bulk Image & File Downloader
Pricing
from $1.20 / 1,000 files
Download Images from URLs: Bulk Image & File Downloader
Download images from URLs in bulk: an image downloader API for lists of direct image or file links and for images found on web pages. Dedupe by content hash, convert to JPG, PNG or WebP, resize, filter by size and get public links plus one ZIP.
Pricing
from $1.20 / 1,000 files
Rating
0.0
(0)
Developer
Data Done Right
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
a day ago
Last modified
Categories
Share
Use this tool to download images from URLs in bulk. Paste a list of direct image links (or web pages to pull the images from) and get every file saved to a key-value store with a public link, its real type, its size in pixels and a SHA-256 hash. It is a bulk image downloader and a general image downloader API: it removes duplicates by content, can convert to JPG, PNG or WebP, resize, filter out icons and tracking pixels, and pack everything into one ZIP. No browser, no login and no API key.
Rights and fair use. You are responsible for having the right to download and reuse the images you fetch. Do not use this Actor on sites whose terms forbid automated downloads. It does not log in, does not send a forged Referer and does not work around hotlink protection: if a host answers 401, 403 or 429, you get a
failedrow with that reason. ForpageUrlsit reads and obeys the site'srobots.txt.
What can this bulk image downloader do
- Download images from a list of URLs. One dataset row per URL with
status:downloaded,duplicate,skippedorfailed, and a reason when it is notdownloaded. - Download all images from a web page. Add page links in
pageUrls: the Actor reads<img src>andsrcset(the largest size of each),<picture>sources, lazydata-srcimages,og:imageandtwitter:imagemeta tags and<link rel="image_src">, resolves relative links (including<base href>) and downloads those images. - Know what you really got. The type is detected from the file's bytes, not the file name or the server header. A
.jpglink that serves a PNG is saved as.pngand the row says so; a link that serves a web page is reported as failed instead of being saved as an "image". - Filter. Minimum width and height (drop 1x1 tracking pixels and icons), the image types you want, a size limit per file.
- Remove duplicates. Identical files (same SHA-256) are delivered once; later copies get status
duplicatewith a link to the first copy, and are free. - Convert and resize. Convert to JPG, PNG or WebP with Pillow and limit the width, keeping the aspect ratio (never upscaled). JPG gets a white background behind transparency, EXIF rotation is applied, metadata is dropped.
- One ZIP. Optionally also get all delivered files in one
images.zipwith amanifest.csv, with a public link. - Any file type (opt-in). Turn on
anyFileto download PDFs, ZIPs, CSVs and other files too. Web pages (HTML) are never saved.
How to download images from URLs
- Paste direct image links in Image or file URLs (
urls), one per line, and/or page links inpageUrls. - Optionally set the image types, a minimum size,
convertTo,maxWidthandzip. - Run it. Each file is saved in the run's key-value store under
<sha256>.<ext>, and the dataset lists its public link (fileUrl).
Input example
{"urls": ["https://upload.wikimedia.org/wikipedia/commons/a/a9/Example.jpg","https://upload.wikimedia.org/wikipedia/commons/3/35/Information_icon.svg","https://picsum.photos/id/237/200/300.jpg","https://picsum.photos/id/10/200/300.webp"],"convertTo": "original","zip": true}
More examples: "pageUrls": ["https://example.com/gallery"], "minWidth": 200 (all larger images of a page), "convertTo": "webp", "maxWidth": 1600 (smaller files for your site), "anyFile": true (PDFs and other files).
Output
One dataset row per URL:
{"url": "https://picsum.photos/id/237/200/300.jpg","finalUrl": "https://fastly.picsum.photos/id/237/200/300.jpg?hmac=...","status": "downloaded","reason": null,"contentType": "image/jpeg","sizeBytes": 11615,"width": 200,"height": 300,"sha256": "e5f9164e2ca3cd72c533145fcc1c3adc1b3af8072f0677955ec5217d1f3bceeb","fileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/e5f9164e...ceeb.jpg","sourcePage": null,"key": "e5f9164e2ca3cd72c533145fcc1c3adc1b3af8072f0677955ec5217d1f3bceeb.jpg","index": 3}
status:downloaded(charged),duplicate(same content as an earlier file or the same URL listed twice),skipped(your rules: type, size, minimum dimensions, spending limit, robots.txt) orfailed(network error, HTTP error, not a valid image, blocked address).reason: why a URL was not downloaded, or a note on a downloaded file (for exampleconverted png to jpg; resized to 800px wide, orURL ends in .jpg but the file is png; saved as .png).sha256,sizeBytes,width,height,contentTypedescribe the delivered file (after any conversion). The key issha256plus the real extension, so it is always safe and never contains parts of the URL.sourcePageis the page an image was found on (pageUrls), empty for URLs you listed yourself.- The
SUMMARYrecord has the counts, the charged units,zipUrland any notes.
Image downloader API
Call this Actor from the Apify API, Python, JavaScript, Make, Zapier or n8n. Example with the Apify Python client:
from apify_client import ApifyClientrun = ApifyClient("<APIFY_TOKEN>").actor("data-done-right/image-downloader").call(run_input={"urls": ["https://example.com/a.jpg", "https://example.com/b.png"],"convertTo": "webp", "maxWidth": 1600, "zip": True})client = ApifyClient("<APIFY_TOKEN>")for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["status"], row["url"], row["fileUrl"])
Files are read back from the run's key-value store (client.key_value_store(run["defaultKeyValueStoreId"])) or by their fileUrl.
Use it in Claude, ChatGPT and Cursor
Connect Apify's MCP server (mcp.apify.com) and your AI assistant can fetch images for you. For example: "download the images from this list of URLs as WebP, skip anything under 300 pixels wide, and give me the ZIP link". The only input you need is a list of image URLs (urls) or a page URL (pageUrls).
Use cases
- Archive or migrate images: turn a spreadsheet of image links into files you own, with hashes to verify them.
- Build datasets: collect images for machine-learning training sets, with duplicates removed and tiny images filtered out.
- Prepare images for a website or store: convert a folder of mixed formats to WebP and limit the width.
- Check links: see which image URLs are dead, are not images, or are too large.
- Product and media catalogs: download the product images listed on your own pages.
How much does it cost
Pay per event, only for files that are delivered:
- $0.0015 per downloaded file (
file). 100 small images cost about $0.15. - $0.0002 per started MB beyond the first MB of each file (
megabyte), so large files cost fairly. A 4.2 MB file costs $0.0023; a file of 1 MB or less costs just the file price. 1 MB is 1,000,000 bytes, measured on the delivered file. - Free: duplicates, skipped and failed URLs, the ZIP, the dataset and the
SUMMARYrecord.
Paid Apify plans get 10% (Silver) to 20% (Gold and up) off. maxFiles caps the number of URLs, maxFileSizeMb caps each file, and if you set a maximum spend per run the Actor stops cleanly when it is reached, keeping the files already delivered (the remaining URLs get a skipped row).
FAQ
How do I download images from a list of URLs?
Put the links in urls and run. Every link gets a row; the files that were delivered have a fileUrl you can open or download. Turn on zip to also get everything in one ZIP.
How do I download all images from a web page?
Put the page link in pageUrls. The Actor fetches the page (respecting its robots.txt), finds the images and downloads them. Images are taken from the HTML as served, so images that a page only creates with JavaScript after loading are not found. Use minWidth to drop icons and maxFiles to limit the count. Images found on a page are fetched like any other image link; robots.txt is applied to the page itself, not to the image files it points to.
Does it respect robots.txt?
For pageUrls, yes: a page that robots.txt disallows for the ImageDownloader agent (or *) is not fetched and gets a skipped row. If robots.txt cannot be read because of a server error, the page is not fetched either. Direct file links you list yourself in urls are not checked against robots.txt, because you chose them; you are responsible for the right to download them.
Can it get images behind a login or bypass hotlink protection?
No. It sends no cookies, credentials or Referer, and it does not pretend to be a browser. Links with a user name or password in the URL are refused. Pages of login-walled social sites (Instagram, Facebook, LinkedIn, X, TikTok) are not supported. A host that refuses the download gives a failed row with the HTTP status.
Which image formats are supported?
JPG, PNG, WebP, GIF, AVIF, SVG, BMP and TIFF. The type is read from the file's bytes. SVG files that contain scripts, event handlers or embedded pages are not saved. With convertTo set, SVG files are kept as SVG (they are vector). Animated GIF or WebP files keep only their first frame when they are converted or resized; without conversion the original animation file is delivered untouched.
How are duplicates found?
By the SHA-256 of the downloaded bytes, and again by the hash of the delivered file after conversion (two different sources that convert to the same output also count). The same URL listed twice is fetched only once.
How big can a file be?
25 MB by default, up to 100 MB with maxFileSizeMb. The limit is checked on the Content-Length header and again while streaming, so an oversized or endless response is cut off early. Images over 100 megapixels are skipped, and conversion is only done for images up to 36 megapixels.
How long are the file links kept?
Files are saved in the run's default key-value store, which expires after your plan's data retention period like other unnamed storages. Set outputStoreName to save them in a named store that stays until you delete it. Anyone who has a fileUrl can open it.
Is it safe to give it any URL?
Links to localhost, private networks, link-local and cloud-metadata addresses are blocked, including names that resolve to them and redirects into them (every redirect hop is checked again; up to 5 are followed). When you use a proxy, the proxy opens the connection, but the same address checks still run before every request.
Is it polite to the servers?
Requests to the same host start at least perHostDelayMs apart (250 ms by default) and at most 3 run at once per host. So a higher concurrency only speeds up lists that are spread across several hosts. The timeoutSecs clock for a file starts when its turn at the host comes, not while it waits in line. Network errors, timeouts and 429/5xx answers are retried up to 3 times with backoff, and Retry-After is honored. 401, 403 and 404 are not retried.
Do I need an API key or login?
No.
Related tools
- All-in-One File Converter: PDF, Office, Images, Audio & Video converts the files you download to other formats.
- Video Frame Extractor: Keyframes, Scenes & Thumbnails for AI turns video files into images.
- PDF to Text & Markdown Converter with Automatic OCR reads the text in the PDFs and images you download.
- Merge Datasets & Dedupe: Combine, Filter, Export CSV & Excel combines the result rows of several runs.