Bulk Image Optimizer: WebP, AVIF Converter & Compressor avatar

Bulk Image Optimizer: WebP, AVIF Converter & Compressor

Pricing

from $1.70 / 1,000 image optimizeds

Go to Apify Store
Bulk Image Optimizer: WebP, AVIF Converter & Compressor

Bulk Image Optimizer: WebP, AVIF Converter & Compressor

Compress, resize and convert images in bulk from URLs to WebP, AVIF, JPEG or PNG. Get download links, sizes before/after, % saved, dimensions. No API key, no login. MCP-ready for Claude, Cursor, ChatGPT. Pay per result, no monthly rental. Errors are free. $2 per 1,000 images.

Pricing

from $1.70 / 1,000 image optimizeds

Rating

0.0

(0)

Developer

ABM

ABM

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Bulk Image Optimizer: WebP, AVIF Converter & Image Compressor API

$2 per 1,000 images. Failed, broken and duplicate URLs are free. No subscription, no API key.

Give it a list of image URLs, get back optimized files: compressed, resized and converted to WebP, AVIF, JPEG or PNG, each with a download link, the original and new size in bytes, the % saved and the final dimensions. Built for e-commerce catalogs, agencies and developers who need lighter images for Core Web Vitals, without installing ImageMagick, sharp or a CLI.

  • 🖼️ Formats in: JPEG, PNG, WebP, AVIF, GIF (first frame), TIFF, BMP, HEIC/HEIF (iPhone photos)
  • 📦 Formats out: WebP, AVIF, JPEG (progressive, optimized), PNG (lossless or palette-reduced), or "keep original format"
  • 📐 Resize: max width / max height (never upscales), exact-size crop (cover) or letterbox (contain)
  • 🎯 Smart defaults: EXIF orientation applied, ICC color profile kept, EXIF/GPS stripped (optional), transparency flattened on the color you choose for JPEG
  • 🔁 onlyNew mode for scheduled runs: only new catalog images are processed and billed
  • 🤖 MCP-ready for Claude, Cursor, ChatGPT and other AI agents

How much does it cost?

Pay per result: $0.002 per optimized image (event image-processed). No monthly rental.

VolumePrice
100 images$0.20
1,000 images$2.00
10,000 images$20.00

Free: invalid URLs, 404s, timeouts, non-image files, duplicates in the same run, and images skipped by onlyNew.

Very large images count as more than one image, so normal catalog photos stay cheap: one image = up to 2 MB downloaded, up to 4 megapixels in output (≈ 2000 × 2000 px) and up to 24 megapixels in the source. A 6 MB DSLR photo counts as 3. A typical product photo (300 KB–2 MB, resized to 1200–2000 px) always counts as 1. The billedUnits field of each result tells you exactly what was charged.

Your spending limit is respected: when it is reached, the run stops cleanly and nothing more is delivered or billed.

Input

{
"imageUrls": [
"https://picsum.photos/id/433/2400/1600.jpg",
"https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png"
],
"outputFormat": "webp",
"quality": 80,
"maxWidth": 1200
}
FieldTypeDefaultDescription
imageUrlsarray of strings—Public image URLs (required)
outputFormatwebp · avif · jpeg · png · originalwebpOutput format
quality1–10080WebP / AVIF / JPEG quality
maxWidth, maxHeightintegernoneMax size in px (proportions kept, never upscaled)
fitinside · cover · containinsidecover = crop to exact size, contain = pad to exact size (needs both max width and height)
losslessbooleanfalseLossless WebP / AVIF
pngColors2–256nonePalette-reduce PNG output (pngquant-like, 50–80% smaller)
backgroundColorhex#ffffffFill for transparency in JPEG and for contain padding
keepMetadatabooleanfalseKeep EXIF (camera, date, GPS)
onlyNewbooleanfalseSkip URLs already optimized with the same settings in earlier runs
storeNamestringrun storeNamed key-value store to keep the files indefinitely
maxConcurrency1–164Parallel downloads
maxInputSizeMb1–5025Skip heavier source files

