E-commerce Image Pack Pipeline avatar

E-commerce Image Pack Pipeline

Pricing

from $20.00 / 1,000 image processeds

Go to Apify Store
E-commerce Image Pack Pipeline

E-commerce Image Pack Pipeline

Turn product photos into white-background image packs sized for Amazon, Etsy, Shopify, and eBay.

Pricing

from $20.00 / 1,000 image processeds

Rating

0.0

(0)

Developer

Olalekan Johnson

Olalekan Johnson

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Turn a product photo into a marketplace-ready pack: background removed, placed on pure white, sized for Amazon, Etsy, Shopify, and eBay, compressed, and stripped of EXIF. One run, one ZIP, one report row per photo.

Unofficial, and not affiliated with Amazon, Etsy, Shopify, or eBay. Channel presets follow those companies' published image pages as checked on 23 October 2026. Category style guides can be stricter than the preset.

For sellers and listing agencies who repeat the same export every time a photo comes in.

  • A ZIP (IMAGE_PACK in the key-value store) with one file per channel, plus manifest.csv.
  • A dataset row per source photo: sizes, hashes, alt text, confidence, and whether it changed since the last run.
  • A run summary (OUTPUT) with rowsCharged, rowsDropped, fillRate, and error counts.

You're only charged for rows that pass validation. A row is billed only when every channel you asked for produced a file that matches that channel's size, format, byte cap, and (where required) white background, and the file has no EXIF.

What a row looks like

{
"status": "ok",
"charged": true,
"coverage": "complete",
"fillRate": 1,
"observedAt": "2026-10-23T16:30:00Z",
"sourceTitle": "Coffee cup",
"sourceKind": "sample",
"channelsRequested": "amazon,etsy,shopify,ebay",
"channelsPassed": "amazon,etsy,shopify,ebay",
"backgroundRemoved": true,
"whiteBackground": true,
"exifStripped": true,
"confidence": 0.9938,
"altText": "Coffee cup. White-background product photo. Prepared for Amazon (2000×2000), Etsy (2000×2000), Shopify (2048×2048), and eBay (1600×1600).",
"altTextSource": "deterministic",
"changedSincePrevious": true,
"amazonFile": "amazon/01-coffee-cup.jpg",
"amazonWidth": 2000,
"amazonHeight": 2000,
"amazonBytes": 183417,
"amazonFormat": "jpeg",
"specVersion": "2026-10-23",
"zipKey": "IMAGE_PACK"
}

Etsy, Shopify, and eBay use the same column pattern (etsyFile, shopifyWidth, ebayBytes, and so on). Failed fetches use status of blocked, unsupported, failed, or no_results and are not billed.

Pricing

This Actor uses pay-per-event pricing. The event is image-processed: $0.02 per validated source image. There is no per-dataset-item charge. Apify also charges a $0.005 start event once per run.

Billing is per source image, not per channel file. Cutting the background out is the costly step and it runs once per photo. Exporting Amazon plus Etsy plus Shopify plus eBay after that is a resize. Charging once per photo keeps a 4-channel pack the same price as a 1-channel pack.

JobEventsTotal
1 photo, any number of the four channels1 × $0.02$0.02 plus the $0.005 start
Default demo (3 public-domain photos, 4 channels)3 × $0.02$0.06 plus the $0.005 start
100-photo catalog100 × $0.02$2.00 plus one start event
1,000 photos1,000 × $0.02$20 plus one start event

1,000 results ≈ $20, plus one $0.005 start event for the run. maxImages defaults to 10 (maximum 50) so a dataset cannot run away. Raise it when you mean to.

Rows that fail validation are not charged. When the Actor runs without pay-per-event (for example locally), the rows are still delivered and rowsCharged stays 0. fillRate is still the share of finished rows that passed validation.

