# Picpail — Bulk Image Downloader: All Images from URLs to ZIP (`cybermax/bulk-image-downloader`) Actor

Download all images from web pages or image URLs into one ZIP, full-size originals instead of thumbnails: img, srcset, lazy-load, CSS, og:image. Real format and pixel size, duplicate removal, size/format filters, monitor mode. $0.0005 per image; duplicates and skips free.

- **URL**: https://apify.com/cybermax/bulk-image-downloader.md
- **Developed by:** [CyberMax](https://apify.com/cybermax) (community)
- **Categories:** Developer tools, Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Picpail: Bulk Image Downloader — All Images from URLs to ZIP

**Download all images from any web page, or a list of image URLs, into one ZIP.** Picpail finds every picture a
visitor would see or click through to (`<img>`, `srcset`, lazy-load attributes, `<picture>`, CSS backgrounds,
`og:image`, JSON-LD product images, gallery links to originals), swaps thumbnails for the **full-size originals**
on Shopify, WordPress, Wikimedia, Cloudinary, Wix, Squarespace, Contentful and imgix, and downloads each file once.
Every image is checked from its bytes (real format, width and height), duplicates are dropped by SHA-256, and you
get a ZIP with a folder per page plus one data row per image. **$0.50 per 1,000 images**; duplicates, filtered-out
images and failures are free.

Use it for: product photo downloads for a catalogue or marketplace migration, competitor image audits, backing up a
site's media before a redesign, building image datasets, grabbing every photo from a gallery or blog post, and
checking alt text across pages.

### Why Picpail

| | Picpail | Typical image downloader |
|---|---|---|
| Thumbnails → full-size originals | Yes (Shopify, WordPress, Wikimedia, Cloudinary, Wix, Squarespace, Contentful, imgix) | No: you get the 300 px copy the page shows |
| Lazy-loaded images (`data-src`, `data-srcset`, `data-lazy-src` …) | Yes | Often missed |
| Real format, width, height, bytes, SHA-256 per image | Yes, read from the file | Guessed from the HTML, or none |
| Duplicates removed | By URL and by file content | Rarely |
| Filters (min width/height, formats, file size, URL regex, same site) | Yes; filtered images are free and big files are cut short after the header | Few |
| One ZIP, split into parts for big jobs | Yes, streamed to disk (steady memory on any job size) | Varies |
| Monitor mode (only new images since the last run) | Yes | No |
| Price | $0.0005 per image | $0.00089–$0.002 per image, or $0.07 per page URL |

**Benchmark (Apify, 24 Sep 2026, same 3 pages: books.toscrape.com, wordpress.org/news, an Allbirds product page):**

| Actor | Result | Time | Price for this job\* |
|---|---|---|---|
| **Picpail** | 67 images, one 18 MB ZIP + a row per image (format, size, SHA-256, alt) | 4.2 s | **$0.034** |
| getascraper/bulk-image-downloader | 72 files (the same pictures; 5 WordPress photos fetched twice at two sizes), no ZIP | 6.7 s | $0.064 |
| onescales/bulk-image-downloader | one 18 MB ZIP, no per-image data | 36.7 s | $0.21 (free tier, $0.07 per URL) |
| crawlerbros/website-image-scraper | image URLs only (no files), every srcset size listed separately | 3.3–6.4 s per page | $0.20 |

\* Each Actor's published price for the Apify free tier on 24 Sep 2026. With full-size originals switched on
(the default, added after this benchmark), the Allbirds page returns 2000–4000 px product photos instead of 300 px copies.

### Ready-made inputs (first try in one click)

**Every product image on a page, as one ZIP** (the Store's default input; skips icons and tiny images):

```json
{ "urls": ["https://books.toscrape.com/"], "minWidth": 100, "minHeight": 100 }
```

**Only JPEG/PNG/WebP images, as a metadata list (links, sizes, formats) instead of a ZIP:**

```json
{ "urls": ["https://books.toscrape.com/"], "output": "list", "formats": ["jpeg", "png", "webp"], "minWidth": 100 }
```

**Watch a page and download only new images each run** (pair with a daily Schedule):

```json
{ "urls": ["https://books.toscrape.com/"], "monitor": true, "monitorKey": "books-home" }
```

### Example

Input:

```json
{
  "urls": [
    "https://books.toscrape.com/",
    "https://wordpress.org/news/",
    "https://www.allbirds.com/products/mens-tree-runners"
  ],
  "minWidth": 100,
  "minHeight": 100
}
```

One dataset row per image:

```json
{
  "type": "image",
  "pageUrl": "https://wordpress.org/news/",
  "pageTitle": "WordPress News – The latest news about WordPress and the WordPress community",
  "imageUrl": "https://i0.wp.com/wordpress.org/news/files/2024/01/sunita-rai-featured-img.jpg?ssl=1",
  "pageImageUrl": "https://i0.wp.com/wordpress.org/news/files/2024/01/sunita-rai-featured-img.jpg?w=1920&ssl=1",
  "source": "srcset",
  "alt": "Sunita Rai at WordCamp Asia",
  "format": "jpeg",
  "mimeType": "image/jpeg",
  "width": 1920,
  "height": 1200,
  "bytes": 1408399,
  "sha256": "0b8801fead7b4a693ec6c4e13ec5ac1c0ed25b2872428fbf829b5c649c670494",
  "fileName": "002-wordpress.org_news/0002-sunita-rai-featured-img.jpg",
  "zipFile": "images.zip",
  "zipUrl": "https://api.apify.com/v2/key-value-stores/<your-run-store>/records/images.zip?signature=…",
  "via": "direct",
  "downloadedAt": "2026-09-24T11:39:38.560Z"
}
```

The `OUTPUT` record has the ZIP link(s), totals and a line per page (images found, saved, duplicates, filtered,
failed, and why a page failed). More: [`examples/three-pages-one-zip.json`](examples/three-pages-one-zip.json).

### Input

| Field | Default | What it does |
|---|---|---|
| `urls` | required | Page URLs and/or direct image URLs, mixed. Bare domains get `https://`. |
| `output` | `zip` | `zip` (one ZIP, a folder per page), `zipPerPage`, `files` (each image in the key-value store with its own link) or `list` (metadata only). |
| `minWidth`, `minHeight` | 0 | Skip smaller images (measured from the file). 100 skips icons and thumbnails. |
| `formats` | all | e.g. `["jpeg", "png", "webp"]` (real format from the bytes). |
| `minFileSizeKb`, `maxFileSizeMb` | 0, 25 | File size limits. |
| `urlPattern`, `excludeUrlPattern` | – | Regex on the image URL, e.g. `/products/` or `logo\|icon\|sprite`. |
| `sameDomainOnly` | false | Skip images hosted on other sites (ads, trackers); the site's own CDN subdomains count. |
| `upgradeToOriginals` | true | Full-size originals instead of CDN thumbnails (falls back to the page's copy). |
| `srcset` | `largest` | `largest`, `all` sizes, or `none`. |
| `includeLinkedImages`, `includeCssBackgrounds`, `includeMetaImages` | true | Where to look. |
| `includeIcons`, `includeDataUris` | false | Favicons/touch icons; inline `data:` images. |
| `preferOriginalFormat` | true | Ask CDNs for the original JPEG/PNG instead of WebP/AVIF copies. |
| `dedupe`, `skipTrackingPixels` | true | Remove duplicates; skip 1×1 pixels. |
| `fileNaming` | `original` | `0001-original-name.jpg`, `alt`, `index` or `hash`. |
| `zipPartSizeMb` | 1000 | Split big ZIPs into parts. |
| `maxImagesPerPage`, `maxImagesTotal` | 500, 100000 | Safety caps. |
| `proxyConfiguration`, `retryWithProxy` | none, true | Blocked requests (403/429/503) are retried once through Apify Proxy. |
| `monitor`, `monitorKey` | false | Only images that are new since the last monitor run. |

### Output

- **Dataset:** one `image` row per delivered image (fields above). Pages that failed or had no images get a free
  `page-error` row with the reason (`HTTP 403`, "the page may build its content with JavaScript", …).
- **Key-value store:** `images.zip` (or `images-part-2.zip` …, or one ZIP per page, or the individual files), and
  `OUTPUT` with the ZIP links and per-page counts. The dataset's `zipUrl`/`fileUrl` links work without a token.

### Monitor mode: new images only

Tick `monitor` and schedule the run: Picpail remembers every image it has delivered for this URL list (by content
hash) and returns only images that are new since the last monitor run, such as new products in a category, new photos in a
gallery, or a changed homepage banner. Images you already have are skipped and **not charged**, so a daily check of a
quiet page costs nothing. Use `monitorKey` to keep the history when you edit the URL list.

### Pricing

- **$0.0005 per image delivered** (event `image-downloaded`): downloaded, verified as a real image, measured and
  saved. 1,000 images = $0.50.
- **Very large files only:** $0.0001 per started MB above 2 MB of one file (event `large-image-megabyte`), so a
  5.5 MB photo costs $0.0009. Typical web images are well under 2 MB. Lower `maxFileSizeMb` or switch off
  `upgradeToOriginals` to avoid it.
- **Free:** duplicates, images skipped by your filters, links that turn out to be HTML pages, failed downloads,
  failed pages, and in monitor mode images you already received.

Set a maximum charge per run in Apify and Picpail stops cleanly when it's reached.

### Run it on a schedule

Apify Console → **Schedules** → **Create new** → cron `0 7 * * *` (daily) → **Add Actor** → Picpail with your pages
and `"monitor": true`. Through the API:

```json
POST https://api.apify.com/v2/schedules?token=YOUR_TOKEN
{
  "name": "picpail-new-product-photos",
  "cronExpression": "0 7 * * *",
  "timezone": "America/New_York",
  "isEnabled": true,
  "actions": [{
    "type": "RUN_ACTOR",
    "actorId": "cybermax/bulk-image-downloader",
    "runInput": {
      "body": "{\"urls\":[\"https://www.example-shop.com/collections/new\"],\"minWidth\":400,\"monitor\":true,\"monitorKey\":\"new-arrivals\"}",
      "contentType": "application/json"
    }
  }]
}
```

Add an email, Slack or webhook notification on "Run succeeded" under the Actor's **Integrations** tab.

### Integrations

**API (synchronous):** `POST https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/run-sync-get-dataset-items?token=YOUR_TOKEN`
with the input JSON returns the image rows (each with `zipUrl` or `fileUrl`). Use `"output": "files"` when each
image needs its own link (e.g. to import into a CMS or a Google Sheet with `=IMAGE()`).

**Make / Zapier:** Apify app → "Run an Actor" (`cybermax/bulk-image-downloader`, run synchronously) → "Get dataset
items" → map `fileUrl`, `width`, `height`, `alt` into Airtable, a CMS or cloud storage.

**n8n:** Apify node ("Run an Actor and get dataset"), or HTTP Request:

```
POST https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/run-sync-get-dataset-items?token=YOUR_TOKEN
{"urls": ["https://books.toscrape.com/"], "output": "files", "minWidth": 100}
```

**Google Sheets:**

```
=IMPORTDATA("https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/runs/last/dataset/items?format=csv&fields=pageUrl,imageUrl,width,height,alt,fileUrl&token=YOUR_TOKEN")
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("cybermax/bulk-image-downloader").call(run_input={"urls": ["https://books.toscrape.com/"], "minWidth": 100})
zip_url = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")["value"]["zips"][0]["url"]
print(zip_url)
```

**JavaScript** (`npm i apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('cybermax/bulk-image-downloader').call({ urls: ['https://books.toscrape.com/'], output: 'files' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**AI agents (MCP):** Picpail is a tool on Apify's MCP server, `https://mcp.apify.com/?tools=cybermax/bulk-image-downloader`
(Authorization: `Bearer YOUR_TOKEN`). Claude Desktop / Cursor config:

```json
{ "mcpServers": { "picpail": { "url": "https://mcp.apify.com/?tools=cybermax/bulk-image-downloader",
  "headers": { "Authorization": "Bearer YOUR_TOKEN" } } } }
```

Typical agent prompts: "Download every product photo from these 20 pages as a ZIP", "Which images on our blog have
no alt text?", "Get the full-size images from this Shopify collection, at least 1000 px wide".

### When NOT to use it

- **Pages that build their content with JavaScript** (infinite-scroll feeds, single-page apps). Picpail reads the
  HTML the server sends; such pages come back with few images and a `page-error` row saying so. Use a browser-based
  scraper for those.
- **Sites behind strong bot walls** (Cloudflare challenge, DataDome), e.g. Etsy and Unsplash search pages returned
  403/401 in our tests, even through Apify's datacenter proxy. Try `proxyConfiguration` with residential proxies
  (billed by Apify to your account).
- **Pages behind a login**, and whole-site crawls: Picpail downloads the pages you list; it doesn't follow links
  to other pages.
- **Images you have no right to reuse.** Downloading is not a licence: product photos, stock photos and artwork
  belong to their owners. Use the files for analysis, backups of your own sites, or with permission.
- **Permanent hosting.** ZIPs and files stay in the run's storage for your Apify plan's retention period (7 days on
  the free plan). Copy them somewhere permanent.

### FAQ

**Why is my ZIP bigger than the page?** Full-size originals are much larger than the thumbnails a page shows (a
Shopify product photo is often 2000–4000 px). Switch off `upgradeToOriginals` to get the page's own copies.

**Why is a `.jpg` link a WebP file?** It won't be by default: `preferOriginalFormat` asks CDNs for the original
format, and each file's extension always matches its real format (`format` field).

**How big can a job be?** Images are written to disk one by one and ZIPs are split into parts, so memory stays
flat (a 295 MB, 155-image test run peaked under 600 MB). For very large jobs raise the run's memory (disk grows with it) or use `zipPerPage`.

### Also from CyberMax

- [Printwren](https://huggingface.co/spaces/CyberMax-tools/docs-pages-as-pdfs?soon=html-to-pdf): save the same pages as PDFs.
- [SnapScout](https://apify.com/cybermax/website-screenshot): a screenshot and the text of each page.
- [Logolark](https://huggingface.co/spaces/CyberMax-tools/saas-logos-brand-colors?soon=logo-finder): the company logo and icon for each domain.
- [Inkpluck](https://apify.com/cybermax/article-extract): the article text of blog and news pages.

All tools: [Boardroom Buys](https://apify.com/cybermax/sec-insider-tracker) · [DomainDNA](https://apify.com/cybermax/domain-intel) · [HireHeat](https://apify.com/cybermax/hiring-signals) · [Swellmeter](https://apify.com/cybermax/google-trends) · [Hollerdex](https://apify.com/cybermax/website-contacts) · [Gripeline](https://apify.com/cybermax/app-reviews) · [Keyfern](https://apify.com/cybermax/keyword-ideas)

### Changelog

- 2026-09-24: First release: ZIP/files/list output, full-size originals for 9 CDN families, lazy-load and CSS
  images, real format/size per file, content dedupe, filters, monitor mode.

© 2026 CyberMax. All rights reserved.

# Actor input Schema

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

Web pages to take every image from (product pages, galleries, blog posts, listings) and/or direct image URLs (…/photo.jpg). Mix freely; bare domains get https://. Each image is downloaded, checked to be a real image and measured.

## `output` (type: `string`):

How to get the images. ZIPs are split into parts at 'ZIP part size'. Every mode also returns one dataset row per image (URL, format, width, height, bytes, SHA-256, alt text, where it was found).

## `minWidth` (type: `integer`):

Skip images narrower than this (measured from the file, not the HTML). 100 skips icons and thumbnails. Skipped images are free.

## `minHeight` (type: `integer`):

Skip images shorter than this.

## `formats` (type: `array`):

Keep only these real formats (detected from the file bytes). Empty = all formats.

## `minFileSizeKb` (type: `integer`):

Skip files smaller than this.

## `maxFileSizeMb` (type: `integer`):

Larger files are skipped (not downloaded).

## `urlPattern` (type: `string`):

Optional regular expression, case-insensitive, e.g. /products/|cdn.shopify.com

## `excludeUrlPattern` (type: `string`):

Optional, e.g. logo|icon|sprite|avatar

## `sameDomainOnly` (type: `boolean`):

Skip images hosted on other domains (ads, trackers, embeds). The site's own CDN subdomains (cdn.example.com) count as the same site.

## `dedupe` (type: `boolean`):

Download each image URL once and drop byte-identical files (SHA-256) across all pages. Duplicates are free.

## `skipTrackingPixels` (type: `boolean`):

Skip 1×1 and 2×2 images.

## `upgradeToOriginals` (type: `boolean`):

Pages usually show resized copies. For Shopify, WordPress (media library + Jetpack), Wikimedia, Cloudinary, Wix, Squarespace, Contentful and imgix URLs, download the full-size original instead (falls back to the page's copy if the original can't be fetched). The row keeps both URLs.

## `srcset` (type: `string`):

Pages often offer several sizes of the same picture. 'Largest' gets the best quality once.

## `includeLinkedImages` (type: `boolean`):

Gallery thumbnails often link to the full-size original. Links that turn out to be HTML pages are skipped for free.

## `includeCssBackgrounds` (type: `boolean`):

Inline style and <style> backgrounds (hero banners, sliders). External CSS files are not fetched.

## `includeMetaImages` (type: `boolean`):

og:image, twitter:image, JSON-LD product/article images and video posters.

## `includeIcons` (type: `boolean`):

Include <link rel=icon> and apple-touch-icon files.

## `includeDataUris` (type: `boolean`):

Include images embedded in the HTML as data: URIs (placeholders are always skipped).

## `preferOriginalFormat` (type: `boolean`):

Ask servers for the original JPEG/PNG/GIF instead of the WebP/AVIF copies many CDNs create on the fly. Turn off to get the (usually smaller) modern formats a browser would get.

## `fileNaming` (type: `string`):

Names inside the ZIP / key-value store. Extensions always match the real format.

## `zipPartSizeMb` (type: `integer`):

Big jobs are split into images.zip, images-part-2.zip, …

## `maxImagesPerPage` (type: `integer`):

Safety cap per input URL.

## `maxImagesTotal` (type: `integer`):

Stop after this many delivered images (you can also set a maximum charge per run in Apify).

## `pageConcurrency` (type: `integer`):

How many input URLs are processed at the same time.

## `imageConcurrency` (type: `integer`):

How many images of one page download at the same time. Lower it for small sites.

## `timeoutSecs` (type: `integer`):

Per page or image download.

## `proxyConfiguration` (type: `object`):

Optional. By default requests go direct and blocked ones (403/429/503) are retried once through Apify Proxy. Use residential proxies for strict sites.

## `retryWithProxy` (type: `boolean`):

Only used when no proxy is set above.

## `monitor` (type: `boolean`):

For scheduled runs. Remembers every image delivered for this list of URLs (by content hash) and returns only images that are new since the last monitor run: new products, new gallery photos, a changed banner. Images you already got are skipped and not charged. The first run returns everything.

## `monitorKey` (type: `string`):

Optional name for the monitor memory, so you can change the URL list and keep history. Default: derived from the URL list.

## Actor input object example

```json
{
  "urls": [
    "https://books.toscrape.com/",
    "https://www.gstatic.com/webp/gallery/1.webp"
  ],
  "output": "zip",
  "minWidth": 100,
  "minHeight": 100,
  "minFileSizeKb": 0,
  "maxFileSizeMb": 25,
  "sameDomainOnly": false,
  "dedupe": true,
  "skipTrackingPixels": true,
  "upgradeToOriginals": true,
  "srcset": "largest",
  "includeLinkedImages": true,
  "includeCssBackgrounds": true,
  "includeMetaImages": true,
  "includeIcons": false,
  "includeDataUris": false,
  "preferOriginalFormat": true,
  "fileNaming": "original",
  "zipPartSizeMb": 1000,
  "maxImagesPerPage": 500,
  "maxImagesTotal": 100000,
  "pageConcurrency": 4,
  "imageConcurrency": 12,
  "timeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "retryWithProxy": true,
  "monitor": false
}
```

# Actor output Schema

## `zip` (type: `string`):

No description

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

No description

## `summary` (type: `string`):

No description

## `files` (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://books.toscrape.com/",
        "https://www.gstatic.com/webp/gallery/1.webp"
    ],
    "minWidth": 100,
    "minHeight": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cybermax/bulk-image-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://books.toscrape.com/",
        "https://www.gstatic.com/webp/gallery/1.webp",
    ],
    "minWidth": 100,
    "minHeight": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("cybermax/bulk-image-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://books.toscrape.com/",
    "https://www.gstatic.com/webp/gallery/1.webp"
  ],
  "minWidth": 100,
  "minHeight": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call cybermax/bulk-image-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cybermax/bulk-image-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/CtVVylJBcCx0IRiGS/builds/sa9cxK1NgAMMp8KXI/openapi.json
