# Image Resizer API (`parsebird/image-resizer-api`) Actor

Resize, crop, pad, and convert images by URL, base64, or key-value-store key. E-commerce, social, website, and WhatsApp presets. Batch up to 100 images per run.

- **URL**: https://apify.com/parsebird/image-resizer-api.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.39 / 1,000 image processeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### Image Resizer API

Image Resizer API resizes, crops, pads, and converts images by URL, base64 data, or an Apify key-value-store key — with cover/contain/fill/inside/outside fit modes and ready-made presets for e-commerce, social, website, and WhatsApp layouts.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Batch-process up to 100 images per run with precise fit and padding control, solid/blur/edge-extend backgrounds, an optional max-file-size target, and WebP, JPEG, PNG, AVIF, GIF, or TIFF output.
</td>
</tr></table>

##### Copy to your AI assistant

```
Use the Apify actor "parsebird/image-resizer-api" via the ApifyClient to resize and convert images. Example: client.actor("parsebird/image-resizer-api").call(run_input={"images": [{"url": "https://example.com/photo.jpg", "id": "photo-1"}], "targetPreset": "ecommerce_square", "outputFormat": "webp", "quality": 80}). Inputs: images (array, 1-100 objects, each needs exactly one of url/base64/keyValueStoreKey, plus optional id/filename), combineImages (boolean, combine 2-3 sources into one output image), targetPreset (string: custom, ecommerce_square, website_thumbnail, social_square, whatsapp_carousel, whatsapp_catalog_thumbnail, or whatsapp_template_header — sets width/height/fit for you), width/height (integers 1-10000, used when targetPreset is custom), fit (cover/contain/fill/inside/outside), position (center/top/bottom/left/right/top-left/top-right/bottom-left/bottom-right), paddingMode (solid/blur/edge_extend), backgroundColor (hex), outputFormat (webp/jpeg/png/avif/gif/tiff/original), quality (1-100), maxFileSizeMb (0.1-50, optional), preserveMetadata (boolean). Output: one dataset row per generated image with id, source, original (width/height/format/contentType/sizeBytes), output (url/width/height/format/contentType/sizeBytes), metadataPreserved, and fileSizeLimitMb. Full API spec: https://apify.com/parsebird/image-resizer-api/api. Get an API token at https://console.apify.com/settings/integrations.
```

### What does Image Resizer API do?

Image Resizer API is a batch image-processing tool: send it up to 100 images — by public URL, base64-encoded data, or a key already uploaded to the run's key-value store — and get back resized, padded, and format-converted files, each with a direct downloadable URL.

- 🖼️ Accepts images by **URL**, **base64**, or **Apify key-value-store key** in the same batch
- 📐 Five fit modes matching standard image-library semantics: `cover`, `contain`, `fill`, `inside`, `outside`
- 🎯 9-point position anchoring for cropping and padding placement
- 🎨 Three padding modes: solid color, blurred zoomed background, or edge-pixel extension
- 📱 Built-in presets for e-commerce, website, social, and WhatsApp Business layouts (see table below)
- 🔄 Converts to WebP, JPEG, PNG, AVIF, GIF, or TIFF, or keeps the original format
- 📉 Optional max file size target — automatically re-encodes JPEG/WebP/AVIF at a lower quality until it fits
- 🧩 Combine 2 or 3 source images into a single side-by-side output image
- 🔒 Strips EXIF/metadata by default; toggle `preserveMetadata` to keep it
- ⚙️ Runs on Apify's infrastructure with scheduling, API access, and integrations

#### Preset dimensions