Output

One dataset item per image. The file itself is in the key-value store; fileUrl is a direct download link.

{
"sourceUrl": "https://picsum.photos/id/433/2400/1600.jpg",
"status": "ok",
"fileUrl": "https://api.apify.com/v2/key-value-stores/aBcD1234/records/1600-3f9a1c2b7d.webp",
"fileKey": "1600-3f9a1c2b7d.webp",
"format": "webp",
"contentType": "image/webp",
"originalFormat": "jpeg",
"originalBytes": 412876,
"outputBytes": 71230,
"savedBytes": 341646,
"savedPercent": 82.7,
"originalWidth": 2400,
"originalHeight": 1600,
"width": 1200,
"height": 800,
"quality": 80,
"hasAlpha": false,
"wasAnimated": false,
"billedUnits": 1,
"processedAt": "2026-10-20T08:15:02.512Z",
"errorMessage": null
}

Failed images are listed too (free), so you can fix your catalog:

{
"sourceUrl": "https://example.com/images/missing.jpg",
"status": "error",
"errorMessage": "HTTP 404 when downloading the image",
"processedAt": "2026-10-20T08:15:03.020Z"
}

Export the dataset as JSON, CSV, Excel or XML from the run page or the API.

Use cases

1. Shopify / WooCommerce merchant: convert the product catalog to WebP every night

An e-commerce manager with 4,000 product photos (JPEG, 1.5 MB on average) wants to pass Core Web Vitals. A nightly schedule with onlyNew converts only the photos added that day (≈ 30 per day ⇒ about $0.06 per night; the first full run costs $8).

{
"imageUrls": ["https://cdn.example-shop.com/products/sku-1042-front.jpg", "https://cdn.example-shop.com/products/sku-1042-back.jpg"],
"outputFormat": "webp",
"quality": 80,
"maxWidth": 1600,
"onlyNew": true,
"storeName": "shop-webp-catalog"
}
[{ "sourceUrl": "https://cdn.example-shop.com/products/sku-1042-front.jpg", "fileUrl": "https://api.apify.com/v2/key-value-stores/…/records/sku-1042-front-a81c03f2e4.webp", "originalBytes": 1583201, "outputBytes": 148920, "savedPercent": 90.6 }]

Next: a Make scenario reads the dataset and updates the product image URLs (or uploads the files to the CDN). Page weight drops by ~85%.

2. Web agency: AVIF hero images and square thumbnails for a site redesign

A front-end developer receives 250 images from the client's old site. One run makes 1:1 thumbnails for the listing grid, another makes AVIF hero images.

{
"imageUrls": ["https://old-site.example.com/uploads/team-photo.png", "https://old-site.example.com/uploads/office.jpg"],
"outputFormat": "avif",
"quality": 60,
"maxWidth": 400,
"maxHeight": 400,
"fit": "cover"
}
[{ "fileKey": "office-07be4c1d9a.avif", "width": 400, "height": 400, "originalBytes": 2380114, "outputBytes": 18342, "savedPercent": 99.2 }]

Cost: 500 images ⇒ about $1. The developer downloads the files with the API and commits them to the repo.

3. Marketplace / feed manager: normalize supplier images before import

A feed manager imports 10,000 supplier images in mixed formats (PNG with transparency, HEIC, TIFF). Marketplaces want JPEG on a white background, max 2000 px, no metadata.

{
"imageUrls": ["https://supplier.example.com/media/ART-5531.png", "https://supplier.example.com/media/ART-5532.heic"],
"outputFormat": "jpeg",
"quality": 85,
"maxWidth": 2000,
"maxHeight": 2000,
"backgroundColor": "#ffffff"
}
[{ "sourceUrl": "https://supplier.example.com/media/ART-5531.png", "format": "jpeg", "hasAlpha": false, "width": 2000, "height": 2000, "savedPercent": 71.4 }]

