Website Screenshot API: The Developer's Guide to Capturing Any Page
Capturing website screenshots programmatically comes up constantly in developer workflows: visual regression testing, website monitoring, generating social preview cards, building PDFs from HTML, and increasingly — providing visual proof for AI agent actions.
You have two options: run Puppeteer (or Playwright) yourself, or call a screenshot API. This guide covers the API approach — what it is, when to use it, and how to call it from curl, Node.js, and Python.
Why a Screenshot API Instead of Puppeteer?
Self-hosting headless Chrome sounds simple but isn't:
- Binary dependency hell — Chrome needs specific system libraries. Docker images bloat to 1–2 GB.
- Memory leaks — Long-running Puppeteer processes consume memory and need restarts.
- Blocked renders — Many sites detect headless Chrome and block it.
- CAPTCHA / JS rendering — You're responsible for solving CAPTCHAs and waiting for dynamic content.
- Maintenance — Chrome updates can break your setup unexpectedly.
A screenshot API handles all of this. You send a URL, get back an image.
The Simplest Possible Screenshot
curl "https://api.pagebolt.dev/v1/screenshot" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"url": "https://example.com"}' \
-H "Content-Type: application/json" \
--output screenshot.png
Done. No Chrome. No dependencies. No Docker.
Node.js Example
const fs = require('fs');
async function screenshot(url, outputPath) {
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url,
fullPage: true,
blockBanners: true,
blockAds: true
})
});
const buffer = await response.arrayBuffer();
fs.writeFileSync(outputPath, Buffer.from(buffer));
console.log(`Screenshot saved to ${outputPath}`);
}
screenshot('https://example.com', 'output.png');
Python Example
import requests
import os
def screenshot(url: str, output_path: str):
response = requests.post(
'https://api.pagebolt.dev/v1/screenshot',
headers={
'Authorization': f'Bearer {os.environ["PAGEBOLT_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'url': url,
'fullPage': True,
'blockBanners': True,
'format': 'png'
}
)
response.raise_for_status()
with open(output_path, 'wb') as f:
f.write(response.content)
print(f'Screenshot saved to {output_path}')
screenshot('https://example.com', 'output.png')
Common Use Cases
1. Website Monitoring
Capture a daily screenshot to detect visual changes — layout breaks, content changes, error pages.
const cron = require('node-cron');
cron.schedule('0 9 * * *', async () => {
const date = new Date().toISOString().split('T')[0];
await screenshot('https://yourapp.com', `snapshots/${date}.png`);
});
2. Open Graph / Social Preview Images
Generate og:image cards dynamically so every blog post and product page looks sharp when shared on LinkedIn, Twitter, or Slack.
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: `https://yourapp.com/og-template?title=${encodeURIComponent(post.title)}`,
viewportWidth: 1200,
viewportHeight: 630,
format: 'jpeg',
quality: 90
})
});
3. HTML to PDF
Render invoices, reports, and certificates from HTML templates.
const response = await fetch('https://api.pagebolt.dev/v1/pdf', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
html: `<html><body><h1>Invoice #${id}</h1>...</body></html>`,
pdfOptions: { format: 'A4' }
})
});
4. AI Agent Visual Proof
When an AI agent completes a browser task, capture a screenshot as evidence. This is critical for compliance workflows — you need to prove the agent did what it was supposed to do.
// After agent completes a task
const evidence = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: currentUrl,
metadata: { agentId, taskId, timestamp: Date.now() }
})
});
// Store the binary + metadata for the audit trail
5. Visual Regression Testing in CI
Capture screenshots before and after a deploy, diff them with a tool like pixelmatch or resemblejs.
# .github/workflows/visual-test.yml
- name: Capture post-deploy screenshot
run: |
curl -s -X POST https://api.pagebolt.dev/v1/screenshot \
-H "Authorization: Bearer ${{ secrets.PAGEBOLT_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"url": "https://staging.yourapp.com", "fullPage": true}' \
--output post-deploy.png
Full-Page vs Viewport Screenshots
-
fullPage: true— captures the entire scrollable page, even content below the fold. Best for content pages and documentation. - Default (no
fullPage) — captures only the visible viewport. Best for above-the-fold social cards and hero images.
Blocking Noise
Most pages have banners, ads, and chat widgets that pollute screenshots. Block them:
{
"url": "https://example.com",
"blockBanners": true,
"blockAds": true,
"blockChats": true,
"blockTrackers": true
}
Device Emulation
Capture how a page looks on mobile, tablet, or a specific device:
body: JSON.stringify({
url: 'https://example.com',
viewportDevice: 'iphone_14_pro'
})
Get the full list of supported devices with:
curl "https://api.pagebolt.dev/v1/devices" \
-H "Authorization: Bearer YOUR_API_KEY"
Authenticated Pages
For pages behind login, pass session cookies:
body: JSON.stringify({
url: 'https://app.yourservice.com/dashboard',
cookies: [
{ name: 'session', value: process.env.SESSION_TOKEN, domain: 'app.yourservice.com' }
]
})
Handling the Response
By default, the API returns binary image data. For programmatic workflows, use response_type: "json" to get a base64 payload:
body: JSON.stringify({
url: 'https://example.com',
response_type: 'json'
})
// Response: { "image": "base64string...", "metadata": { ... } }
Free Tier
PageBolt includes 100 screenshot requests per month on the free tier — no credit card required. It's enough to explore every feature and prototype your integration before committing.
Get started: pagebolt.dev
Top comments (0)