| Preset | Size | Fit | Source |
|--------|------|-----|--------|
| `ecommerce_square` | 2048×2048 | contain | Shopify's documented recommended square product image size |
| `website_thumbnail` | 400×400 | cover | Common general-purpose web thumbnail size |
| `social_square` | 1080×1080 | cover | Instagram/Facebook standard square feed post size |
| `whatsapp_carousel` | 1125×600 | cover | WhatsApp Business Platform's mandatory 1.91:1 carousel card ratio |
| `whatsapp_catalog_thumbnail` | 1080×1080 | cover | Meta's WhatsApp Business catalog product image guidance |
| `whatsapp_template_header` | 1125×600 | cover | WhatsApp Business Platform template header image guidance (2MB limit applied automatically) |

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| images | array | **Yes** | — | 1 to 100 image objects. Each needs exactly one of `url`, `base64`, or `keyValueStoreKey`, plus optional `id` and `filename`. |
| combineImages | boolean | No | false | Combine 2 or 3 sources into one output image. |
| targetPreset | string | No | "custom" | `custom`, `ecommerce_square`, `website_thumbnail`, `social_square`, `whatsapp_carousel`, `whatsapp_catalog_thumbnail`, or `whatsapp_template_header`. |
| width | integer | No | 800 | Output width in pixels, 1-10000. Used when `targetPreset` is `custom`. |
| height | integer | No | 600 | Output height in pixels, 1-10000. Used when `targetPreset` is `custom`. |
| fit | string | No | "cover" | `cover`, `contain`, `fill`, `inside`, or `outside`. |
| position | string | No | "center" | `center`, `top`, `bottom`, `left`, `right`, `top-left`, `top-right`, `bottom-left`, or `bottom-right`. |
| paddingMode | string | No | "solid" | `solid`, `blur`, or `edge_extend`. |
| backgroundColor | string | No | "#FFFFFF" | Hex color for solid padding and for flattening transparent areas. |
| outputFormat | string | No | "webp" | `webp`, `jpeg`, `png`, `avif`, `gif`, `tiff`, or `original`. |
| quality | integer | No | 80 | 1-100, for JPEG/WebP/AVIF. |
| maxFileSizeMb | number | No | — | 0.1-50. Re-encodes lossy output at a lower quality until it fits. |
| preserveMetadata | boolean | No | false | Keep EXIF and other source metadata. |

#### Basic resize

```json
{
  "images": [{ "url": "https://example.com/photo.jpg", "id": "photo-1" }],
  "width": 800,
  "height": 600,
  "fit": "cover",
  "outputFormat": "webp"
}
```

#### E-commerce preset with a file-size cap

```json
{
  "images": [
    { "url": "https://example.com/product-1.jpg", "id": "sku-101" },
    { "url": "https://example.com/product-2.jpg", "id": "sku-102" }
  ],
  "targetPreset": "ecommerce_square",
  "outputFormat": "jpeg",
  "quality": 85,
  "maxFileSizeMb": 1
}
```

#### Combine 3 images into one

```json
{
  "images": [
    { "url": "https://example.com/a.jpg" },
    { "url": "https://example.com/b.jpg" },
    { "url": "https://example.com/c.jpg" }
  ],
  "combineImages": true,
  "targetPreset": "social_square"
}
```

### Output example

```json
{
  "id": "sample-image-1",
  "source": {
    "type": "url",
    "url": "https://placehold.co/1200x800.jpg?text=sample-1",
    "keyValueStoreKey": null,
    "filename": "1200x800.jpg"
  },
  "original": {
    "width": 1200,
    "height": 800,
    "format": "jpeg",
    "contentType": "image/jpeg",
    "sizeBytes": 12722
  },
  "output": {
    "url": "https://api.apify.com/v2/key-value-stores/vta29acCSdrwoGfPz/records/sample-image-1-800x600.webp",
    "width": 800,
    "height": 600,
    "format": "webp",
    "contentType": "image/webp",
    "sizeBytes": 2846
  },
  "metadataPreserved": false,
  "fileSizeLimitMb": null
}
```

When `combineImages` is used, the single output row's `source.type` is `"combined"` and includes a `source.sources` array listing each contributing source's details.