Next: the CSV export (sourceUrl → fileUrl) is merged into the product feed in Google Sheets; rows with status: "error" go back to the supplier. Cost: about $20 for 10,000 images.

API examples

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<USERNAME>/bulk-image-optimizer").call(run_input={
"imageUrls": ["https://picsum.photos/id/433/2400/1600.jpg"],
"outputFormat": "webp",
"quality": 80,
"maxWidth": 1200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["status"], item.get("fileUrl"), item.get("savedPercent"))

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('<USERNAME>/bulk-image-optimizer').call({
imageUrls: ['https://picsum.photos/id/433/2400/1600.jpg'],
outputFormat: 'avif',
quality: 60,
maxWidth: 1200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.fileUrl, i.savedPercent]));

Integrations (Make, Zapier, n8n, Google Sheets)

  • n8n / Make: "Run Actor" module with the input above → "Get dataset items" → for each item, HTTP download fileUrl and upload it to S3, Cloudinary, Shopify or WordPress.
  • Zapier: new row in a Google Sheet (column = image URL) → run the Actor → write fileUrl and savedPercent back to the row.
  • Google Sheets: export the dataset as CSV, or use the Apify Google Sheets integration to push results automatically after each run.
  • Schedules: Apify Schedules + onlyNew: true = a hands-off nightly image pipeline.
  • Webhooks: get notified when the run finishes and pull the dataset.

Use with AI agents (MCP)

This Actor works as a tool through the Apify MCP server (https://mcp.apify.com) in Claude, Cursor, ChatGPT, VS Code and any MCP client. Ask for example: "Convert these 20 product photos to WebP, max 1200 px wide, and give me the download links and the total size saved." The agent passes imageUrls, outputFormat, quality and maxWidth, then reads fileUrl, savedPercent and errorMessage from the dataset. Output is flat, typed JSON, easy for an LLM to summarize.

FAQ

Which format should I choose? WebP for maximum compatibility (all current browsers) and a good size reduction. AVIF for the smallest files (often 20–40% smaller than WebP), at the cost of slower encoding. JPEG for marketplaces and email. PNG for logos and screenshots that must stay pixel-perfect.

Will my images be upscaled? No. With the default inside mode, images smaller than max width/height keep their size. Only cover and contain produce an exact size.

Can the output be bigger than the input? Yes, occasionally (e.g. an already-optimized JPEG converted to lossless PNG). savedPercent is then negative so you can spot it.

How long are the files kept? Files in the run's default store follow your Apify data retention. Set storeName to keep them in a named store indefinitely.

Do you need my login or API keys for my CDN? No. The Actor only downloads public URLs and never logs in anywhere.

Is the source site affected? Each image is downloaded once with polite concurrency (4 by default) and automatic retries with backoff on 429/5xx.

What about animated GIFs/WebPs? Only the first frame is kept (wasAnimated: true tells you).

Limits

  • Images must be publicly reachable. Hosts that block cloud servers, require a login or sit behind an anti-bot challenge will fail (free, reported in errorMessage). Private/internal network addresses are refused.
  • Max 50 MB per source file (25 MB by default) and 100 megapixels per image.
  • Memory: the default 512 MB run handles typical photos (up to about 30 MP decoded; JPEGs resized with maxWidth/maxHeight are decoded at reduced size, so 24 MP camera JPEGs work too). A larger PNG/WebP/TIFF, or a big JPEG kept at full size, is reported with a clear errorMessage (free) asking you to re-run with 1024 MB or more in Run options → Memory. The rest of the batch is always processed.
  • Animated images are converted to a still image (first frame).
  • SVG and RAW camera formats (CR2, NEF...) are not supported as input.
  • AVIF encoding is CPU-heavy: expect roughly 2–4× longer runs than WebP for the same images.