What is BrowserGrab?

BrowserGrab is a screenshot API that captures any public webpage as a pixel-perfect image with a single HTTP request. No browser to run, no Puppeteer to manage — just send a URL and get back an image.

It runs on Cloudflare's global network, so captures are fast from anywhere in the world. You can store results on BrowserGrab's CDN, save directly to Google Drive, or receive the raw image as a base64 string in the API response.

Screenshot API

POST a URL, get back an image URL. Works in any language that can make HTTP requests.

JavaScript SDK

npm install browsergrab — a zero-dependency TypeScript client with full types and retry logic.

Chrome Extension

Press Alt+Shift+S on any tab to capture and save a screenshot using your account defaults.

Quick Start

Get your first screenshot in under a minute:

1
Get an API key — Sign up at browsergrab.app/sign-up then create a key from your dashboard. Keys look like bg_live_xxxxxxxxxxxxxxxxxxxx.
2
Send a request — POST to https://browsergrab.app/api/screenshot with your URL. See the full request format in the Postman collection.
3
Get your image — The response contains a permanent CDN URL you can embed directly in <img> tags, store in your database, or share anywhere.
Free plan: 100 screenshots/month at up to 1920×1080. No credit card required. Upgrade to Super for 5,000/month or Pro for 25,000/month — both include 4K resolution, retina captures, and more.

Authentication

All API requests require a Bearer token in the Authorization header. Create and manage your keys from the API Keys page.

Authorization header
http
Authorization: Bearer bg_live_xxxxxxxxxxxxxxxxxxxx

Keep your keys secret — they carry your quota. If a key is compromised, delete it from the dashboard and create a new one.

Parameters

Send a JSON body to POST /api/screenshot. Only url is required — everything else has a sensible default.

Core (all plans)

