DEV Community

Ozor
Ozor

Posted on

Automate Website Screenshots with a Single API Call (No Puppeteer Required)

Every developer eventually needs website screenshots. Maybe it's for visual regression testing, generating link previews, or building a monitoring dashboard. The usual approach? Install Puppeteer or Playwright, configure a headless browser, deal with memory issues, handle timeouts, and manage Chromium updates.

There's a faster way. A single HTTP request.

The Problem with Self-Hosted Headless Browsers

Running Puppeteer in production means:

  • Memory: Chromium eats 200-500MB per instance
  • Timeouts: Pages with heavy JavaScript can hang for 30+ seconds
  • Infrastructure: You need a server with Chromium installed and enough resources
  • Maintenance: Browser updates break things, fonts render differently across OSes
  • Scaling: Each screenshot blocks a browser instance

For a side project or startup, that's overkill.

One API Call Instead

Here's how to take a screenshot of any website with zero setup:

curl "https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=https://github.com" \
  --output github.png
Enter fullscreen mode Exit fullscreen mode

That's it. You get back a PNG image. No API key required for basic usage.

Real Use Cases with Code

1. Generate Link Previews

When users paste a URL in your app, show a visual preview:

async function getLinkPreview(url) {
  const apiUrl = `https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=${encodeURIComponent(url)}&width=1200&height=630`;

  const response = await fetch(apiUrl);
  const imageBuffer = await response.arrayBuffer();

  // Save or serve as base64
  const base64 = Buffer.from(imageBuffer).toString('base64');
  return `data:image/png;base64,${base64}`;
}

// Usage
const preview = await getLinkPreview('https://dev.to');
Enter fullscreen mode Exit fullscreen mode

2. Visual Regression Testing

Compare screenshots before and after deployments to catch UI bugs:

const { writeFileSync, readFileSync } = require('fs');
const crypto = require('crypto');

async function captureAndCompare(url, baselinePath) {
  const apiUrl = `https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=${encodeURIComponent(url)}&width=1280&height=720`;

  const response = await fetch(apiUrl);
  const buffer = Buffer.from(await response.arrayBuffer());

  // Hash the screenshot
  const currentHash = crypto.createHash('sha256').update(buffer).digest('hex');

  try {
    const baseline = readFileSync(baselinePath);
    const baselineHash = crypto.createHash('sha256').update(baseline).digest('hex');

    if (currentHash !== baselineHash) {
      writeFileSync('diff-screenshot.png', buffer);
      console.log('VISUAL CHANGE DETECTED - check diff-screenshot.png');
      return false;
    }
    console.log('No visual changes');
    return true;
  } catch {
    // No baseline exists yet — save this as the baseline
    writeFileSync(baselinePath, buffer);
    console.log('Baseline saved');
    return true;
  }
}

// Run in CI
captureAndCompare('https://your-app.com', './baselines/homepage.png');
Enter fullscreen mode Exit fullscreen mode

3. Uptime Monitoring with Visual Proof

Don't just check if a site returns 200 — verify it actually looks right:

async function monitorSite(url, name) {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');

  const apiUrl = `https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=${encodeURIComponent(url)}&width=1280&height=720`;

  try {
    const response = await fetch(apiUrl);

    if (!response.ok) {
      console.error(`${name}: Screenshot failed (${response.status})`);
      return;
    }

    const buffer = Buffer.from(await response.arrayBuffer());
    const filename = `monitors/${name}-${timestamp}.png`;
    require('fs').writeFileSync(filename, buffer);

    console.log(`${name}: OK - saved ${filename} (${buffer.length} bytes)`);
  } catch (err) {
    console.error(`${name}: ERROR - ${err.message}`);
  }
}

// Monitor multiple sites
const sites = [
  { url: 'https://your-app.com', name: 'production' },
  { url: 'https://staging.your-app.com', name: 'staging' },
  { url: 'https://docs.your-app.com', name: 'docs' },
];

for (const site of sites) {
  await monitorSite(site.url, site.name);
}
Enter fullscreen mode Exit fullscreen mode

4. Batch Screenshots for Reports

Generate a PDF-ready report with screenshots of competitor pages:

import requests
import os
from datetime import datetime

API_BASE = "https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot"

sites = [
    "https://stripe.com",
    "https://vercel.com",
    "https://github.com",
    "https://dev.to",
]

os.makedirs("report", exist_ok=True)
timestamp = datetime.now().strftime("%Y-%m-%d")

for site in sites:
    name = site.split("//")[1].split(".")[0]
    params = {"url": site, "width": 1280, "height": 800}

    response = requests.get(API_BASE, params=params)

    if response.status_code == 200:
        filename = f"report/{name}-{timestamp}.png"
        with open(filename, "wb") as f:
            f.write(response.content)
        print(f"Saved {filename} ({len(response.content)} bytes)")
    else:
        print(f"Failed: {site} ({response.status_code})")
Enter fullscreen mode Exit fullscreen mode

API Options

The screenshot API supports several parameters:

Parameter Description Example
url Target URL (required) https://example.com
width Viewport width in px 1280
height Viewport height in px 720
fullPage Capture entire page true
darkMode Force dark color scheme true
delay Wait before capture (ms) 2000
selector Capture specific element #hero

Mobile Screenshots

# iPhone viewport
curl "https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=https://dev.to&width=390&height=844" \
  --output dev-to-mobile.png
Enter fullscreen mode Exit fullscreen mode

Dark Mode

curl "https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=https://github.com&darkMode=true" \
  --output github-dark.png
Enter fullscreen mode Exit fullscreen mode

Full Page

curl "https://agent-gateway-kappa.vercel.app/v1/agent-screenshot/api/screenshot?url=https://dev.to&fullPage=true" \
  --output dev-to-full.png
Enter fullscreen mode Exit fullscreen mode

Why Not Just Use Puppeteer?

If you're taking thousands of screenshots daily, running your own infrastructure makes sense. But for most use cases:

Self-Hosted Puppeteer Screenshot API
Setup time Hours (install, configure, deploy) Zero
Memory usage 200-500MB per instance None (server-side)
Scaling You manage it Built-in
Browser updates You manage them Handled for you
Cost Server costs Free tier available
First screenshot After deployment Immediately

The API approach lets you start capturing screenshots in minutes instead of hours. When you outgrow the free tier, you can upgrade — but most projects never reach that point.

Getting Started

  1. No signup needed for basic usage — just make HTTP requests
  2. Get a free API key at agent-gateway-kappa.vercel.app for higher rate limits (200 free credits)
  3. Use any HTTP client — curl, fetch, axios, requests, whatever your stack uses

The screenshot service is part of Frostbyte API, which also includes IP geolocation, DNS lookup, crypto prices, code execution, and 40+ other developer tools — all accessible through a single API key.


Got questions or ideas for the API? Drop them in the comments.

Top comments (0)