Download results as **JSON, CSV, Excel, HTML, or XML** from the Apify Console, or pull them programmatically through the [Apify API](https://docs.apify.com/api/v2). Each `output.url` is a direct, publicly downloadable link to the generated file.

### How to resize images with this Actor

1. Open **Image Resizer API** on the Apify Store and click **Try for free**.
2. Add image objects to **Images** — a `url`, `base64`, or `keyValueStoreKey` each.
3. Pick a **Target preset**, or choose Custom and set **Width**, **Height**, and **Fit**.
4. Set **Output format**, **Quality**, and optionally **Max file size (MB)**.
5. Click **Start**. Each generated image's URL appears in the **Dataset** tab within seconds.

### How it works

1. For each image, the Actor resolves the source: downloads the URL, decodes the base64, or reads the key-value-store record.
2. It measures the source's real width, height, format, and file size.
3. It resizes/crops/pads the image according to `fit`, `position`, and `paddingMode` (or the chosen preset).
4. It encodes the result in `outputFormat`, iterating quality downward if `maxFileSizeMb` is set and not yet met.
5. It uploads the generated file to the run's key-value store and writes one dataset row with the source, original, and output details.

### How much does it cost to resize images?

Image Resizer API uses **pay-per-event** pricing — you're charged only for images actually generated, not for compute time.

| Event | Price per event | Price per 1,000 |
|-------|------------------|------------------|
| image-processed | $0.00399 (Free plan) | **$3.99** |

Paid Apify plans unlock lower rates ($3.79/1,000 on Bronze, $3.59/1,000 on Silver, $3.39/1,000 on Gold). Processing the 5-image default run costs about $0.02. `combineImages` charges once per combined output image, not once per source. Apify's [monthly platform usage credits](https://apify.com/pricing) apply to this Actor like any other.

### Using the API

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("parsebird/image-resizer-api").call(run_input={
    "images": [{"url": "https://example.com/photo.jpg", "id": "photo-1"}],
    "targetPreset": "ecommerce_square",
    "outputFormat": "webp",
    "quality": 80,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["id"], item["output"]["url"])
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('parsebird/image-resizer-api').call({
    images: [{ url: 'https://example.com/photo.jpg', id: 'photo-1' }],
    targetPreset: 'ecommerce_square',
    outputFormat: 'webp',
    quality: 80,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Schedule recurring batches, trigger the Actor from a webhook after new product photos land in storage, or connect it to Zapier/Make through Apify's [integrations](https://apify.com/integrations).

### Legal and compliance

You are responsible for having the rights to process any image you submit to this Actor, whether by URL, base64, or key-value-store key, and for complying with the terms of any source you pull images from. This Actor only transforms the pixel and file data you provide — it does not retain, redistribute, or index your images beyond the run's own storage.

### Related Actors

- [HTTP Request Actor](https://apify.com/parsebird/http-request-actor) — send arbitrary HTTP requests from a run
- [Data Deduplicator](https://apify.com/parsebird/dataset-deduplicator) — remove duplicate records from a dataset
- [Data Cleaner](https://apify.com/parsebird/data-cleaner) — clean and normalize dataset fields

### FAQ

**What happens if one image fails to download or decode?**
It's skipped with a warning in the run log; the rest of the batch keeps processing. The dataset only contains successfully generated images.

**What's the difference between `inside`/`outside` and `cover`/`contain`?**
`cover` and `contain` always return exactly your requested width/height (cropping or padding as needed). `inside` and `outside` preserve the exact scaled aspect ratio with no cropping or padding, so the output dimensions may differ from what you requested — `inside` never exceeds them, `outside` never falls short of them.

**Does `maxFileSizeMb` work for PNG or GIF?**
No — it only re-encodes JPEG, WebP, and AVIF, since PNG/GIF/TIFF are lossless and don't have a quality dial to turn down. For those formats the file is produced at its natural size and `maxFileSizeMb` is ignored.

**Why is metadata stripped by default?**
EXIF data can include GPS coordinates, camera/device info, and timestamps that many users don't want to republish. Set `preserveMetadata: true` if you need it kept.

**Can I mix `url`, `base64`, and `keyValueStoreKey` sources in one run?**
Yes — each image object in `images` picks its own source type independently.

**Can I schedule recurring runs?**
Yes. Use Apify's [Scheduler](https://docs.apify.com/platform/schedules) to run this Actor on any interval.

**Does this Actor have an API?**
Yes — every Apify Actor is automatically available as an API. See the [API tab](https://apify.com/parsebird/image-resizer-api/api) for the full spec, or use the Python/JavaScript examples above.

**Something not working?**
Report it on the Actor's **Issues** tab in Apify Console.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/image-resizer-api/changelog.md

# Actor input Schema

## `images` (type: `array`):

1 to 100 image objects. Each needs exactly one of `url`, `base64`, or `keyValueStoreKey`. Add `id` and/or `filename` for stable matching in the output.

## `combineImages` (type: `boolean`):

Combine 2 or 3 source images into a single output image side by side, then apply the size/fit settings below to the combined result.

## `targetPreset` (type: `string`):

A preset sets width, height, and fit for a common layout. Choose Custom to set width/height/fit yourself.

## `width` (type: `integer`):

Output width in pixels. Only used when Target preset is Custom.

## `height` (type: `integer`):

Output height in pixels. Only used when Target preset is Custom.

## `fit` (type: `string`):

How the image fills the target box. Only used when Target preset is Custom.

## `position` (type: `string`):

Anchor used when cropping (Cover) or placing the image on padding (Contain).

## `paddingMode` (type: `string`):

How to fill extra space left by Contain fit, or by transparent areas in formats that don't support alpha.

## `backgroundColor` (type: `string`):

Hex color used for solid padding, and to flatten transparent areas when the output format has no alpha channel (e.g. JPEG).

## `outputFormat` (type: `string`):

File format for every generated image.

## `quality` (type: `integer`):

Quality for lossy formats (JPEG, WebP, AVIF), 1-100. Ignored for PNG, GIF, and TIFF.

## `maxFileSizeMb` (type: `number`):

Optional. For JPEG, WebP, or AVIF output, re-encode at a lower quality until the file is under this size. Leave empty for no limit. Some presets imply a limit (e.g. WhatsApp) unless you set one here.

## `preserveMetadata` (type: `boolean`):

Keep EXIF and other source metadata in the output. Off by default, which also produces smaller files.

## Actor input object example

```json
{
  "images": [
    {
      "url": "https://placehold.co/1200x800.jpg?text=sample-1",
      "id": "sample-image-1"
    },
    {
      "url": "https://placehold.co/1280x840.jpg?text=sample-2",
      "id": "sample-image-2"
    },
    {
      "url": "https://placehold.co/1360x880.jpg?text=sample-3",
      "id": "sample-image-3"
    },
    {
      "url": "https://placehold.co/1440x920.jpg?text=sample-4",
      "id": "sample-image-4"
    },
    {
      "url": "https://placehold.co/1520x960.jpg?text=sample-5",
      "id": "sample-image-5"
    }
  ],
  "combineImages": false,
  "targetPreset": "custom",
  "width": 800,
  "height": 600,
  "fit": "cover",
  "position": "center",
  "paddingMode": "solid",
  "backgroundColor": "#FFFFFF",
  "outputFormat": "webp",
  "quality": 80,
  "preserveMetadata": false
}
```

# Actor output Schema

## `dataset` (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 = {
    "images": [
        {
            "url": "https://placehold.co/1200x800.jpg?text=sample-1",
            "id": "sample-image-1"
        },
        {
            "url": "https://placehold.co/1280x840.jpg?text=sample-2",
            "id": "sample-image-2"
        },
        {
            "url": "https://placehold.co/1360x880.jpg?text=sample-3",
            "id": "sample-image-3"
        },
        {
            "url": "https://placehold.co/1440x920.jpg?text=sample-4",
            "id": "sample-image-4"
        },
        {
            "url": "https://placehold.co/1520x960.jpg?text=sample-5",
            "id": "sample-image-5"
        }
    ],
    "width": 800,
    "height": 600,
    "backgroundColor": "#FFFFFF",
    "quality": 80
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/image-resizer-api").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 = {
    "images": [
        {
            "url": "https://placehold.co/1200x800.jpg?text=sample-1",
            "id": "sample-image-1",
        },
        {
            "url": "https://placehold.co/1280x840.jpg?text=sample-2",
            "id": "sample-image-2",
        },
        {
            "url": "https://placehold.co/1360x880.jpg?text=sample-3",
            "id": "sample-image-3",
        },
        {
            "url": "https://placehold.co/1440x920.jpg?text=sample-4",
            "id": "sample-image-4",
        },
        {
            "url": "https://placehold.co/1520x960.jpg?text=sample-5",
            "id": "sample-image-5",
        },
    ],
    "width": 800,
    "height": 600,
    "backgroundColor": "#FFFFFF",
    "quality": 80,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/image-resizer-api").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 '{
  "images": [
    {
      "url": "https://placehold.co/1200x800.jpg?text=sample-1",
      "id": "sample-image-1"
    },
    {
      "url": "https://placehold.co/1280x840.jpg?text=sample-2",
      "id": "sample-image-2"
    },
    {
      "url": "https://placehold.co/1360x880.jpg?text=sample-3",
      "id": "sample-image-3"
    },
    {
      "url": "https://placehold.co/1440x920.jpg?text=sample-4",
      "id": "sample-image-4"
    },
    {
      "url": "https://placehold.co/1520x960.jpg?text=sample-5",
      "id": "sample-image-5"
    }
  ],
  "width": 800,
  "height": 600,
  "backgroundColor": "#FFFFFF",
  "quality": 80
}' |
apify call parsebird/image-resizer-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/image-resizer-api"
        }
    }
}
```

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/0vQdodRssedRqmEA9/builds/WqcavAsLzRFTHlDwd/openapi.json