ParameterTypeDefaultDescription
urlstringrequiredFully-qualified URL to capture (must include https://)
formatstring"png"Output format: png, jpeg, or webp
widthinteger1280Viewport width in pixels (320–1920 on Free, up to 3840 on Super)
heightinteger800Viewport height in pixels (240–1080 on Free, up to 2160 on Super)
fullPagebooleanfalseCapture the full scrollable page height, not just the viewport
waitForinteger0Extra milliseconds to wait after page load (0–5000). Useful for animations or lazy-loaded content.
storagestring"cloud"Where to store the result: cloud, gdrive, or none

Super plan only

ParameterTypeDefaultDescription
retinabooleanfalseRender at 2× device pixel ratio (HiDPI / Retina). Output image is double the width/height.
darkModebooleanfalseForce prefers-color-scheme: dark before capturing
blockAdsbooleanfalseBlock common ad networks and trackers before capture
qualityinteger85JPEG/WebP compression quality (1–100). Ignored for PNG.
For interactive examples with every parameter pre-filled, use the Postman collection.

Bulk Screenshots

Capture up to 20 URLs in a single API call. Each URL counts as one screenshot credit. The entire batch is checked against your quota upfront — if you don't have enough credits for all URLs, the whole request is rejected rather than processing a partial batch.

Two ways to send multiple URLs

Option 1 — urls array (recommended)
json
{
  "urls": [
    "https://example.com",
    "https://github.com",
    "https://stripe.com"
  ],
  "format": "png",
  "width": 1280,
  "storage": "cloud"
}
Option 2 — comma-separated url string
json
{
  "url": "https://example.com,https://github.com,https://stripe.com",
  "format": "png"
}

Bulk response shape

When 2 or more URLs are sent, the response wraps individual results in a results array. Each item has its own success flag and charged indicator.

Bulk response (200 OK)
json
{
  "success": true,
  "count": 3,
  "captured": 2,
  "failed": 1,
  "results": [
    {
      "url": "https://example.com",
      "success": true,
      "data": {
        "url": "https://pub-....r2.dev/screenshots/2025-04/abc123.png",
        "width": 1280,
        "height": 800,
        "format": "png",
        "storage": "cloud"
      },
      "charged": true
    },
    {
      "url": "https://github.com",
      "success": true,
      "data": { "url": "https://pub-....r2.dev/screenshots/...", ... },
      "charged": true
    },
    {
      "url": "https://bad-url.xyz",
      "success": false,
      "error": "page_load_failed",
      "message": "DNS lookup failed",
      "charged": false
    }
  ]
}

Bulk behaviour

ScenarioBehaviour
One URL fails (DNS, blank page)Not charged. Rest of the batch continues normally.
Insufficient quota for full batchEntire request rejected with quota_exceeded before any captures run.
More than 20 URLsRejected with too_many_urls. Max is 20 per request.
Single URL (backward-compatible)Returns the standard { "success": true, "data": {...} } shape, not the bulk wrapper.
Tester: The API Tester in your dashboard supports bulk too — paste up to 5 comma- or newline-separated URLs to try it out before hitting production.

Storage Options

The storage parameter controls where the screenshot ends up after capture.

ValuePlanWhat you get back
cloudSuper, ProA permanent public CDN URL (e.g. https://pub-....r2.dev/screenshots/...)
gdriveSuper, ProA shareable Google Drive link. Requires Drive connected in Account settings.
noneAll plansA data:image/...;base64,... string in the response body. Nothing stored remotely.

CDN URLs are permanent — they don't expire. You can link to them directly in emails, embed them in <img> tags, or store them in your own database.

Response Format

All responses are JSON. A successful capture returns:

Success (200 OK)
json
{
  "success": true,
  "data": {
    "url": "https://pub-....r2.dev/screenshots/2025-04/abc123.png",
    "width": 1280,
    "height": 800,
    "format": "png",
    "storage": "cloud"
  }
}

data.url is the image you store or display. For storage: "none" this is a base64 data URL instead of a CDN link.

Error Codes

Errors follow a consistent shape: { "error": "code", "message": "Human description" }. The charged field will be false when no screenshot credit was consumed.

HTTPError codeMeaningCharged?
400validation_errorMissing or invalid parameter in the request bodyNo
400unsafe_urlURL targets a private/internal IP — blocked for securityNo
401missing_api_keyNo Authorization header providedNo
401invalid_api_keyKey not found or has been deletedNo
403dimension_exceeds_planRequested resolution exceeds your plan maximumNo
403feature_requires_superretina, darkMode, blockAds, or quality used on Free plan — requires Super or ProNo
403gdrive_not_availableGoogle Drive storage requires Super or Pro planNo
422page_load_failedPage couldn't be loaded (DNS error, blank page, timeout)No
429quota_exceededMonthly screenshot limit reached. Includes current, limit, and resetAt.No
500internal_errorSomething went wrong on our side — retry with exponential backoffNo

Rate Limits

There is no per-second rate limit — burst as fast as you like within your monthly allocation. Quotas reset on the 1st of each month UTC. Need more? Contact us for a custom plan.


JavaScript / TypeScript SDK

The official SDK is published on npm as browsergrab. Zero dependencies. Works in Node.js 18+, Deno, Bun, and any runtime with the Fetch API. Full TypeScript types included.

Installation

bash
npm install browsergrab

Usage

index.ts
ts
import BrowserGrab from "browsergrab";

const client = new BrowserGrab("bg_live_your_api_key");

// Basic screenshot — returns CDN URL
const result = await client.screenshot({
  url: "https://stripe.com",
});
console.log(result.url); // https://pub-....r2.dev/screenshots/...

// Full page in WebP with dark mode (Super plan)
const dark = await client.screenshot({
  url: "https://github.com",
  format: "webp",
  fullPage: true,
  darkMode: true,
  storage: "cloud",
});

// Mobile viewport
const mobile = await client.screenshot({
  url: "https://example.com",
  width: 375,
  height: 812,
});

Client options:

ts
const client = new BrowserGrab("bg_live_xxx", {
  retries: 3,        // retry on 5xx errors (default: 2)
  timeoutMs: 60_000, // per-request timeout in ms (default: 90000)
  baseUrl: "...",    // override API base URL
});

Error Handling

All API errors throw a BrowserGrabError with machine-readable fields.

ts
import BrowserGrab, { BrowserGrabError } from "browsergrab";

const client = new BrowserGrab("bg_live_xxx");

try {
  const result = await client.screenshot({ url: "https://example.com" });
  console.log(result.url);
} catch (err) {
  if (err instanceof BrowserGrabError) {
    console.error(err.message);  // "Monthly quota exceeded (15/15 screenshots used...)"
    console.error(err.code);     // "quota_exceeded"
    console.error(err.status);   // 429
    console.error(err.charged);  // false — no credit used
  }
}

The SDK retries automatically on 5xx server errors with exponential backoff. 4xx errors are not retried since they represent caller mistakes.


Chrome Extension

The BrowserGrab Chrome extension lets you screenshot any tab with a single keyboard shortcut. Captures are sent to your BrowserGrab account and stored using your default settings — no copy-paste, no API calls to write.

Installation

1
Install the extension from the Chrome Web Store (coming soon).
2
Once installed, the BrowserGrab icon will appear in your Chrome toolbar. Pin it via the puzzle piece icon for easy access.

Setup

1
Click the BrowserGrab extension icon in the Chrome toolbar (pin it via the puzzle piece icon first), then click Settings.
2
Paste your API key — get one from browsergrab.app/dashboard/keys. Keys look like bg_live_xxx.
3
Choose your Default Storage: Cloud (saved to BrowserGrab CDN), Google Drive, or None (base64 in response). This is also configurable from Account settings on the web.
4
Click Test Connection to verify your key is working. You should see a green success message.

Using the Keyboard Shortcut

Press Alt+Shift+S on any https:// page to capture a screenshot.

You'll see a Capturing… notification while the screenshot processes, then a Screenshot Captured! notification with the result URL. Clicking the notification opens the image in a new tab.

You can also click the extension popup and hit Capture This Page to trigger a capture without using the keyboard.

Reassigning the shortcut: Go to chrome://extensions/shortcuts to change the default Alt+Shift+S binding to any key combination you prefer.

The extension cannot capture Chrome internal pages (chrome://), the New Tab page, or the Chrome Web Store — only regular http:// and https:// URLs.


Postman Collection

Every endpoint pre-wired with example bodies and expected responses. The fastest way to explore the API without writing any code.

Open Postman Documenter

Interactive API reference — run requests directly in Postman or your browser

The collection includes: Basic screenshot, all options, full page, mobile viewport, wait for animations, bulk screenshots (multiple URLs), Super features (retina + dark mode + block ads), base64 response, and Google Drive storage — each as a ready-to-run request.

Plans & Limits

FeatureFreeBasic ($4.99/mo)Super ($9.99/mo)Pro ($39/mo)
Screenshots / month505005,00025,000
Max resolution1920×10801920×10803840×21603840×2160
FormatsPNG, JPEG, WebPPNG, JPEG, WebPPNG, JPEG, WebPPNG, JPEG, WebP
Cloud storage (CDN)1 GB15 GB100 GB
Google Drive
Retina (2×)
Dark mode emulation
Ad blocking
Custom JPEG/WebP quality

Failed captures (DNS errors, blank pages, invalid URLs) are never charged against your quota. You only pay for successful screenshots.

Ready to start building?

Create a free account and start capturing screenshots in minutes.

Get Started Free

Get support on Discord

Ask questions, share feedback, and get help from the community and the team.

Join Discord