ScreenshotNeo

BlogHow-to

How to Capture Screenshots of Every URL in a Google Sheet with n8n

Build an n8n workflow that reads website URLs from Google Sheets, captures each page, and saves the images to Google Drive with useful status tracking.

By the ScreenshotNeo team4 October 202610 min read

To capture screenshots for every URL in a Google Sheet with n8n, read the rows, send each URL to a screenshot service, and upload the returned image to Google Drive. For a new row at a time, start with a Google Sheets Trigger. For a sheet already containing URLs, use Google Sheets Get Row(s) and process the results in batches. A published n8n workflow demonstrates the trigger → screenshot node → Drive upload pattern with CustomJS PDF Toolkit; that community node requires self-hosted n8n. See n8n workflow templates.

This guide uses n8n’s HTTP Request node with ScreenshotNeo for the capture step, so it does not depend on installing a community node. It also explains how to use a different screenshot API, avoid common workflow failures, and optionally write results back to the sheet.

1. Prepare the Google Sheet and credentials

Use one row per page. Give the first row clear headings and keep them consistent with the field names you map in n8n.

Url Name Status Screenshot Error
https://example.com Example home

Url is the address to capture. Name is a readable filename base. The last three columns are optional, but useful when you want to track completion, store a Drive link, and record failures. Avoid duplicate or blank headings. n8n’s Google Sheets node treats the first row as headings by default. Its automatic mapping expects incoming field names to match the sheet columns, so explicitly map fields when they differ. Google Sheets node documentation.

  1. In n8n, create Google Sheets and Google Drive credentials using the credential flow supported by your n8n deployment.
  2. Create a Drive folder for screenshots and note its folder ID if the node requests it.
  3. Create a ScreenshotNeo API key at ScreenshotNeo. Store it in n8n credentials or an environment-backed secret; do not place a live key in a shared workflow export.
  4. Decide whether the workflow should handle new rows, existing rows, or both. Build separate trigger and backfill workflows if that makes reruns easier to control.

2. Build the workflow for new rows

The basic flow is:

  1. Google Sheets Trigger: select the spreadsheet and worksheet, and configure it to detect new rows.
  2. Validate row: ensure Url is present and is a usable HTTP or HTTPS URL. Keep Name for the output filename.
  3. HTTP Request: call the screenshot endpoint with the row URL and receive a binary image.
  4. Google Drive: upload the binary image to the target folder with a filename derived from Name.
  5. Optional status update: record success and the Drive link in the matching sheet row. Add a failure path that records the error.

Configure the HTTP Request node as follows. UI labels can vary slightly between n8n versions:

Setting Value
Method GET
URL https://api.screenshotneo.com/v1/shot
Query parameter access_key Your ScreenshotNeo API key, supplied as a credential or secret expression
Query parameter url The incoming row’s Url field, for example {{$json.Url}}
Response format File/binary
Binary property data (use this same property in the Drive upload node)

Do not concatenate the URL into a query string by hand. Configure query parameters as separate fields so n8n encodes special characters. Set a request timeout long enough for pages that take time to render, while keeping an upper bound so a slow page does not stall a run indefinitely. ScreenshotNeo’s API options and parameter names are documented at ScreenshotNeo API documentation.

In Google Drive’s upload node, choose the destination folder, set the input binary property to data, and construct a filename such as {{$json.Name}}.webp. If names can contain path separators or other characters your storage workflow does not accept, sanitize them first. If the capture format is changed from WebP, change the extension too.

3. Process every existing row

A trigger watches for new rows; it is not a backfill by itself. To capture rows already in the sheet:

  1. Start a workflow manually or on a schedule.
  2. Use Google Sheets Get Row(s) to retrieve rows from the chosen worksheet.
  3. Filter out rows with an empty URL and, if appropriate, rows already marked complete.
  4. Process the returned items through the same validation, HTTP Request, and Drive upload steps.
  5. Update the corresponding row with its result so a later run can safely skip completed captures.

For large lists, use batches instead of sending the whole sheet through a large simultaneous burst. Configure loop/batch processing in your n8n workflow, and select a batch size and wait interval that fit the screenshot provider’s current limits and your instance’s available memory. The research sources do not establish provider quotas or a universally safe batch size; confirm the current limits with the provider you choose.

4. Configure output and capture behavior

The screenshot endpoint returns an image file. Keep the HTTP Request response as binary all the way into Drive; converting image bytes to ordinary text or JSON will corrupt the upload. Choose a consistent image format and matching extension. ScreenshotNeo supports PNG, JPEG, and WebP, along with PDF output. Its other capture controls include full-page capture with lazy images loaded, CSS selector element capture, dark mode, device presets and custom viewport, retina scale, custom CSS and JavaScript, click-before-capture, hide selectors, wait conditions, request blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent background, resizing, and caching. Consult the API docs for parameter names and supported values before adding options to the request.

For a simple URL inventory, begin with the default capture behavior. Add waits or full-page capture only when the target pages need them. If using a different provider, map its authentication, URL parameter, output format, and binary response settings to the equivalent HTTP Request configuration. n8n’s integration guide documents calling Browserless through HTTP Request and lists screenshots in PNG, JPEG, or WebP. n8n Browserless integration. n8n also documents GetScreenshot as an API integration option. n8n GetScreenshot integration.

5. Add status tracking and safe retries

