How to schedule recurring website screenshots with Browserless
Schedule Browserless screenshots with an external trigger, a token-authenticated POST, and a plan for storing or sending each image.
To schedule recurring website screenshots with Browserless, use an external scheduler to send a token-authenticated POST request to Browserless’s /screenshot REST endpoint on your chosen cadence. Put the target URL and capture options in the JSON request body, then configure the workflow to save or deliver the returned image bytes. Browserless documents this pattern with Schedule by Zapier, a Webhooks by Zapier POST action, and an optional Gmail delivery step.
This approach fits a job that needs to capture a page on a schedule. If each run must click through a workflow or interact with the page first, use browser automation through Browserless’s browser connection options instead.
1. Choose a schedule and destination
- Get a Browserless API token. Keep it in the scheduler’s protected configuration where available; do not expose a real token in public workflow screenshots or examples.
- Choose a recurrence based on how often the page changes and how quickly you need to notice a change. Browserless’s Zapier example runs every hour; that is an example, not a recommendation for every site.
- Choose where each image should go: file or object storage, an email, or another system that accepts binary image data. Plan to include the capture time and target URL in the filename or record metadata so repeated runs are distinguishable.
- Test the request manually against the target before enabling the recurrence. Confirm that the page has finished rendering and that the returned image has the format and dimensions you expect.
2. Configure Browserless’s screenshot request
Browserless documents POST /screenshot with the token in the query string and a JSON request. The endpoint returns image data; PNG is the default, and JPEG or WebP can be selected through the screenshot options. The exact endpoint host depends on your Browserless setup. The example below uses the hosted endpoint form with a placeholder token.
POST https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN
Content-Type: application/json
{
"url": "https://example.com",
"options": {
"fullPage": true,
"type": "png"
}
}
Use the endpoint host and token supplied for your account. Keep credentials in a secret or protected field in your scheduler when supported, and avoid logging the full URL if it would expose the token.
Runnable cURL request
curl -X POST \
'https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com","options":{"fullPage":true,"type":"png"}}' \
--output screenshot.png
Replace the token and URL. The output file contains the response body, so use an extension that matches the requested image type.
Runnable Python request
import os
import requests
endpoint = "https://production-sfo.browserless.io/screenshot"
token = os.environ["BROWSERLESS_TOKEN"]
response = requests.post(
endpoint,
params={"token": token},
json={
"url": "https://example.com",
"options": {"fullPage": True, "type": "png"},
},
timeout=120,
)
response.raise_for_status()
with open("screenshot.png", "wb") as image_file:
image_file.write(response.content)
Install the dependency with python -m pip install requests. Set BROWSERLESS_TOKEN in the process environment or scheduler secret store before running.
Runnable Node.js request
const token = process.env.BROWSERLESS_TOKEN;
if (!token) throw new Error("Set BROWSERLESS_TOKEN first");
const response = await fetch(
`https://production-sfo.browserless.io/screenshot?token=${encodeURIComponent(token)}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://example.com",
options: { fullPage: true, type: "png" },
}),
},
);
if (!response.ok) {
throw new Error(`Browserless returned ${response.status}: ${await response.text()}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) => writeFile("screenshot.png", image));
This uses the Node.js built-in fetch available in current Node releases. In a scheduler, send the response bytes to its configured storage or delivery step instead of writing to a local file.
3. Set capture behavior for the page
Browserless’s screenshot options cover the main differences between a quick viewport capture and a useful recurring record:
| Need | Request setting or approach | When to use it |
|---|---|---|
| Capture the whole document | fullPage: true |
Useful for pages whose content extends below the initial viewport. |
| Choose output | type such as PNG, JPEG, or WebP |
Use PNG for lossless detail; JPEG or WebP may reduce stored file size, depending on image content and quality settings. |
| Control lossy output | Image quality option | Relevant to JPEG or WebP; verify that text and visual details remain readable. |
| Capture a region | Clip coordinates and dimensions | Use when only a fixed part of the page matters. |
| Set page size | Viewport dimensions and device scale factor | Keep these fixed across runs if you intend to compare screenshots consistently. |
| Capture a specific element | Element selector, optionally with a wait for that selector | Useful for a chart, product panel, or other region identified in the page DOM. |
| Wait for dynamic content | Wait for an event, function, selector, or timeout; navigation behavior can also be adjusted | Use a readiness condition that reflects the actual content you need to capture. |
| Load lazy content | scrollPage: true, with full-page capture as appropriate |
Scrolling can trigger lazy-loaded images and elements; the result depends on the target page’s behavior. |
Check Browserless’s screenshot API documentation for the current request schema and option names before adding less common settings. Keep the viewport, scale, wait condition, and capture region stable between runs if the goal is visual comparison; changing these can make screenshots differ even when the page itself has not changed.
4. Build the recurring workflow in Zapier
- Create a Zap with the documented Schedule by Zapier trigger and choose a recurrence. The Browserless example uses an hourly schedule.
- Add a Webhooks by Zapier action configured as a POST to the Browserless
/screenshotendpoint. Put the token in the query string in a protected configuration field if the platform supports it. - Set the request body to JSON and include the page URL and screenshot options. The documented example requests a full-page PNG.
- Add a step to handle the response. Browserless’s template demonstrates Gmail as an optional way to deliver the image; adapt the step to the storage or notification service you use.
- Run a test and inspect the actual output. Verify that the image is attached or stored as binary data rather than as a text rendering of the response, and confirm the content type and file extension agree.
- Enable the recurrence and monitor initial runs for timing, page readiness, and delivery behavior.
Automation platforms differ in how they pass binary HTTP response bodies between steps. If your chosen webhook action cannot preserve the response as a file, use a small scheduled script or a separate storage step that accepts the bytes.
5. Handle page readiness and lazy-loaded content
A scheduled trigger does not make a page ready for capture. Pages can render important content after navigation, fetch data asynchronously, or load images only when scrolled into view. Browserless documents waits based on events, functions, selectors, and timeouts, plus navigation controls and scrolling for lazy content.
- Prefer a selector or page condition tied to the content you need when the page exposes one reliably.
- Use a timeout as a bounded fallback, not as proof the page has finished loading.
- For long pages with lazy images, try scrolling before full-page capture and inspect the result for missing sections.
- Use a fixed viewport and device scale factor to make successive captures comparable.
- If the site changes unpredictably, capture a known stable element or region rather than relying only on a full-page screenshot.
6. Save, label, and retain each image
Recurring captures are only useful if you can find the right run later. Use a filename or storage key that includes a timestamp and a safe identifier for the page, such as example-com/2026-10-04T1200Z.png. Avoid putting secrets or sensitive query parameters in object names, notification subjects, or logs.
Decide how long to retain images and whether every scheduled run needs to be kept. Full-page PNGs can consume more storage than compressed formats; selecting JPEG or WebP and a suitable quality can reduce storage where lossy output is acceptable. Browserless’s cited documentation does not provide a comparative storage, performance, or pricing benchmark, so estimate from your own target pages and retention needs.
7. Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| Unauthorized response | Missing, invalid, or incorrectly passed token. | Check the account token, endpoint host, and query parameter. Ensure the scheduler did not strip or encode the token incorrectly. |
| Request rejected | Malformed JSON, wrong content type, or unsupported option name/value. | Send Content-Type: application/json, validate the JSON, and compare option names with the current API reference. |
| Blank or white image | The target may still be loading, may have failed navigation, or may be blocking automation. | Check the target URL in a browser, add an appropriate wait, and inspect whether the page displays a challenge or access-denied state. |
| CAPTCHA, 403, or access denied | The target site may block automated browsing. | Browserless points to its separate /unblock API for some anti-bot cases. It is a possible route, not a guarantee that every target can be captured. |
| Missing images or lower-page sections | Lazy-loaded content was not triggered, or capture occurred before content appeared. | Try page scrolling, full-page capture, and a selector or other readiness wait; then inspect the resulting image. |
| Element capture is empty or wrong | The selector did not match, matched a hidden element, or the element appeared after capture. | Confirm the selector on the live page and wait for it before taking the screenshot. |
| Image is saved as unreadable text or has the wrong extension | The workflow treated the binary response as text, or the selected format and filename do not match. | Preserve the response body as binary data and align the file extension with the requested image type. |
| Intermittent timeouts | The target is slow or the readiness condition waits too long. | Use a bounded timeout, choose a more specific readiness condition, and review whether the page can be captured without loading unnecessary resources. |
8. Reliability, performance, and cost considerations
- Schedule deliberately: choose a cadence that matches the monitoring need. More frequent schedules create more capture jobs and more image data to route and retain.
- Bound each run: set an appropriate request timeout and use bounded page waits so a slow page does not leave the workflow hanging indefinitely.
- Make retries safe: if a scheduler retries after an uncertain delivery, use a run timestamp or execution identifier in storage naming so duplicate attempts can be identified.
- Separate capture from notification: when practical, retain the returned image first and send a link or notification afterward. This makes a delivery failure easier to recover without recapturing the page.
- Protect the token: the documented authentication pattern places the token in the endpoint query string. Keep it in protected workflow configuration and avoid exposing request URLs in public logs or screenshots.
- Estimate costs from actual usage: count scheduled runs, any retries, and any additional interaction steps. Browserless’s cited sources do not establish a performance comparison or cost benchmark, so check your account’s current plan and measure the needs of your own workflow.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP, or PDF. Its consent handling accepts cookie banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
For the full option list and request details, see the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Use the returned image bytes as the output for your scheduler’s storage or notification step. Sign up for 1,000 free screenshots a month with no card.
FAQ
Can Browserless send a screenshot on a schedule by itself?
The documented workflow uses an external scheduler to trigger the screenshot request. The schedule is configured in the automation platform.
Does the screenshot endpoint return a file or a URL?
It returns image data in the HTTP response. Configure the next workflow step to preserve and store or deliver that binary response.
Should I use REST or a browser connection?
Use the REST screenshot request for a scheduled capture that needs no page interaction. Browserless documents WebSocket access for direct CDP, Playwright, or Puppeteer automation when the workflow must interact with the page first.
Will every target site work?
No guarantee is documented. Blank captures, CAPTCHA pages, access-denied responses, or missing elements can indicate that the site is blocking automation.


