Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallTo bulk screenshot URLs from Google Sheets, use the sheet as a queue, Apps Script to read and update rows, and a website screenshot API to render each page. Apps Script can make HTTP requests, but it is not itself a browser renderer. The workflow below validates URLs, sends captures in batches, records results against their source rows, and can resume after an execution limit.
How the workflow fits together
Each part has a distinct role:
- Google Sheets stores the input URLs and output status or screenshot references.
- Apps Script reads rows, sends HTTP requests, handles responses, and writes results back.
- A screenshot API opens each target page in a browser and returns an image, a URL to an image, or a job reference.
Google describes UrlFetchApp as a service for communicating with other applications or accessing web resources by fetching URLs. It supports individual requests with fetch() and multiple requests with fetchAll(). Those requests originate from Google IP ranges, which may matter if a destination restricts incoming traffic.
As an Amazon Associate I earn from qualifying purchases.
Use a provider’s documented response format and limits; do not assume that every service returns image bytes or accepts the same batch size. One vendor’s documentation describes POST /api/v1/screenshot/batch as accepting multiple URLs and returning a batch ID, but that is a provider-specific contract, not a universal API standard.
Free tools Windows power users keep installed
One-click scans. No signup required.
Set up the sheet
Choose columns for inputs and results
Create a sheet with one URL per row and reserve columns for the screenshot reference, status, and error details. For example:
#1 Best Overall
- PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
- QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
- VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
- INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
- EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0
| Column | Purpose | Example |
|---|---|---|
| A | Source URL | https://example.com/page |
| B | Screenshot reference | Image URL, file reference, or job ID |
| C | Status | OK, HTTP error, invalid URL |
| D | Error details | HTTP status or provider message |
Keep the original URL in the same row as its result. If you process only a portion of the sheet, retain the row number or another stable identifier when mapping results back.
Enable URL Fetch permissions
Apps Script’s URL Fetch service requires the script.external_request scope when a project sets OAuth scopes explicitly. A script using the Spreadsheet service also needs authorization to access the spreadsheet. Review the requested permissions before authorizing.
Apps Script example: send URL rows to a screenshot API
The following template reads a URL column once, validates the rows, issues concurrent requests with fetchAll(), and writes a rectangular result range in one operation. Replace the endpoint, authentication, request payload, and success-response parsing with the screenshot provider’s documented contract. The template expects a JSON response containing an image_url; adjust parseScreenshotUrl if the service returns bytes, a job ID, or a different field.
Set API_ENDPOINT and API_KEY in the script. Keep secrets out of cells that are shared with spreadsheet users; for a production script, use an appropriate protected secret store such as Apps Script Properties and restrict project access.
const SHEET_NAME = 'Sheet1';
const FIRST_DATA_ROW = 2;
const URL_COLUMN = 1; // A
const OUTPUT_COLUMN = 2; // B: screenshot reference
const STATUS_COLUMN = 3; // C
const ERROR_COLUMN = 4; // D
const CHUNK_SIZE = 10; // Conservative starting point; tune to provider limits and response times
const API_ENDPOINT = 'https://api.example.com/screenshot';
const API_KEY = 'YOUR_API_KEY';
function captureNextChunk() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) throw new Error('Sheet not found: ' + SHEET_NAME);
const lastRow = sheet.getLastRow();
if (lastRow < FIRST_DATA_ROW) return;
// Read inputs and existing statuses in rectangular ranges, not cell by cell.
const rowCount = lastRow - FIRST_DATA_ROW + 1;
const urls = sheet.getRange(FIRST_DATA_ROW, URL_COLUMN, rowCount, 1).getDisplayValues();
const existing = sheet.getRange(FIRST_DATA_ROW, STATUS_COLUMN, rowCount, 1).getDisplayValues();
const startIndex = findNextPendingIndex_(urls, existing);
if (startIndex === -1) return;
const selected = [];
for (let i = startIndex; i < urls.length && selected.length < CHUNK_SIZE; i++) {
const url = String(urls[i][0]).trim();
const status = String(existing[i][0]).trim();
if (!url || status === 'OK') continue;
if (!isHttpUrl_(url)) {
selected.push({ index: i, url: url, invalid: true });
} else {
selected.push({ index: i, url: url, invalid: false });
}
}
if (!selected.length) return;
const requests = selected.filter(item => !item.invalid).map(item => ({
url: API_ENDPOINT,
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + API_KEY },
payload: JSON.stringify({ url: item.url }),
muteHttpExceptions: true
}));
let responseIndex = 0;
const results = selected.map(item => {
if (item.invalid) {
return { index: item.index, image: '', status: 'Invalid URL', error: 'Enter a URL beginning with http:// or https://' };
}
const response = responses[responseIndex++];
const code = response.getResponseCode();
const body = response.getContentText();
if (code < 200 || code >= 300) {
return { index: item.index, image: '', status: 'HTTP error', error: 'HTTP ' + code + ': ' + body.slice(0, 500) };
}
try {
const image = parseScreenshotUrl(body);
if (!image) throw new Error('No screenshot reference in response');
return { index: item.index, image: image, status: 'OK', error: '' };
} catch (e) {
return { index: item.index, image: '', status: 'Parse error', error: String(e) };
}
});
// Write each contiguous output range in one call, preserving row alignment.
const output = Array.from({ length: rowCount }, () => ['', '', '']);
results.forEach(result => {
output[result.index] = [result.image, result.status, result.error];
});
// This example writes only the selected rows, grouped into contiguous runs.
writeSelectedResults_(sheet, results, OUTPUT_COLUMN);
}
function findNextPendingIndex_(urls, statuses) {
for (let i = 0; i < urls.length; i++) {
if (String(urls[i][0]).trim() && String(statuses[i][0]).trim() !== 'OK') return i;
}
return -1;
}
function isHttpUrl_(value) {
return /^https?://[^s]+$/i.test(value);
}
function parseScreenshotUrl_(body) {
const data = JSON.parse(body);
return data.image_url || '';
}
function writeSelectedResults_(sheet, results, firstColumn) {
if (!results.length) return;
// The results may be non-contiguous if blank or completed rows were skipped.
// Group adjacent rows so each group can be written as one rectangular range.
const sorted = results.slice().sort((a, b) => a.index - b.index);
let group = [sorted[0]];
const flush = () => {
const firstRow = FIRST_DATA_ROW + group[0].index;
const values = group.map(r => [r.image, r.status, r.error]);
sheet.getRange(firstRow, firstColumn, values.length, 3).setValues(values);
};
for (let i = 1; i < sorted.length; i++) {
if (sorted[i].index === sorted[i - 1].index + 1) group.push(sorted[i]);
else { flush(); group = [sorted[i]]; }
}
flush();
}
Important correction before running: the code above needs a response array declared after the request list. Add this line immediately after the requests definition and before let responseIndex = 0;:
Rank #2
- FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
- ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
- READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
- WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
- OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)
const responses = requests.length ? UrlFetchApp.fetchAll(requests) : [];
Alternatively, to make the flow simpler, place that declaration directly after the closing ]; of the request mapping. When adapting the snippet, keep the request-to-response order consistent: invalid URLs do not generate requests, so only valid entries advance responseIndex.
Make the response match your provider
Some services return an image URL; others return image bytes or a batch/job identifier. If a response is asynchronous, store its batch ID in the row and add a separate polling step that retrieves completion results according to the provider’s documented workflow. If the API returns private image bytes, a URL-based sheet image insertion method may not be suitable. Google’s Spreadsheet service documentation says URL-based image insertion requires a publicly accessible URL.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Apps Script Range methods read and write rectangular arrays. Reading the input range once and writing results as arrays avoids making a spreadsheet service call for every cell. Google documents these range operations in the Range reference.
Choose a request pattern and keep the run resumable
One request per URL
A single fetch() per row is easiest to reason about, but a large sequential queue can take longer than one Apps Script run permits. Use it when the queue is small, or when you need strict per-request pacing to meet a provider’s rate limit.
Several requests with fetchAll()
fetchAll() sends multiple requests from the script. It can reduce client-side coordination for a group of URLs, but it does not remove provider rate limits, guarantee faster rendering, or change the provider’s response contract. Start with a modest chunk, monitor actual runtimes and failures, and adjust within the service’s documented limits. No universal safe chunk size is established.
Rank #3
- FAST DOCUMENT SCANNING — Document scanner with feeder allows you to speed through stacks with a 50-sheet Auto Document Feeder (ADF); Efficient office scanner to help you scan more productively
- INTUITIVE, HIGH-SPEED SOFTWARE — Quickly scan with this desktop document scanner; Epson ScanSmart Software lets you easily preview scans, email files, upload to the cloud, and more; Plus, automatic file naming saves even more time
- SEAMLESS INTEGRATION — Easily incorporate your data into most document management software with the included TWAIN driver; Office document scanner integrates seamlessly with business workflows
- EASY SHARING — Duplex scanner allows you to scan straight to email or popular cloud storage2 services like Dropbox, Evernote, Google Drive, and OneDrive for simple storage and sharing
- SIMPLE FILE MANAGEMENT — Scanner allows the creation of searchable PDFs with Optical Character Recognition (OCR) and convert scans to editable Word or Excel files effortlessly; Designed for home and office document scanning
A provider’s batch endpoint
A documented batch endpoint can accept multiple URLs and return a batch ID, reducing the need to submit one client request per target. Confirm the maximum URLs per job, whether processing is synchronous, how results are retrieved, image retention, rate limits, and error mapping. A batch ID is not itself a screenshot; the script must retrieve the completed results and associate them with their original rows.
Resume rather than restarting
Apps Script documents a six-minute maximum execution time per run. Process a manageable chunk, write each result promptly, and then run again or schedule a continuation. Treat row status as the completion marker, and distinguish permanent errors such as an invalid URL from retryable failures such as timeouts or temporary server errors. Avoid marking a row complete until the screenshot result has been stored successfully.
Quotas, reliability, and costs to check
Google’s current Apps Script quotas documentation, accessed in 2026, lists these URL Fetch and runtime figures. Google says quotas vary by account class and can change without notice; they are documentation values, not a promise that an individual project will receive a particular throughput.
| Apps Script limit | Consumer account | Workspace account |
|---|---|---|
| URL Fetch calls per day | 20,000 | 100,000 |
| Maximum runtime per execution | 6 minutes | 6 minutes |
Google notes that quotas reset 24 hours after the first request. Rendering time, the screenshot provider’s limits, and retries also affect how many rows a run can finish; API call quotas alone do not predict completion time.
If you use the Sheets API rather than SpreadsheetApp, its separate documented quotas are 300 read requests per minute per project and 60 per minute per user per project, with the same figures for writes. These are Sheets API quotas, not URL Fetch limits. For HTTP 429 quota responses, Google advises an exponential backoff algorithm.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesRank #4
- Scanner type: Document
- Connectivity technology: USB
- With Auto Scan Mode, the scanner automatically detects what you're scanning
- Digitize documents and images
Budget for the provider’s charging rules, not merely the number of rows. Check whether failed captures, cache hits, retries, or asynchronous jobs are billable, and whether the returned image remains available long enough for your workflow. Also confirm privacy and data handling before sending sensitive URLs or page content to a third party.
India-specific considerations
The Apps Script workflow is broadly usable, but the available evidence does not establish a screenshot provider’s India-specific availability, pricing, payment support, data location, or API latency. Before relying on a service for a production workflow in India, verify its current terms, billing support, regional availability, data handling, and rate limits directly. Google documents that UrlFetch requests originate from Google IP ranges, which can matter where destination sites apply network restrictions.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting
Authorization or scope errors
Cause: the script lacks permission for external requests, spreadsheet access, or an explicitly configured OAuth scope. Fix: authorize the required scopes and include script.external_request when manually setting scopes.
HTTP errors or empty results
Cause: the API key, endpoint, payload shape, provider quota, or target URL may be wrong; the response may also be an asynchronous job reference rather than an image URL. Fix: inspect the HTTP status and response body, compare the request with the provider’s API documentation, and record the provider error in the row. Using muteHttpExceptions: true lets the script inspect non-2xx responses instead of stopping at the HTTP error.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →CAPTCHA, blocked page, or unexpected screenshot
Cause: the target site may block automated traffic, require a login, or render differently from a normal visitor session. Apps Script requests originate from Google IP ranges. Fix: check the provider’s browser, cookie, wait, and authentication options and the target site’s access rules. Do not assume adding retries will resolve deliberate bot blocking.
Best Value
- OUR MOST ADVANCED SCANSNAP. Large touchscreen, fast 45ppm double-sided scanning, 100-sheet document feeder, Wi-Fi and USB connectivity, automatic optimizations, and support for cloud services. Upgraded replacement for the discontinued iX1600
- CUSTOMIZABLE. SHARABLE. Select personalized profiles from the touchscreen. Send to PC, Mac, mobile devices, and clouds. QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
- STABLE WIRELESS OR USB CONNECTION. Built-in Wi-Fi 6 for the fastest and most secure scanning. Connect to smart devices or cloud services without a computer. USB-C connection also available
- PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. Easily manage, edit, and use scanned data from documents, receipts, photos, and business cards. Automatically optimize, name, and sort files
- AVOIDS PAPER JAMS AND DAMAGE. Features a brake roller system to feed paper smoothly, a multi-feed sensor that detects pages stuck together, and skew detection to prevent paper damage and data loss
Script stops before the queue is finished
Cause: the execution reaches the six-minute limit, or the daily URL Fetch quota is exhausted. Fix: reduce the chunk size, persist results after each chunk, and resume from rows not marked complete. Check quota status and avoid uncontrolled retries.
HTTP 429 from the Sheets API
Cause: the script exceeds the Sheets API request quota. Fix: combine reads and writes into range operations and apply exponential backoff to quota responses, as Google recommends. This applies to the Sheets API; it is separate from Apps Script URL Fetch quotas.
Image does not display in the sheet
Cause: the result may be private, temporary, or returned as bytes instead of a public image URL. Fix: follow the provider’s documented image-delivery method. A URL-based Spreadsheet image insertion method requires a publicly accessible URL; do not expose a private API key or assume a signed/private response can be inserted directly.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It returns a screenshot or PDF through a request, and the API can be called from Apps Script. For bulk work, submit requests in controlled chunks and write the returned result or error beside each source URL. See the ScreenshotNeo API documentation for current parameters and response details.
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
For Apps Script, use UrlFetchApp.fetch() or fetchAll() with the API URL and parameters, then handle the returned image or error according to the API documentation. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
Frequently Asked Questions
Can Apps Script take a website screenshot without a screenshot API?
No. Apps Script can send HTTP requests, but browser rendering and screenshot creation must be provided by another service or browser environment.
Can I insert an API’s returned screenshot directly into Google Sheets?
Only if the returned format works with the insertion method you choose. URL-based image insertion requires a publicly accessible image URL; private bytes or protected links need a different storage or display approach.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