Without a status field, rerunning a workflow can produce duplicate files. For a repeatable process, use a stable identifier such as the sheet row number or a dedicated record ID, and track states such as Pending, Complete, and Failed. Write the status only after the relevant action succeeds. For example, set Complete after Drive confirms upload, and store the returned file link if available.

  • Retry transient errors: configure retries for temporary network or service errors, with a bounded attempt count and delay. Avoid unlimited retries.
  • Do not blindly retry permanent input errors: blank URLs, malformed addresses, and authentication failures need correction first.
  • Make reruns idempotent: check the status or find/update a known destination file instead of uploading another copy each run.
  • Keep failures visible: route errors to a status update or error log containing the row identifier and a short cause, without writing API keys or sensitive page data.
  • Handle partial runs: if some rows succeeded before a run stopped, use per-row status to resume the remaining work.

Google Sheets offers Append Row and Append or Update Row operations in addition to Get Row(s). When using automatic mapping, align incoming field names with the sheet headings; otherwise map columns explicitly. Google Sheets operations and mapping.

6. Alternative screenshot routes

ScreenshotNeo is the first option to try when you want a screenshot API: it removes consent banners, newsletter popups, and chat widgets before capture, and charges only for clean shots. Its paid plans start at $5 for 3,000 shots. Other routes in the research include:

  • CustomJS PDF Toolkit community node: the published n8n template uses it between a Google Sheets Trigger and Google Drive upload. The template says community nodes can only be installed on self-hosted n8n. It requires a CustomJS API key and Google credentials. Confirm current node compatibility and provider terms before adopting it. n8n workflow templates.
  • Browserless: n8n documents calling its REST API through HTTP Request and describes PNG, JPEG, or WebP screenshots. Browserless integration.
  • GetScreenshot: n8n documents calling its API through HTTP Request. GetScreenshot integration.

The cited integration pages do not establish current prices, quotas, or suitability at a particular volume. Compare authentication, supported rendering options, output handling, current rate limits, and cost using each provider’s current documentation.

7. Runnable API examples

These standalone examples capture one URL. In an automated workflow, replace the example address with the current row’s Url value and pass the resulting binary file to the Drive upload step. Keep the API key in a secret store or environment variable.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as image_file:
    image_file.write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: process.env.SCREENSHOTNEO_API_KEY,
  url: 'https://stripe.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

8. Or skip the browser setup

Use the HTTP Request node above, or make one API call for each sheet row:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API docs. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month.

9. Troubleshooting

Symptom Likely cause Fix
No workflow run for a new row Trigger is pointed at another spreadsheet or worksheet, or the row was added in a way the trigger does not detect. Check the selected document, tab, trigger event, and workflow activation. Test with a newly added row in the watched sheet.
URL is missing in the request Sheet heading differs from the mapped property, such as URL versus Url. Inspect the trigger output and use its exact property name. Align headers or map explicitly.
Bad request or invalid URL Blank cell, missing scheme, whitespace, or malformed URL. Trim and validate the value; require an http:// or https:// URL before capture.
Authentication error Missing, incorrect, or expired API key; credential expression not resolved. Check the secret and query parameter configuration. Do not expose the key in logs or exported workflow files.
Drive upload contains corrupt or empty data HTTP Request returned JSON/text instead of a file, or the Drive node reads the wrong binary property. Set response format to file/binary, inspect the binary property name, and make it match the upload node input.
Image has the wrong file type Requested output format and filename extension do not match. Choose a format explicitly where supported and set the matching extension and MIME type.
Page is blank or incomplete Page needs more rendering time, lazy-loaded content, or a different viewport; it may also be blocked or unavailable. Use an appropriate wait condition, full-page capture, or viewport. Check the response verdict and provider documentation.
Some rows finish, then execution stops Timeout, memory pressure, rate limit, or an individual slow page. Reduce batch size, bound concurrency, use retries for transient errors, and record per-row status so the run can resume.
Duplicate files after reruns Workflow always performs a new upload without checking completion. Track a stable row ID and status, then skip completed rows or update a known file.
Sheet update changes the wrong row Update mapping uses a non-unique value or mismatched columns. Use the row number or a unique ID as the match key and explicitly map the update operation.

10. Performance, reliability, and cost

Each URL requires a capture request and a storage upload, so total run time grows with the number of rows and page render time. A modest batch size limits memory use and helps avoid bursts against the screenshot service. Parallel requests can shorten elapsed time but increase resource use and the chance of hitting provider limits; set concurrency according to the current service quota and n8n deployment capacity.

Set finite request timeouts, retry only transient failures, and retain row-level outcomes. For recurring capture jobs, keep completed status and a timestamp so the workflow can distinguish a new page from a deliberate recapture. Consider whether screenshots contain personal, account, or confidential information before choosing a Drive folder and access policy.

Cost depends on the selected screenshot route, capture volume, and any storage or n8n hosting charges. The cited pages do not establish prices or quotas for CustomJS, Browserless, or GetScreenshot, so verify them directly before deploying. ScreenshotNeo’s listed plans are Free with 1,000 shots per month and no card; Starter $5 for 3,000; Growth $15 for 15,000; Pro $39 for 60,000; Scale $99 for 250,000; and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Only clean shots are billed; bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with response headers indicating the page verdict and billing status. See the docs for the current API details.

11. Frequently asked questions

Can this workflow capture a whole sheet at once?

Yes. Use Get Row(s), then process the returned rows in batches. A trigger alone handles new rows rather than acting as a backfill.

Does the CustomJS template work on n8n Cloud?

The cited template says its community node can only be installed on self-hosted n8n. The HTTP Request approach avoids that node requirement.

Can I save PDFs instead of images?

ScreenshotNeo supports PDF output. Configure the capture request and Drive filename for PDF, and confirm the returned binary data and content type before using it in production.

Can an AI agent run the screenshot workflow?

ScreenshotNeo provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The n8n sheet workflow described here uses ordinary n8n nodes and an HTTP Request.