Headless Browser API: Skip the Infrastructure, Keep the Power
A headless browser is a web browser without a graphical user interface. It's how developers automate screenshots, generate PDFs, test pages, and run browser-based workflows.
For years, the only option was self-hosting: install Chrome, manage its memory footprint, handle crashes, maintain Docker images, debug production incidents.
There's a better way: a headless browser API.
What Is a Headless Browser API?
Instead of running Chrome yourself, you send HTTP requests to a managed service that has Chrome running. You describe what you want (take a screenshot, generate a PDF, click a button), and the API gives you the result.
Self-hosted Puppeteer:
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
// You now own a Chrome process — memory, CPU, crashes, all on you
const page = await browser.newPage();
await page.goto('https://example.com');
const screenshot = await page.screenshot();
Headless Browser API (PageBolt):
const response = await fetch('https://api.pagebolt.dev/take_screenshot', {
method: 'POST',
headers: { 'Authorization': 'Bearer KEY' },
body: JSON.stringify({ url: 'https://example.com' })
});
const { imageUrl } = await response.json();
// Done. Chrome? Not your problem.
The difference: responsibility.
With Puppeteer, you're responsible for Chrome. With an API, the provider is.
Why APIs Win Over Self-Hosted
| Aspect | Self-Hosted Puppeteer | Headless Browser API |
|---|---|---|
| Installation | apt-get, brew, Docker Dockerfile | HTTP request |
| Memory Management | You manage Chrome processes | Provider handles it |
| Scaling | Deploy more servers + Chrome | API scales automatically |
| Crashes | You debug memory leaks | Provider handles failures |
| Updates | Manual Chrome binary updates | Automatic |
| Serverless (Lambda) | 500MB+ layer, slow cold starts | Lightweight HTTP calls |
| Shared Hosting | Usually blocked (permissions) | Works everywhere |
| Cost | $50-200/month (infrastructure) | $0.01-0.10 per request |
| Time to First Request | Hours (setup + testing) | Minutes (sign up + API key) |
Real-World Use Cases
1. Social Media Preview (OG Images)
Generate preview images when users share links:
curl -X POST https://api.pagebolt.dev/create_og_image \
-H "Authorization: Bearer KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Check out this article",
"subtitle": "Learn how APIs solve infrastructure pain",
"template": "minimal"
}' \
-o preview.png
Self-hosted: Maintain image generation infrastructure. Update as design changes. Debug rendering bugs.
API: Send a request, get an image.
2. Invoice PDFs
Generate PDFs from HTML for receipts:
const html = `
<html>
<style>
body { font-family: Arial; margin: 40px; }
.invoice-header { font-size: 24px; font-weight: bold; }
.items { margin-top: 30px; }
</style>
<div class="invoice-header">Invoice #12345</div>
<div class="items">
<p>Item 1: $50</p>
<p>Item 2: $30</p>
</div>
</html>
`;
const response = await fetch('https://api.pagebolt.dev/generate_pdf', {
method: 'POST',
headers: { 'Authorization': 'Bearer KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ html })
});
const { pdfUrl } = await response.json();
// Use pdfUrl to stream to user or store
Self-hosted: Deploy wkhtmltopdf, manage system dependencies, handle CSS rendering bugs.
API: Send HTML, get PDF URL.
3. Page Screenshots for Testing
Capture pages in CI/CD pipelines:
import requests
import json
response = requests.post('https://api.pagebolt.dev/take_screenshot', {
'headers': {'Authorization': 'Bearer KEY'},
'json': {
'url': 'https://myapp.com/checkout',
'width': 1280,
'height': 720,
'cookies': [
{'name': 'session_id', 'value': 'abc123', 'domain': 'myapp.com'}
]
}
})
data = response.json()
screenshot_url = data['imageUrl']
# Compare against baseline, alert on visual changes
Self-hosted: CI/CD runners need Chrome installed. Slow builds. Docker bloat.
API: API call from anywhere, instantly.
4. Multi-Step Automation
Record or automate a sequence of interactions:
curl -X POST https://api.pagebolt.dev/run_sequence \
-H "Authorization: Bearer KEY" \
-H "Content-Type: application/json" \
-d '{
"steps": [
{ "action": "navigate", "url": "https://example.com/login" },
{ "action": "fill", "selector": "#email", "value": "user@example.com" },
{ "action": "fill", "selector": "#password", "value": "password" },
{ "action": "click", "selector": "#submit" },
{ "action": "screenshot" }
]
}' \
-o authenticated_page.png
Self-hosted: Maintain Puppeteer, manage timeouts, debug flaky tests.
API: Send steps, get screenshot.
Infrastructure Pain Points Solved
Pain: Memory Management
Problem: Chrome processes leak memory over time. Your server runs out of RAM.
Solution: API provider manages memory. You make requests, they handle everything.
Pain: Docker Bloat
Problem: Docker image for Chrome = 700MB–1GB. Slow builds. Registry costs.
Solution: API calls are tiny. No Docker required.
Pain: Shared Hosting Restrictions
Problem: Can't install system binaries. Can't run processes. Trapped.
Solution: APIs work from anywhere — even restricted environments.
Pain: Serverless Cold Starts
Problem: Lambda with Chrome layer = 500MB, slow cold start, high cost.
Solution: Lightweight HTTP API call = fast, cheap, reliable.
Pain: Scaling Headaches
Problem: Need more screenshots? Deploy more servers + more Chrome.
Solution: API scales. You just make more requests.
When to Use Each
Use a headless browser API if:
- You need headless browser capabilities but don't own infrastructure
- You're on serverless, shared hosting, or restricted environments
- You want to minimize operations burden
- You generate 100+ headless requests/month
- You value time-to-market over cost-per-request
Use self-hosted Puppeteer if:
- You have dedicated infrastructure and ops team
- You need sub-millisecond latency (rare)
- You're running 10,000+ headless operations daily and can optimize costs
- You need full control over Chrome configuration (extremely rare)
For 99% of use cases: API wins.
Getting Started: Your First API Call
1. Sign up (free tier: 100 requests/month)
# Visit pagebolt.dev, create account, copy API key
export PAGEBOLT_KEY="your_key_here"
2. Make a request (any language, any environment)
curl -X POST https://api.pagebolt.dev/take_screenshot \
-H "Authorization: Bearer $PAGEBOLT_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' \
-o screenshot.png
3. Use the result (image URL, PDF URL, data, whatever)
# screenshot.png is ready to use
file screenshot.png
The Shift: From Infrastructure to API
The headless browser space has shifted. Five years ago, everyone self-hosted. Today, APIs are the default.
It's the same shift that happened with:
- File storage (S3 instead of NFS)
- Databases (managed Postgres instead of ops-managed)
- Email (SendGrid instead of postfix)
- CDN (Cloudflare instead of nginx)
Managed services win because they eliminate complexity.
Next Steps
- Try PageBolt free — 100 requests/month, no credit card. One API call away from your first screenshot.
- Explore use cases — screenshots, PDFs, OG images, automation sequences. Pick one that solves your current problem.
- Benchmark against self-hosted — measure time-to-implementation, ops burden, cost. The API usually wins.
Stop managing infrastructure. Start building features.
PageBolt: Headless browser power without the headache. Get started free →
Top comments (0)