How a photo is processed

  1. Read URLs, an inline JSON or CSV list, a dataset, or the three bundled samples when the input is empty.
  2. Reject private, loopback, link-local, and metadata addresses before the request. Redirects are checked again.
  3. Download with a size cap. An HTTP 200 page that is HTML or a challenge is blocked, not a success.
  4. Apply the EXIF orientation, then drop EXIF (including GPS) from the output. An sRGB profile is embedded so the file stays in sRGB.
  5. Optionally cut the background out with U²-Net portable (u2netp), a 4.4 MB Apache-2.0 model, on CPU at 320×320. No GPU.
  6. Place the product on pure white so its longer side is 85% of the channel canvas, then compress under that channel's byte cap.
  7. Write alt text from the title and the channel sizes. An optional OpenAI key can phrase the sentence. If the key is missing or the call fails, the deterministic sentence is used.
  8. Charge image-processed only after the row passes. Stop when the run's max total charge is reached. The same result id is not charged twice in one run.

Channel presets

Checked 23 October 2026. specVersion on each row is 2026-10-23.

ChannelCanvasFileWhat the publisher's page says
Amazon2000×2000 JPEG, pure white, product longer side at 85% of the frame, under 10,485,760 bytesMain-image packSeller Central help G1881 is login-gated. Amazon's own restatement of that page (Seller Central, checked the same day) says: longest side 500–10,000 px, at least 1,000 px for zoom, JPEG preferred (PNG, TIFF, or non-animated GIF also accepted), MAIN image on RGB 255,255,255, product shown as 85% of the image. The byte cap is the 10,485,760-byte ceiling shown in an Amazon upload dialog; G1881's public restatement specifies pixels and formats, not bytes.
Etsy2000×2000 JPEG, sRGB, under 960 KBEdited companion imageEtsy Help: image requirements. Listing photos are recommended at 2,000 px or more on width and height. The first photo should be at least 635 px. Files larger than 1 MB may fail to upload. Accepted types include JPEG and PNG. Transparent PNG is not supported. Square is allowed for the first photo.
Shopify2048×2048 JPEG, under 20 MBProduct imageProduct media types. Square images usually display best at 2048×2048. Uploads can be up to 5000×5000 px or 25 megapixels and must be under 20 MB. JPEG is the recommended type for product photos. File uploads also cite a 20 megapixel and 20 MB cap. 2048×2048 sits inside both.
eBay1600×1600 JPEG, under 7 MBListing photoAdding pictures (Australia): at least 500 px on the longest side, 800–1600 recommended, direct upload up to 7 MB (12 MB if imported from a URL). JPEG, PNG, GIF, TIFF, BMP, WEBP, HEIC, or AVIF. UK Seller Centre: at least 1600×1600 recommended, and a white or neutral background.

Two limits you should not skip:

  • Etsy still wants one unedited photo of the real item on a real background for most listings. This pack is the edited white-background image, not that photo. See how the requirement applies.
  • Amazon category rules are not applied. Apparel-on-a-model, a single shoe facing left, and similar rules live in category style guides. This preset is the ordinary main image: white, 85% fill, nothing cropped, no text added.

The 85% figure is the longer side of the product box as a fraction of the canvas. The product is not cropped to hit it. "Show the product as 85% of the image" is Amazon's wording; the other channels do not require that ratio. The same framing is used so the pack matches.

Input

Leave every field blank and the run processes three CC0 sample photos (a coffee cup, a water bottle, a moulding bowl). That is the default, and it is what an empty {} input does.

FieldDefaultWhat it does
imageUrlsemptyhttps image URLs, or a small data:image/...;base64 URL.
datasetIdemptyApify dataset to read. The run must be allowed to read it.
datasetImageFieldimageUrlField that holds the URL. A list of URLs in that field works too.
imagesJsonempty["https://..."] or [{"url":"https://...","title":"Mug"}].
imagesCsvemptyHeader row with url and optional title.
productTitleemptyUsed when an image has no title of its own. Stored as plain text.
channelsall fouramazon, etsy, shopify, ebay.
removeBackgroundtrueCPU cutout. Turn off to only resize, pad, and strip EXIF.
whiteBackgroundtrueFlatten onto RGB 255,255,255. Amazon's preset does not export without it.
outputFormatjpegpng or webp when the channel allows it. Otherwise the file is JPEG.
jpegQuality90Starting quality. It steps down if a byte cap would be missed.
suggestAltTexttrueDeterministic sentence.
openAiApiKeyempty secretOptional. Your key, used only to phrase alt text. Not stored.
maxImages10Cap, maximum 50.
maxImageBytes8000000Reject larger downloads.
alertOnlyOnChangefalseSkip photos whose output hash matches the saved baseline.

