Console API
Find JavaScript errors on any site, with nothing installed
The browser console of any public page, as JSON — for sites you don't control, pages you can't add an SDK to, and checks you want to run from outside.
By Roger Campos · Last updated: September 2026
TL;DR
POST a URL to /console and get back what the page's JavaScript reported while it loaded: console.error calls, console.warn calls, uncaught exceptions and unhandled promise rejections, as a JSON array. The page is loaded in real Chrome, so it works on sites you don't own and can't instrument. 1 credit per page.
Free plan, no credit card. 1,000 credits a month.
Try it now — no signup
Try your own URL
Paste up to 10 URLs
Your result will appear here.
Pick one of the pages above to get started.
The request
One POST, one bearer token
curl -X POST https://urlpipe.dev/console \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/checkout", "sync": true, "page_options": {"delay":3000}}'import requests
res = requests.post(
"https://urlpipe.dev/console",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"url": "https://example.com/checkout", "sync": True, "page_options": {"delay": 3000}},
)const res = await fetch("https://urlpipe.dev/console", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com/checkout", sync: true, page_options: {"delay":3000} }),
})$ch = curl_init("https://urlpipe.dev/console");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["url" => "https://example.com/checkout", "sync" => true, "page_options" => ["delay" => 3000]]),
]);
$response = curl_exec($ch);[
{
"type": "exception",
"text": "Uncaught TypeError: Cannot read properties of undefined (reading 'map')"
},
{
"type": "error",
"text": "[checkout] payment widget failed to initialise: timeout"
},
{
"type": "warning",
"text": "[consent] TCF API not found, defaulting to deny"
}
]Scope
Exactly what is captured
The page loads in headless Chrome, and the capture waits briefly after network activity settles so late scripts get to report. Each message comes back with a type and its text:
| type | Comes from | Captured |
|---|---|---|
| error | console.error() calls | Yes |
| warning | console.warn() calls | Yes |
| exception | Uncaught exceptions, and promise rejections nothing handled | Yes |
| — | console.log(), console.info(), console.debug() | No |
| — | Failed resource loads (a 404 image, a blocked script) that nothing logged | No |
| — | Messages from iframes — ads, embeds, third-party widgets | No |
Only the top-level page is listened to: an ad network's iframe logs to its own console, so what you get is your page's output rather than everyone else's. An empty array [] means the page logged no errors or warnings.
Use cases
Why check from outside?
- Sites you don't control. A client's site before you take it on, a vendor's checkout, a partner's embed page, a competitor's landing page. There is no code of yours on them to report anything.
- Third-party scripts on your own pages. Tag managers, consent tools and chat widgets change without a deploy of yours. A scheduled check catches the day one starts throwing.
- After a deploy. Run it against your key pages as a post-deploy smoke test and fail the pipeline on a new exception.
- At scale. Sweep a list of URLs — every landing page, every client — with labels to group the results.
errors=$(curl -s -X POST https://urlpipe.dev/console \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://staging.example.com/", "sync": true, "max_age": 0}' \
| jq '[.[] | select(.type == "exception")] | length')
[ "$errors" -eq 0 ] || { echo "$errors uncaught exceptions"; exit 1; }max_age: 0 skips the stored result so every run loads the page afresh. The staging URL has to be publicly reachable.
Triage
Reading the results
Not every message is a bug. A practical order to read them in:
- 1
exceptionfirst. An uncaught exception stopped some script from finishing. If it came from the code that renders the page, part of the page is probably missing — check the screenshot from the same /scrape call. - 2Then
error. These are the page's ownconsole.errorcalls: a failed API call a framework caught, a widget that gave up, a missing configuration. - 3
warninglast. Deprecations and library notices. Worth tracking as a count, rarely worth waking anyone for.
For a recurring check, compare runs rather than alerting on every message: store each run's messages keyed by their text, and alert on texts you haven't seen before. Third-party scripts on a page change without anyone deploying, so a new message is the signal; a warning that's been there for months is not.
Compared
Console capture and error trackers
Error trackers such as Sentry work from inside the page: you add their SDK to your code, and it reports errors from every real visitor's browser, with stack traces, releases and user context. That is the right tool for your own production app, and this doesn't replace it.
The console API works from outside: one synthetic visit, no SDK, no access to the site's code. It sees only what happens during that one load, in one browser, with no user interaction — and it works on any public page, including ones where you could never install anything.
Page options
Getting errors that appear late
Some errors fire on a timer or after a lazy widget loads. page_options.delay waits up to 10 seconds after the page settles; wait_for_selector waits for an element you name. block_cookie_banners and remove_selectors apply too, though removing an element after its script ran won't un-throw its errors. With /scrape you can take a screenshot and a Lighthouse audit in the same request.
Limits
What it does not do
- No console.log output, and no info or debug messages.
- No network log. A failed image or script request that nothing logged isn't reported.
- No source maps. An uncaught exception comes back as its message, without a stack trace or a mapped file and line.
- No interaction. Errors that only happen after a click, a scroll or a login aren't reached.
- No iframes. Only the top-level page's console.
Pricing
What it costs
| Call | Credits | Free (calls/mo) | Starter (calls/mo) | Pro (calls/mo) | Scale (calls/mo) |
|---|---|---|---|---|---|
| /console | 1 credit | 1,000 | 20,000 | 55,000 | 175,000 |
Cache hits and failed requests cost nothing. Paid plans are never cut off: past the allowance, extra credits are $1.50 per 1,000 credits. See every plan.
FAQ
Frequently asked questions
Does the console API capture console.log?
Do I need to install anything on the site?
Does it report failed network requests?
Is it a replacement for Sentry or another error tracker?
How much does a console check cost?
Make your first request in five minutes.
Free plan, no card. Confirm your email and your API key is live — you'll be making real requests in minutes.