Use cases
Every client site, checked every day
Console errors, Lighthouse scores and a screenshot for each page you look after — and a bill you can split by client.
By Roger Campos · Last updated: September 2026
TL;DR
To monitor client websites from outside, load each key page on a schedule and record its JavaScript errors, Lighthouse scores and a screenshot. URLpipe does all three from one /scrape request with nothing installed on the client's site, and a label per client splits your usage so you can bill each one for exactly what their checks spent.
Free plan, no credit card. 1,000 credits a month.
The job
The job, as an agency sees it
You look after forty sites you did not all build. A plugin update breaks the checkout's JavaScript on a Saturday; a new hero image doubles the LCP; a cookie banner starts covering the menu on mobile. You find out when the client calls. The fix is a daily check from outside, on the pages that matter, with nothing to install on anyone's server.
- /console —
console.error,console.warn, uncaught exceptions and unhandled promise rejections from the page as it loads. 1 credit. Plainconsole.logis not captured. - /lighthouse — a real Lighthouse audit: performance, accessibility, best practices and SEO scores, plus LCP, CLS, TBT and FCP. 2 credits.
- /screenshot — the full page as a browser draws it, to compare week on week. 1 credit.
Accounting
Label every request with its client
Labels are your own ids on a request — up to 16 keys, like {"client": "acme", "page": "checkout"}. They come back in every result and webhook, so your handler routes each result to the right client without a lookup table. The project's Labels page totals requests, failures and credits for each value, a calendar month at a time, and shows what unlabelled requests spent — so the per-client figures add up to the invoice.
Labels cost nothing and are not part of the cache key: two clients who share a page each see their own labels on a single stored result.
Flow
One request per page, end to end
- 1Keep a list of pages per client: home, a product page, the checkout, the contact form.
- 2Each morning, send one
/scrapeper page withconsole,lighthouseandscreenshot, async, labelled with the client. Lighthouse runs its own instrumented page load beside the shared visit, so async is the right mode — audits often outlast the 60-second sync window. - 3Your webhook stores the three results against the client and page, and compares them with yesterday's: new console errors, a performance score that fell by more than your threshold, a screenshot that changed.
- 4At the month's end, the Labels page gives you each client's credits for the invoice.
curl -X POST https://urlpipe.dev/scrape \
-H "Authorization: Bearer $URLPIPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://acme-shop.example/checkout",
"operations": ["console", "lighthouse", "screenshot"],
"device": "mobile",
"screenshot_options": {"format": "webp"},
"report_to": "https://agency.example/hooks/urlpipe",
"labels": {"client": "acme", "page": "checkout"}
}'import os, requests
SITES = {
"acme": ["https://acme-shop.example/", "https://acme-shop.example/checkout"],
"brightside": ["https://brightside.example/", "https://brightside.example/book"],
}
for client, pages in SITES.items():
for url in pages:
requests.post("https://urlpipe.dev/scrape",
headers={"Authorization": f"Bearer {os.environ['URLPIPE_API_KEY']}"},
json={
"url": url,
"operations": ["console", "lighthouse", "screenshot"],
"device": "mobile",
"screenshot_options": {"format": "webp"},
"report_to": "https://agency.example/hooks/urlpipe",
"labels": {"client": client, "page": url},
}, timeout=30).raise_for_status()// In the webhook: compare today's results with yesterday's
export function regressions(today, yesterday) {
const ops = today.result.operations;
const found = [];
const errors = ops.console.success ? ops.console.result : [];
const known = new Set((yesterday?.console ?? []).map((m) => m.text));
for (const m of errors) {
if (m.type !== "warning" && !known.has(m.text)) found.push(`New ${m.type}: ${m.text}`);
}
const perf = ops.lighthouse.success
? ops.lighthouse.result.categories.performance.score : null;
if (perf !== null && yesterday?.performance - perf >= 0.1) {
found.push(`Performance fell from ${yesterday.performance} to ${perf}`);
}
return { client: today.labels.client, page: today.labels.page, found };
}Keep no more checks in flight than your plan's parallel limit — 3 on Starter, 8 on Pro, 20 on Scale — and remember the API allows 60 requests a minute per project. Forty clients' worth of pages is a short queue, not a problem.
Responsibility
robots.txt, and whose call it is
Every project follows the robots.txt of the sites it fetches by default: a page the file disallows is not fetched, the request fails with a reason, and it costs nothing. A client's staging site that disallows everything will do exactly that.
Each project can turn this off in its Settings. When you do, having the right to fetch those pages and use what comes back is your responsibility. For sites your clients own and have asked you to monitor, that is usually a line in the contract — put it there. Keep client monitoring in its own project so the setting applies only where you have that permission.
Credits
What it costs
Forty clients, five pages each, checked every day, with a weekly screenshot, at list price:
| What | A month | Credits each | Credits |
|---|---|---|---|
| Console check, daily, 200 pages | 6,000 | 1 | 6,000 |
| Mobile Lighthouse audit, daily, 200 pages | 6,000 | 2 | 12,000 |
| Full-page screenshot, weekly, 200 pages | 800 | 1 | 800 |
18,800 credits; the cheapest plan that covers it is Starter: $19 a month for 20,000 credits. A desktop audit as well as a mobile one doubles the Lighthouse row, since the two are cached and billed separately. A failed check — a site that was down, a page robots.txt disallowed — costs nothing.
Limits
What URLpipe does not do for monitoring
- Schedule or alert. You run the cron and decide what counts as a regression. URLpipe returns the data.
- Uptime. This is a page check a few times a day, not a ping every minute.
- Field data. Lighthouse is a lab test. INP needs real users; TBT is the lab stand-in.
- Capture everything the console shows.
console.logis not captured, and scripts inside embedded frames log to their own console. - Write the report. For a monitored, client-ready audit report rather than the raw JSON, Full Stack Audit is our sister product that does exactly that.
Endpoints
The endpoints on this page
- Check any website for JavaScript errors
Paste a link and see the console errors, warnings and uncaught exceptions logged while the page loads in a real browser — no DevTools, no local setup.
Try it free - Run a Lighthouse audit on any URL
Paste a link and get a real Google Lighthouse audit — performance, accessibility, best practices and SEO scores, plus Core Web Vitals — measured against the live page.
Try it free - Screenshot any website from its URL
Paste a link and get a full-page PNG of the rendered page — JavaScript executed, exactly as a real browser would draw it. Great for previews, monitoring and visual QA.
Try it free
FAQ
Frequently asked questions
Do I need to install anything on client sites?
How do I bill each client for their share?
Can I monitor pages that disallow bots in robots.txt?
Why is Lighthouse slower than the other checks?
Does it catch failed image or script loads?
Build it on the free plan.
Free plan, no card. Confirm your email and your API key is live — you'll be making real requests in minutes.