How to Capture a Website Screenshot with PagePeeker from Google Sheets
Generate PagePeeker thumbnails from URLs in Google Sheets, display them in cells or over the grid, and manage encoding, quotas, and capture delays.
To capture website screenshots from Google Sheets with PagePeeker, put each page URL in a cell, build a PagePeeker V2 thumbnail URL with the page URL encoded, then display that image URL in the sheet. PagePeeker renders the page; Google Sheets displays the returned thumbnail. A formula does not take the screenshot itself.
1. Build a PagePeeker thumbnail URL
PagePeeker recommends its V2 API. The documented URL pattern is http://{entrypoint}.pagepeeker.com/v2/thumbs.php?size={size}&url={url}. For the no-signup branded free endpoint, use free as the entrypoint:
http://free.pagepeeker.com/v2/thumbs.php?size=m&url=https%3A%2F%2Fexample.com
The example URL illustrates the format; it does not claim a capture was tested. Keep the original page URL in one column and the generated thumbnail URL in another so you can inspect encoding or service errors.
Thumbnail sizes
| Size | Dimensions |
|---|---|
t |
90 × 68 |
s |
120 × 90 |
m |
200 × 150 |
l |
400 × 300 |
x |
480 × 360 |
2. Put source URLs in the sheet
Use a simple layout such as:
| A | B | C |
|---|---|---|
| Page URL | Thumbnail URL | Preview |
https://example.com |
Generated URL | Image |
In an Apps Script cell, construct the URL using JavaScript’s encodeURIComponent; this correctly encodes query characters in the source URL, including ampersands and fragments.
3. Display the thumbnail in Google Sheets
There are two placement choices: a cell image value, or an image floating over the grid. Google’s Apps Script reference documents both.
Option A: Make a cell image value
This script reads URLs from column A, creates PagePeeker thumbnail URLs, and writes image values to column B. Change lastRow handling or the source column if your sheet has a different layout.
function addPagePeekerCellImages() {
const sheet = SpreadsheetApp.getActiveSheet();
const firstDataRow = 2;
const lastRow = sheet.getLastRow();
if (lastRow < firstDataRow) return;
const urls = sheet.getRange(firstDataRow, 1, lastRow - firstDataRow + 1, 1).getValues();
const cellImages = urls.map(([pageUrl]) => {
if (!pageUrl) return [""];
const thumbnailUrl = "http://free.pagepeeker.com/v2/thumbs.php?size=m&url=" +
encodeURIComponent(String(pageUrl).trim());
return [SpreadsheetApp.newCellImage().setSourceUrl(thumbnailUrl).build()];
});
sheet.getRange(firstDataRow, 2, cellImages.length, 1).setValues(cellImages);
}
This uses the Apps Script SpreadsheetApp.newCellImage().setSourceUrl(url).build() cell-image API. Confirm the current editor’s support and behavior for cell image values in your spreadsheet before relying on it for a production workflow.
Option B: Insert images over the grid
Use Sheet.insertImage(url, column, row) to place an image over the sheet grid. The URL must be publicly accessible. This method positions images by column and row; it does not create a cell value.
function insertPagePeekerImagesOverGrid() {
const sheet = SpreadsheetApp.getActiveSheet();
const firstDataRow = 2;
const lastRow = sheet.getLastRow();
if (lastRow < firstDataRow) return;
const urls = sheet.getRange(firstDataRow, 1, lastRow - firstDataRow + 1, 1).getValues();
urls.forEach(([pageUrl], index) => {
if (!pageUrl) return;
const thumbnailUrl = "http://free.pagepeeker.com/v2/thumbs.php?size=m&url=" +
encodeURIComponent(String(pageUrl).trim());
sheet.insertImage(thumbnailUrl, 2, firstDataRow + index);
});
}
Google documents a 2 MB maximum for blob-based image insertion. The URL-based insertion method above uses a public URL; the blob size limit is relevant if you change the script to fetch the image as a blob instead.
Formula-based layouts
A sheet formula can display a remote image when given an image URL, but the exact formula syntax and mode can vary with the current Sheets editor. The Apps Script references cited here establish the script methods above; check the current Sheets editor’s help for formula syntax if you prefer formulas. In either layout, the external screenshot service generates the image.
4. Account for refreshes, readiness, and quotas
PagePeeker counts displaying cached thumbnails, creating thumbnails, readiness checks, and other API calls toward its API-call usage. Recalculating many rows or polling readiness repeatedly can use quota even when a render is not created on each call.
- For ordinary lists, generate the thumbnail URL once and avoid repeatedly rewriting or polling every row.
- PagePeeker documents optional premium
refreshandwaitparameters. Use refresh when you specifically need a new capture; use wait when you need the request to wait for thumbnail generation, up to the requested number of seconds. - For asynchronous workflows, its readiness endpoint returns JSON including
ErrorandIsReady. Poll at a measured interval and stop after a reasonable number of attempts. - A cached thumbnail is still an API call when displayed, according to PagePeeker’s FAQ.
The free branded endpoint requires no signup and includes PagePeeker branding. The free unbranded option requires a link back and is listed with 100,000 monthly calls. The provider lists 20-day caching for free tiers. Published paid terms at research time were Basic at $5.99/month for 100,000 API calls and Advanced at $39.99/month for 1,000,000 calls; pricing and plan details can change, so confirm the current plan table before budgeting.
PagePeeker publishes typical rendering times of 30–60 seconds for branded free, 10–20 seconds for unbranded free, 10–20 seconds for paid Basic, and 5–15 seconds for paid Advanced. These are provider-stated typical figures, not independent benchmarks. The listed cache periods are 20 days on free tiers, 7 days on Basic, and 5 days on Advanced.
5. Protect credentials and respect site restrictions
The API documentation says an account code is optional for client-side direct linking, but warns against exposing it on client-side pages because others could spend the account’s quota. Do not put an authenticated paid URL into a shared sheet or formula. Restrict access to the spreadsheet and keep any credentials in a server-side service you control if your workflow requires them.
PagePeeker documents that its robot may be blocked by a site’s robots.txt. Its guidance shows this rule as a way to block capture:
User-agent: PagePeeker
Disallow: /
Some sites also present bot checks or otherwise prevent automated access. A thumbnail workflow cannot guarantee capture of every website.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Image does not appear | The thumbnail URL is malformed, the source URL was not encoded, or the capture is not ready. | Open the generated thumbnail URL directly and check that the page URL is encoded as one parameter value. For delayed renders, use the documented wait option or readiness endpoint. |
| Only the first part of a URL is captured | Characters such as & in the page URL were treated as query separators. |
Encode the entire source URL with encodeURIComponent before appending it to the PagePeeker URL. |
| A page never becomes ready | The page may block PagePeeker’s robot, require interaction, or fail to load. | Check the site’s robots rules and try a permitted, publicly reachable URL. Do not assume every site can be captured. |
| Quota is used faster than expected | Image displays, cache hits, render creation, readiness checks, and other API calls count. | Reduce repeated recalculation and readiness polling; estimate calls based on sheet refresh behavior, not only the number of unique URLs. |
| Paid account usage appears unexpectedly | An account code in a shared URL may have been reused by others. | Remove exposed codes, limit sheet access, and avoid placing account credentials in client-visible formulas. |
| Over-grid insertion fails | The image URL is not publicly accessible or the target data range is wrong. | Verify the URL can be accessed publicly and check row and column indexes. Use cell-image values if an image should live in a cell. |
7. Performance and reliability choices
- Batch size: process only rows that contain URLs. Large sheets can trigger many separate image displays or script insertions; work in bounded batches if execution time becomes an issue.
- Freshness: cached thumbnails reduce repeated rendering, but the displayed result can be older than the source page. Use the documented refresh parameter only when freshness matters and account for the call.
- Readiness: renders can take seconds or longer according to the provider’s published typical ranges. Avoid tight polling loops; use a wait request or spaced readiness checks where appropriate.
- Failure handling: preserve the original URL and thumbnail URL in separate columns so you can retry a failed row without rebuilding the whole list.
- Access: URL-based insertion requires a publicly accessible image URL. An image that loads in your browser may not be reachable to Apps Script or Sheets under the same conditions.
Or skip the browser setup
ScreenshotNeo is a screenshot API and MCP server for developers. Send one request with a URL to get a PNG, JPEG, WebP, or PDF. Cookie banners, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed, and response headers say the page verdict and billing status. AI agents can use its MCP tools: take_screenshot, get_page_info, and capture_pdf.
For a spreadsheet workflow, your script can request an image and then place it in the sheet. This example saves the returned bytes as a WebP file; see the ScreenshotNeo API documentation for request options and formats.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000 screenshots. Every feature is available on every plan. Sign up for the free plan.
FAQ
Does Google Sheets capture the webpage?
No. PagePeeker captures the page and returns a thumbnail URL; Sheets displays that image.
Can I use PagePeeker without signing up?
The branded free endpoint is offered without signup. Other tiers have their own terms and quotas.
Can PagePeeker capture any URL?
No. Site robot rules, bot checks, access restrictions, and page load failures can prevent a capture.
Should I use a cell image or an over-grid image?
Use a cell image when the preview should be a value associated with that row. Use over-grid insertion when you need a floating image positioned on the sheet.
Will a cached thumbnail be free to display?
PagePeeker says displaying a cached thumbnail counts as an API call, so include repeated displays in your quota estimate.


