# Social Image Resizer (No Crop): Instagram, Pinterest (`bigaceboy/social-image-letterboxer`) Actor

Resize images for Instagram (1080x1350), Pinterest (1000x1500), square and Stories without cropping. Fits the whole photo on any background color, fixes phone rotation, flattens transparent PNGs. Bulk URLs or uploads, JPG/PNG/WebP. $0.005 per image, failures free. API, n8n and MCP ready.

- **URL**: https://apify.com/bigaceboy/social-image-letterboxer.md
- **Developed by:** [Anthony Crawford](https://apify.com/bigaceboy) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 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.

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

**Resize images for Instagram, Pinterest, Facebook and Stories without cropping.** Social Image Resizer takes any photo, product shot, screenshot or logo and fits the *whole* picture into the exact social media size you need (Instagram portrait 1080×1350, Pinterest pin 1000×1500, square 1080×1080, Story/Reel 1080×1920 or any custom size). The leftover space is filled with a background color you choose, so nothing gets cut off. Batch many image URLs in one run, get a direct download link for every resized image, and pay **$0.005 per image**. Works from the Apify Console, the API, n8n, Make, Zapier and AI agents through the Apify MCP server.

### What can this social media image resizer do?

- 📐 **Ready-made social sizes**: Instagram/Facebook portrait **1080×1350 (4:5)**, Pinterest pin **1000×1500 (2:3)**, square **1080×1080 (1:1)**, Story/Reel/TikTok **1080×1920 (9:16)**, plus any **custom width × height** (e.g. 1200×628 link previews).
- ✂️ **No cropping, ever** ("contain" / letterbox fit). Text, faces and products stay fully visible. The bars use your hex color (default warm cream `#F4EFE6`, or white `#FFFFFF`, black `#000000`…).
- 🧭 **Fixes sideways phone photos** by applying the EXIF orientation automatically.
- 🫥 **Handles transparent PNGs**: transparency is flattened onto your background color, so you never get black boxes in JPGs.
- ↔️ **Optional padding** (% of the canvas) for breathing room around the image.
- 🖼️ **JPG, PNG or WebP** output with adjustable quality.
- 📦 **Batch**: up to 500 source images and 1,000 output images per run, several sizes at once.
- 🔗 **Direct download URL** for every result, plus one clean dataset row per image (easy to use in Make, Zapier, n8n, Buffer workflows and AI agents).
- 🛡️ **Safe on bad input**: broken links, web pages instead of images, files over the size cap or over 40 megapixels become error rows and are **not charged**.

### Who is it for?

Small shops, Etsy/Shopify/Whop sellers, creators, social media managers and AI agents that post the same picture to Instagram, Facebook, Pinterest and Stories and don't want the app to crop off the edges.

### How to resize an image for Instagram without cropping

1. Click **Try for free** (or **Start**) on this page and sign in to Apify.
2. Paste one or more **direct image links** into **Image URLs** (right-click an image → *Copy image address*), or upload files.
3. Pick the **Output sizes**, e.g. *Instagram/Facebook portrait 1080×1350* and *Pinterest pin 1000×1500*.
4. Choose a **Background color** (hex) and, if you like, a little **Padding**.
5. Click **Start**. In a few seconds the **Output** tab shows each image with its `outputUrl`. Download them or send them on to your scheduler.

### Input example

Copy-paste this JSON into the Input tab (JSON view), the API or your agent:

```json
{
  "imageUrls": [
    "https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"
  ],
  "presets": ["instagram-portrait", "pinterest-pin", "story"],
  "backgroundColor": "#F4EFE6",
  "paddingPercent": 5,
  "outputFormat": "jpg",
  "quality": 90
}
```

This creates 1 image × 3 sizes = **3 output images = $0.015**.

#### Size presets

| Preset | Size | Use it for |
| --- | --- | --- |
| `instagram-portrait` | 1080 × 1350 (4:5) | Instagram and Facebook feed posts (biggest feed footprint) |
| `pinterest-pin` | 1000 × 1500 (2:3) | Standard Pinterest pins |
| `square` | 1080 × 1080 (1:1) | Instagram, Facebook, LinkedIn, marketplaces |
| `story` | 1080 × 1920 (9:16) | Instagram/Facebook Stories, Reels covers, TikTok |
| `custom` | your width × height | Anything else, e.g. 1200 × 628 link previews or 1280 × 720 YouTube thumbnails |

#### All input fields

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `imageUrls` | array of strings | – | Direct image links. Also accepts `kvs://<storeIdOrName>/<key>` for files in an Apify key-value store. |
| `keyValueStoreImages` | array of strings | – | Upload files in Console, or reference `<storeIdOrName>/<key>` (or `<key>` in the run's default store). |
| `presets` | array | `["instagram-portrait","pinterest-pin"]` | Any of `instagram-portrait`, `pinterest-pin`, `square`, `story`, `custom`. |
| `customWidth`, `customHeight` | integer | – | 16–8000 px. Setting both adds a custom size. |
| `backgroundColor` | hex string | `#F4EFE6` | `#RGB` or `#RRGGBB`. |
| `paddingPercent` | integer | `0` | 0–40 % of the output width (sides) and height (top/bottom). |
| `outputFormat` | `jpg` / `png` / `webp` | `jpg` | |
| `quality` | integer | `90` | jpg/webp only. |
| `maxInputSizeMb` | integer | `25` | Bigger files are skipped (max 50). |
| `downloadTimeoutSecs` | integer | `30` | Per image. |

### Output example

Every resized image is saved to the run's default **key-value store**, and the **dataset** gets one row per source image per size (download as JSON, CSV or Excel, or read it from the API):

```json
{
  "source": "https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600",
  "preset": "pinterest-pin",
  "width": 1000,
  "height": 1500,
  "format": "jpg",
  "backgroundColor": "#F4EFE6",
  "outputKey": "001-photo-1512389142860-9c449e58a543-pinterest-pin.jpg",
  "outputUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-photo-1512389142860-9c449e58a543-pinterest-pin.jpg",
  "outputBytes": 201733,
  "sourceWidth": 1600,
  "sourceHeight": 1067,
  "sourceFormat": "jpeg",
  "exifOrientation": 1,
  "hadTransparency": false,
  "status": "ok",
  "charged": true
}
```

Failed rows are **not charged**:

```json
{ "source": "https://example.com/missing.jpg", "preset": "pinterest-pin", "status": "error", "errorCode": "HTTP_ERROR", "error": "HTTP 404 Not Found", "charged": false }
```

Error codes: `INVALID_URL`, `HTTP_ERROR`, `DOWNLOAD_FAILED`, `DOWNLOAD_TIMEOUT`, `TOO_LARGE`, `TOO_MANY_PIXELS`, `UNSUPPORTED_FORMAT`, `NOT_FOUND`, `PROCESSING_FAILED`.

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

Simple pay-per-image pricing, no subscription to this Actor:

| What you do | Output images | Price |
| --- | --- | --- |
| 1 photo → Instagram portrait | 1 | $0.005 |
| 1 photo → Instagram + Pinterest + Story | 3 | $0.015 |
| 100 product photos → Instagram + Pinterest | 200 | $1.00 |
| 1,000 output images | 1,000 | $5.00 |

| Event | Price | When |
| --- | --- | --- |
| `image-processed` | **$0.005** | One output image (one source × one size) was saved and is downloadable. |
| `apify-actor-start` | $0.00005 | Apify's standard tiny start fee per run. |

Failed images are free. If you set a **maximum cost per run**, the Actor stops cleanly before going over it and keeps everything already made. Apify's free plan includes monthly platform credit, which is enough to try this Actor many times.

### Use with AI agents (Apify MCP server)

AI agents (Claude, ChatGPT, Cursor, VS Code, LangChain, CrewAI and any MCP client) can call this Actor as a tool through the hosted [Apify MCP server](https://mcp.apify.com). To load only this tool, use:

```
https://mcp.apify.com?tools=bigaceboy/social-image-letterboxer
```

Example MCP client config (OAuth sign-in on first connect):

```json
{
  "mcpServers": {
    "social-image-resizer": { "url": "https://mcp.apify.com?tools=bigaceboy/social-image-letterboxer" }
  }
}
```

Then just ask: *"Make Instagram portrait and Pinterest versions of these 3 images on a white background and give me the links."* The agent sends `imageUrls` + `presets` and reads `outputUrl` from each result. Because the Actor uses pay-per-event pricing, agents can also pay per run through Apify's agentic payments.

### Use with n8n, Make and Zapier

- **n8n**: add the **Apify** node → *Actors* → **Run an Actor and Get Dataset** → Actor `bigaceboy/social-image-letterboxer`, put the input JSON in *Custom input* (map your image URL with an expression), and use `outputUrl` in the next node (Google Drive, Buffer, Instagram, email…).
- **Make**: Apify app → **Run an Actor** (wait for finish) → **Get Dataset Items** → map `outputUrl`.
- **Zapier**: Apify → **Run Actor** (synchronous) and use the dataset items in the next step.

### Use with the API (curl, JavaScript, Python)

One synchronous call returns the dataset rows:

```bash
curl -X POST "https://api.apify.com/v2/acts/bigaceboy~social-image-letterboxer/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"imageUrls":["https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"],"presets":["instagram-portrait","pinterest-pin"]}'
```

JavaScript (`npm i apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('bigaceboy/social-image-letterboxer').call({
  imageUrls: ['https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600'],
  presets: ['instagram-portrait', 'pinterest-pin'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => i.outputUrl));
```

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("bigaceboy/social-image-letterboxer").call(run_input={
    "imageUrls": ["https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"],
    "presets": ["instagram-portrait", "pinterest-pin"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["outputUrl"])
```

### FAQ

#### How do I post a full photo on Instagram without cropping?

Instagram crops feed photos that are taller or wider than the ratios it allows. Resize the photo to **1080×1350 (4:5 portrait)**, the classic tallest feed size, with the whole image fitted inside and the empty space filled with a background color. That's exactly what the `instagram-portrait` preset does.

#### What size should a Pinterest pin be?

**1000×1500 px (2:3)** is Pinterest's recommended pin size. Use the `pinterest-pin` preset; wide photos get bars above and below instead of being cut.

#### Does it crop or stretch my image?

Neither. The image is scaled down (or up) proportionally until it fits, then centered on the background color.

#### Can I use a white or transparent background?

Any hex color works (`#FFFFFF` for white). Output is always opaque, so transparent PNGs are flattened onto that color; choose `png` or `webp` if you want lossless edges.

#### Can I resize images in bulk?

Yes. Pass many URLs and several presets; you get one output per image per size (up to 1,000 per run).

#### My link fails with UNSUPPORTED_FORMAT or HTTP_ERROR

The link probably points to a web page, not the image file. Open the image itself and copy that address. Failed images are never charged.

#### Can I schedule it or chain it with other tools?

Yes. Use Apify Schedules, webhooks or integrations, or call it from n8n/Make/Zapier. It pairs well with the tools below.

### Other tools by this developer

| Tool | What it does | Price |
| --- | --- | --- |
| [Image Optimizer & Converter](https://apify.com/bigaceboy/image-optimizer-converter) | Compress images to WebP/AVIF/JPG, hit a target KB size, strip GPS | $0.002 / image |
| [Website Screenshot to Social Image](https://apify.com/bigaceboy/website-screenshot-to-social) | Screenshot any URL into Instagram, Pinterest or OG 1200×630 images | $0.004 / image |
| [Markdown & HTML to PDF Converter](https://apify.com/bigaceboy/markdown-html-to-pdf) | Turn Markdown, HTML or a URL into a clean PDF | $0.004 / PDF |

### Tips and limits

- Inputs: JPG, PNG, WebP, GIF (first frame), AVIF, TIFF. Up to 50 MB (default cap 25 MB) and 40 megapixels.
- Up to 500 source images and 1,000 output images per run; split larger jobs into several runs.
- Default memory is 512 MB; 256 MB also works (slower).
- Results stay in your storage for your Apify plan's data retention period. Download what you need.
- Questions or a feature request? Open an issue on the **Issues** tab.

### Changelog

- **1.0**: First release. Instagram, Pinterest, square, story and custom sizes; EXIF rotation; transparency flattening; JPG/PNG/WebP; pay per image. README and input help improved for search and AI agents.

# Actor input Schema

## `imageUrls` (type: `array`):

Direct, publicly reachable links to image files (JPG, PNG, WebP, GIF first frame, AVIF, TIFF). Each link must return the image itself, not a web page. You can also pass Apify key-value store records as kvs://<storeIdOrName>/<key>.

## `keyValueStoreImages` (type: `array`):

Optional. Upload image files here, or reference images already saved in an Apify key-value store as "<storeIdOrName>/<key>" (or just "<key>" for this run's default store). Combined with Image URLs.

## `presets` (type: `array`):

Which sizes to create for every image. instagram-portrait = 1080×1350 (4:5, Instagram & Facebook feed), pinterest-pin = 1000×1500 (2:3), square = 1080×1080 (1:1), story = 1080×1920 (9:16 Stories, Reels, TikTok). Choose 'custom' and set Custom width/height for any other size. Each selected size is one billable output image.

## `customWidth` (type: `integer`):

Width in pixels for the 'custom' size (16–8000). Setting both custom width and height adds a custom output even if 'custom' is not selected.

## `customHeight` (type: `integer`):

Height in pixels for the 'custom' size (16–8000). Example: 1200 × 628 for a link preview, 1280 × 720 for a YouTube thumbnail.

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

Hex color used for the letterbox bars and behind transparent areas, e.g. #F4EFE6 (warm cream, default), #FFFFFF (white) or #000000 (black).

## `paddingPercent` (type: `integer`):

Extra breathing room on every side, as a percent of the output width (left/right) and height (top/bottom). 0 = image touches the edges on its long side. Max 40.

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

File format of the results. jpg is smallest and accepted everywhere; png is lossless; webp is small and modern. Transparency is always flattened onto the background color.

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

Compression quality for jpg and webp (1–100). 90 is visually lossless for social posts. Ignored for png.

## `maxInputSizeMb` (type: `integer`):

Source files bigger than this are skipped with a TOO_LARGE error (not charged). Images over 40 megapixels are also skipped.

## `downloadTimeoutSecs` (type: `integer`):

How long to wait for each image URL before giving up (not charged).

## Actor input object example

```json
{
  "imageUrls": [
    "https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"
  ],
  "presets": [
    "instagram-portrait",
    "pinterest-pin",
    "story"
  ],
  "customWidth": 1200,
  "customHeight": 628,
  "backgroundColor": "#FFFFFF",
  "paddingPercent": 5,
  "outputFormat": "jpg",
  "quality": 90,
  "maxInputSizeMb": 25,
  "downloadTimeoutSecs": 30
}
```

# Actor output Schema

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

Dataset rows: source, preset, width, height, status, outputUrl, errorCode, error, charged.

## `images` (type: `string`):

Keys of the resized image files saved in the default key-value store.

# 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 = {
    "imageUrls": [
        "https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bigaceboy/social-image-letterboxer").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 = { "imageUrls": ["https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"] }

# Run the Actor and wait for it to finish
run = client.actor("bigaceboy/social-image-letterboxer").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 '{
  "imageUrls": [
    "https://images.unsplash.com/photo-1512389142860-9c449e58a543?w=1600"
  ]
}' |
apify call bigaceboy/social-image-letterboxer --silent --output-dataset

```

## MCP server setup

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

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/Q0tOEPcD4SvlSjOfi/builds/ZVm32DIhJLUoYz34Z/openapi.json