Private IPs, localhost, link-local and metadata hosts, credentials in the URL, and ports other than 80 and 443 are rejected. A public host that resolves to a private address is rejected too.

Output

  • Dataset: one row per source image. The Output tab has an Image report view and a Channel files view.
  • Key-value OUTPUT: counts, fillRate, errors (proxy, rate-limit, blocked, network, other), seconds, and peak memory.
  • Key-value IMAGE_PACK: the ZIP.
  • Named key-value store ecommerce-image-pack-state, record baseline: hashes of billed outputs, used for the next run's diff. A run that throws does not replace this record. An unreadable baseline is left as it is.

coverage is complete, partial, empty, blocked, or unsupported. partial with status: ok still passed validation (usually a low-confidence mask or an upscale warning) and can be billed. changedSincePrevious is false when the file hash matches the baseline.

Scheduled runs

Turn on alertOnlyOnChange for a daily task. Unchanged photos are not exported and not charged. If nothing changed, the dataset gets one unbilled row:

{"status": "no_results", "charged": false, "coverage": "empty", "reason": "No channel files changed since the previous run."}

That is on purpose. A succeeded run with an empty dataset is a bad result for an agent. Duplicate bytes in the same run are processed once (duplicateCount). The same result id is not charged twice after a retry in the same run.

Alt text

With no API key the sentence is built from the title and the channel sizes. It is one line of plain text.

If you set openAiApiKey, the Actor sends a small preview to OpenAI (gpt-4o-mini) and asks for a short description. The channel sizes are still appended here, not invented by the model. Any error, timeout, or unusable reply falls back to the deterministic sentence (altTextSource is llm or deterministic). The key is a secret input and is not written to the dataset or the log.

Model and demo photos

Background removal uses U²-Net portable by Xuebin Qin et al., Apache License 2.0, which allows commercial use. The ONNX file is pinned at SHA-256 309c8469258dda742793dce0ebea8e6dd393174f89934733ecc8b14c76f4ddd8. See THIRD_PARTY_NOTICES.md. The model is small and runs on CPU. Edges on hair, glass, and cluttered backgrounds can be coarse. Read confidence before you publish the file. This is not a studio retouch.

Demo photos are resized CC0 images from Wikimedia Commons:

License: CC0 1.0.

Integrations

  • Webhook. On run succeeded, read the dataset items. Each item is one photo, flat fields, no nested objects.
  • n8n / Make. Apify "Run Actor" then "Get dataset items". Download IMAGE_PACK from the key-value store when you need the files.
  • Google Sheets. Apify's Google Sheets integration can append the dataset. The columns are already flat.
  • Another Actor. Pass a datasetId from an upstream run and set datasetImageField to the URL field.

The Actor does not need Standby mode, a browser, or a proxy. Limited permissions are enough: it fetches the URLs you supply and, only if you set datasetId, reads that dataset.

FAQ

Why is a row ok but charged is false? Pay-per-event is not enabled yet, or the charge limit was already reached. The file can still be in the ZIP. OUTPUT.billingActive and chargeLimitReached say which.

Why did Amazon get dropped when I turned white off? Amazon's main-image preset requires RGB 255,255,255. The other channels still export. If Amazon was the only channel, the row is not billed.

Can I use the Etsy file as my only listing photo? No. Etsy asks most sellers for at least one unedited photo on a real background. Use this file as an additional image.

Does it call a paid background API? No. The cutout runs locally. The only optional paid call is alt text, and only with your own key.

What if the host returns a captcha? The row is blocked with errorCategory: blocked and is not charged. Timeouts and HTTP 5xx count as network. HTTP 429 counts as rate-limit.

Run it locally

Python 3.12.

pip install -r requirements.txt
python -m ecommerce_image_pack

An empty input uses the sample photos and writes storage/. Set ACTOR_TEST_PAY_PER_EVENT=1 if you want charge calls recorded locally. Tests:

pip install -r requirements-dev.txt
pytest

Contact: plusonecares@gmail.com