npm
browsergrab
BrowserGrab SDK
The official JavaScript and TypeScript client. Capture screenshots with a single method call — zero dependencies, works everywhere JS runs.
One method
client.screenshot() is all you need. Options are optional.
Typed errors
BrowserGrabError carries a machine-readable code, HTTP status, and whether a credit was charged.
Auto-retry
Retries on 5xx errors with exponential backoff. Configurable retry count and timeout.
Zero dependencies
Uses the native fetch API. No axios, no node-fetch, no bloat.
PNG · JPEG · WebP
All three formats supported. Set quality for JPEG and WebP compression.
Flexible storage
Cloud CDN, Google Drive, or inline base64 — your choice per request.
Up and running in 30 seconds
Install the package, grab an API key from your dashboard, and make your first capture.
import BrowserGrab from "browsergrab";
const client = new BrowserGrab("bg_live_YOUR_API_KEY");
const result = await client.screenshot({
url: "https://example.com",
});
console.log(result.url); // https://cdn.browsergrab.app/...
console.log(result.width); // 1280
console.log(result.height); // 800
console.log(result.format); // "png"What you can build
Every option the API supports is available through the SDK. Here are the most common patterns.
Full-page capture
Capture the entire scrollable document, not just the visible viewport
const result = await client.screenshot({
url: "https://github.com/trending",
fullPage: true, // captures entire scroll height
format: "webp", // WebP for smaller file sizes
width: 1440,
});Dark mode screenshotsSuper
Forces prefers-color-scheme: dark before capture
const result = await client.screenshot({
url: "https://vercel.com",
darkMode: true, // emulate dark mode
format: "png",
width: 1920,
height: 1080,
});Retina / HiDPISuper
2× device pixel ratio — sharper screenshots for high-res displays and print
const result = await client.screenshot({
url: "https://stripe.com",
retina: true, // 2× DPR — actual output is 2560×1600 for a 1280×800 viewport
width: 1280,
height: 800,
format: "jpeg",
quality: 90, // JPEG compression quality (1–100)
});Dynamic / JS-heavy pages
Add a delay after load to let animations settle or async content render
const result = await client.screenshot({
url: "https://charts.example.com/dashboard",
waitFor: 2000, // wait 2 seconds after load (max 5000ms)
fullPage: true,
format: "png",
});Clean captures with ad blockingSuper
Block common ad networks before capturing — great for content monitoring
const result = await client.screenshot({
url: "https://techcrunch.com",
blockAds: true, // blocks common ad/tracker domains
fullPage: true,
format: "webp",
});Storage options
Save to cloud CDN, Google Drive, or get raw base64 back inline
// Cloud CDN (default) — returns a public CDN URL
const cdn = await client.screenshot({
url: "https://example.com",
storage: "cloud",
});
// result.url → "https://cdn.browsergrab.app/screenshots/..."
// Google Drive — returns a Google Drive webViewLink (Super plan)
const drive = await client.screenshot({
url: "https://example.com",
storage: "gdrive",
});
// result.url → "https://drive.google.com/file/d/..."
// None — returns a base64 data URL inline (no storage used)
const inline = await client.screenshot({
url: "https://example.com",
storage: "none",
});
// result.url → "data:image/png;base64,iVBORw0KGgo..."Batch captures
Screenshot multiple URLs concurrently with Promise.all
const urls = [
"https://example.com",
"https://vercel.com",
"https://stripe.com",
];
const results = await Promise.all(
urls.map((url) =>
client.screenshot({ url, format: "webp", width: 1280 })
)
);
for (const result of results) {
console.log(result.url);
}BrowserGrabError
All errors thrown by the SDK are instances of BrowserGrabError with three extra properties: a machine-readable code, the status HTTP code, and whether a credit was charged.
import BrowserGrab, { BrowserGrabError } from "browsergrab";
const client = new BrowserGrab("bg_live_YOUR_API_KEY");
try {
const result = await client.screenshot({ url: "https://example.com" });
console.log(result.url);
} catch (err) {
if (err instanceof BrowserGrabError) {
console.error("Code: ", err.code); // e.g. "quota_exceeded"
console.error("Status: ", err.status); // e.g. 429
console.error("Charged: ", err.charged); // false = no credit consumed
switch (err.code) {
case "quota_exceeded":
// Monthly limit hit — upgrade or wait for reset
break;
case "invalid_api_key":
// Key is wrong or revoked
break;
case "unsafe_url":
// URL pointed to a private/reserved IP address
break;
case "timeout":
// Request exceeded timeoutMs (default: 90s)
break;
case "network_error":
// Could not reach the API at all
break;
}
}
}| code | status | charged | description |
|---|---|---|---|
invalid_api_key | 401 | false | The API key is missing, revoked, or malformed |
quota_exceeded | 429 | false | Monthly screenshot limit has been reached |
dimension_exceeds_plan | 403 | false | Requested dimensions exceed your plan's maximum |
feature_requires_super | 403 | false | retina, darkMode, blockAds, or quality used on a free plan |
gdrive_not_available | 403 | false | Google Drive storage requires the Super plan |
unsafe_url | 400 | false | URL targets localhost, a private IP, or a non-HTTP scheme |
validation_error | 400 | false | Request body failed schema validation |
page_load_failed | 422 | false | The URL returned an error or couldn't be reached |
timeout | 0 | false | SDK request exceeded timeoutMs |
network_error | 0 | false | Could not connect to the API |
internal_error | 500 | false | Server-side error — SDK retries automatically |
Client options
Pass options as the second argument to new BrowserGrab().
const client = new BrowserGrab("bg_live_YOUR_API_KEY", {
retries: 3, // retry on 5xx up to 3 times (default: 2)
timeoutMs: 60000, // 60s timeout per attempt (default: 90000)
baseUrl: "https://my-proxy.example.com", // optional proxy / test server
});All screenshot parameters
Every parameter accepted by client.screenshot(). Parameters marked Super require the Super plan.
| param | type | default | description |
|---|---|---|---|
url | string | required | Fully-qualified URL to capture. Must begin with https:// or http://. |
width | number | 1280 | Viewport width in pixels. Free plan: 320–1920. Super plan: 320–3840. |
height | number | 800 | Viewport height in pixels. Free plan: 240–1080. Super plan: 240–2160. |
format | "png" | "jpeg" | "webp" | "png" | Output image format. |
fullPage | boolean | false | Capture the entire scrollable page height instead of just the visible viewport. |
waitFor | number | 0 | Extra delay in milliseconds to wait after the page has loaded before taking the screenshot. Useful for JS-rendered content and animations. Maximum 5000ms. |
storage | "cloud" | "gdrive" | "none" | "cloud" | Where to store the result. cloud returns a CDN URL. gdrive saves to Google Drive (Super). none returns a base64 data URL. |
retinaSuper | boolean | false | Render at 2× device pixel ratio (HiDPI). The returned image is twice the requested pixel dimensions. |
darkModeSuper | boolean | false | Emulate prefers-color-scheme: dark before capturing. Affects sites with CSS dark mode support. |
blockAdsSuper | boolean | false | Block common ad networks and tracking scripts before capture. Results in cleaner, faster screenshots of ad-heavy pages. |
qualitySuper | number | 85 | Compression quality for JPEG and WebP formats (1–100). Ignored for PNG. Higher values produce better quality at larger file sizes. |
Free vs Super
All SDK features are available on both plans. Super unlocks higher limits and advanced capture options.
Free
- 100 screenshots / month
- Up to 1920×1080 viewport
- PNG, JPEG, WebP formats
- Full-page capture
- Wait delay up to 5s
- Cloud CDN storage
- Base64 (storage: none)
Super
- Unlimited screenshots
- Up to 3840×2160 viewport
- PNG, JPEG, WebP formats
- Full-page capture
- Wait delay up to 5s
- Cloud CDN storage
- Google Drive storage
- Base64 (storage: none)
- Retina / 2× HiDPI rendering
- Dark mode emulation
- Ad blocking
- Custom JPEG/WebP quality
Ready to start capturing?
Get your API key and make your first screenshot in under a minute.