API

Google Sheets: Remove Backgrounds for a Whole Column of Image URLs (Apps Script)

September 6, 20265 min readBy BG Clear Editorial

Product feeds, supplier catalogues and marketplace exports all end up as a Google Sheet with a column of image URLs. If those images need a clean white background before they go to Google Shopping or a marketplace, you do not need to download anything: Apps Script can call a background removal API for every row and write the result URL next to it. This script is resumable, respects the rate limit, and shows a preview in the sheet.

In this guide

Setup

Create an API key on the bgclear dashboard (10 free full-resolution credits; preview size is free without limit). In your sheet: column A = source image URL, column B = result URL, column C = preview, row 1 = headers. Open Extensions → Apps Script, paste the script below, then store the key with PropertiesService so it never sits in the code: run setKey() once from the editor.

function setKey() {
  PropertiesService.getScriptProperties().setProperty('BGCLEAR_API_KEY', 'bgc_live_PASTE_YOUR_KEY');
}

The script

const API = 'https://www.bgclear.ai/api/v1/remove';

function removeBackgrounds() {
  const key = PropertiesService.getScriptProperties().getProperty('BGCLEAR_API_KEY');
  const sheet = SpreadsheetApp.getActiveSheet();
  const rows = sheet.getRange(2, 1, sheet.getLastRow() - 1, 2).getValues(); // A:B
  const started = Date.now();

  rows.forEach(([src, done], i) => {
    if (!src || done) return;                                    // resumable: skip finished rows
    if (Date.now() - started > 5 * 60 * 1000) return;            // stay under the 6-min execution cap

    const res = UrlFetchApp.fetch(API, {
      method: 'post',
      contentType: 'application/json',
      headers: {
        Authorization: 'Bearer ' + key,
        Accept: 'application/json',
        'Idempotency-Key': 'sheet-' + Utilities.base64EncodeWebSafe(src), // safe re-runs
      },
      payload: JSON.stringify({ image_url: src, size: 'auto', format: 'jpg', bg_color: 'ffffff' }),
      muteHttpExceptions: true,
    });

    const code = res.getResponseCode();
    const body = JSON.parse(res.getContentText());
    const row = i + 2;
    if (code === 200) {
      sheet.getRange(row, 2).setValue(body.url);                      // result URL (valid 24 h)
      sheet.getRange(row, 3).setFormula('=IMAGE(B' + row + ')');      // preview in the sheet
    } else if (code === 429) {
      Utilities.sleep(1000 * Number(res.getHeaders()['X-RateLimit-Reset'] || 5));
    } else if (code === 402) {
      throw new Error('Out of credits — https://www.bgclear.ai/api-pricing/');
    } else {
      sheet.getRange(row, 2).setValue('ERROR ' + code + ': ' + (body.error && body.error.message));
    }
    Utilities.sleep(1100);                                            // ≤60 requests/minute
  });
}

Run removeBackgrounds() from the editor or add a menu item; rerun it to continue where it stopped — rows with a value in column B are skipped, and the idempotency key means a row that was interrupted mid-request is not charged twice.

Getting the images somewhere permanent

Result URLs expire after 24 hours, which is fine for a marketplace upload the same day but not for a feed that is re-read weekly. Add a step that copies each result to Drive:

function archiveToDrive() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const folder = DriveApp.getFolderById('YOUR_FOLDER_ID');
  const rows = sheet.getRange(2, 2, sheet.getLastRow() - 1, 3).getValues(); // B:D
  rows.forEach(([url, , driveUrl], i) => {
    if (!url || driveUrl || !url.startsWith('http')) return;
    const file = folder.createFile(UrlFetchApp.fetch(url).getBlob().setName('row-' + (i + 2) + '.jpg'));
    file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
    sheet.getRange(i + 2, 4).setValue('https://drive.google.com/uc?id=' + file.getId());
  });
}

Column D then holds a stable link you can paste into Google Merchant Center, Shopify or a WooCommerce CSV import.

Dry run, cost and limits

Change size: 'auto' to size: 'preview' for a free dry run (800 px results) on a new supplier's images, then switch back. Each full-resolution image is one credit — a 500-row sheet is the $39 pack ($0.078 per image); credits never expire and failed rows are not charged (pricing). Apps Script's own limits are the ones to watch: 6 minutes per execution (the script stops itself at 5 and resumes on the next run) and a daily UrlFetchApp quota that a 2,000-row sheet fits inside. Images must be publicly fetchable URLs; Drive links need "anyone with the link" sharing and the uc?id= form. Coming from a remove.bg script? The JSON body is the same; only the URL and the header changed — migration notes.

Frequently asked questions

Can I run this automatically when rows are added?

Yes — add a time-driven trigger (Triggers → every hour) for removeBackgrounds(); it only processes rows without a result.

Why JPG with a white background instead of PNG?

Marketplace feeds want a solid white main image and JPG is much smaller. For transparent cutouts use format: 'png' and drop bg_color.

Do the images have to be public?

Yes, the API fetches image_url server-side. Drive files work with 'anyone with the link' and the uc?id= URL form; private CDN links need a signed URL.

What if a row errors?

The error message is written into column B; clear the cell and rerun to retry that row. Failed requests are never charged.

Ship it with the bgclear API

remove.bg-compatible endpoints, credits from $9 for 100 images, no subscription. Pay, get a key, make your first call in under two minutes.

Get API credits →

Tools for this guide

How to Get White Background in Product Photos

how to get white background in product photos

White Background Product Photo Online

white background product photo online

Aadhaar Photo Background White

aadhaar photo background white

Keep reading

API

Automate Background Removal in n8n, Zapier and Make (No Code)

Exact node-by-node settings to remove backgrounds inside an automation: HTTP Request node in n8n, Webhooks by Zapier, and Make's HTTP module — then send the cutout to Drive, Shopify or Airtable.

API

Shopify: Give Every Product Photo a White Background Automatically (Admin API + Background Removal API)

A script that walks your Shopify catalogue, sends each image through a background removal API with a white fill, and re-attaches the result with productCreateMedia — no app, no manual editing.

API

Bulk Background Removal via API: Async Jobs, Batches of 50 and Webhooks

How to process a catalogue of thousands of images without babysitting a script: batch submission, callbacks instead of polling, credit accounting, and what to do when the queue is full.

API

WooCommerce: Remove Product Image Backgrounds Automatically (WP-CLI Command + API)

A small mu-plugin that adds a WP-CLI command to run every WooCommerce product image through a background removal API with a white fill, save the result to the media library and set it as the product image.