Screenshot API in Node.js

Capture any URL as a PNG, JPEG, WebP, or PDF from your Node.js app in three lines of code. No Puppeteer install, no Chromium binary, no headless-browser memory footprint on your server.

100 free screenshots/month · Works with Express, Next.js, Fastify, Hono, Cloudflare Workers, Lambda

The 3-line version

Native fetch (Node.js 18+). Replace YOUR_API_KEY with your key from the signup form.

const res = await fetch('https://api.aisnapapi.com/v1/screenshot?url=https://example.com', { headers: { Authorization: 'Bearer YOUR_API_KEY' } }); const buf = Buffer.from(await res.arrayBuffer()); await require('fs').promises.writeFile('shot.png', buf);

That's it. The response body is raw PNG bytes — no JSON wrapping, no base64.

Express route returning a screenshot

A simple Express handler that proxies a screenshot of any user-supplied URL:

import express from 'express'; const app = express(); app.get('/screenshot', async (req, res) => { const url = req.query.url; const r = await fetch( `https://api.aisnapapi.com/v1/screenshot?url=${encodeURIComponent(url)}&full_page=true`, { headers: { Authorization: `Bearer ${process.env.SNAPAPI_KEY}` } } ); res.type('image/png'); r.body.pipe(res); }); app.listen(3000);

Next.js App Router: dynamic OG images

Generate a screenshot-based Open Graph image for any blog post on demand. Put this in app/api/og/route.ts:

export async function GET(req: Request) { const { searchParams } = new URL(req.url); const slug = searchParams.get('slug'); const target = `https://yourdomain.com/og-preview/${slug}`; const r = await fetch( `https://api.aisnapapi.com/v1/screenshot?url=${encodeURIComponent(target)}&width=1200&height=630`, { headers: { Authorization: `Bearer ${process.env.SNAPAPI_KEY!}` } } ); return new Response(r.body, { headers: { 'Content-Type': 'image/png', 'Cache-Control': 'public, max-age=86400, s-maxage=86400' } }); }

Tip: aggressive caching at the CDN means you spend one screenshot per unique OG image, not per pageview.

Cloudflare Workers / Edge

The same code works at the edge — no Node-specific modules, just fetch and the global Response:

export default { async fetch(req, env) { const url = new URL(req.url).searchParams.get('url'); const r = await fetch( `https://api.aisnapapi.com/v1/screenshot?url=${encodeURIComponent(url)}`, { headers: { Authorization: `Bearer ${env.SNAPAPI_KEY}` } } ); return new Response(r.body, { headers: { 'Content-Type': 'image/png' } }); } };

Save a PDF from a URL

const r = await fetch( 'https://api.aisnapapi.com/v1/screenshot?url=https://en.wikipedia.org/wiki/Web_API&format=pdf', { headers: { Authorization: 'Bearer YOUR_API_KEY' } } ); await require('fs').promises.writeFile('page.pdf', Buffer.from(await r.arrayBuffer()));

Common gotchas

Start with 100 free screenshots / month

No credit card. No upsell wall. 30-second signup.

Get My Free API Key