JavaScript / TypeScript
Use ScreenshotAPI from Node.js, Deno, Bun, or the browser with the JavaScript SDK.
Overview
The JavaScript/TypeScript examples below use the native fetch API, which is available in Node.js 18+, Deno, Bun, and all modern browsers. No external dependencies are required.
Quick Start
Set your API key
Store your API key as an environment variable:
export SCREENSHOTAPI_KEY="sk_live_your_key_here"Take a screenshot
const SCREENSHOTAPI_KEY = process.env.SCREENSHOTAPI_KEY
async function takeScreenshot(url: string): Promise<Buffer> {
const params = new URLSearchParams({ url })
const response = await fetch(
`https://screenshotapi.to/api/v1/screenshot?${params}`,
{ headers: { 'x-api-key': SCREENSHOTAPI_KEY! } }
)
if (!response.ok) {
const error = await response.json()
throw new Error(`Screenshot failed: ${error.message ?? error.error}`)
}
return Buffer.from(await response.arrayBuffer())
}
const screenshot = await takeScreenshot('https://example.com')
await fs.promises.writeFile('screenshot.png', screenshot)Helper Class
A reusable client class with full TypeScript types:
import { writeFile } from 'node:fs/promises'
interface ScreenshotOptions {
url: string
width?: number
height?: number
fullPage?: boolean
type?: 'png' | 'jpeg' | 'webp'
quality?: number
colorScheme?: 'light' | 'dark'
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
waitForSelector?: string
delay?: number
}
interface ScreenshotResult {
buffer: Buffer
contentType: string
creditsRemaining: number
screenshotId: string
durationMs: number
}
class ScreenshotAPI {
private apiKey: string
private baseUrl: string
constructor(apiKey: string, baseUrl = 'https://screenshotapi.to') {
this.apiKey = apiKey
this.baseUrl = baseUrl
}
async capture(options: ScreenshotOptions): Promise<ScreenshotResult> {
const params = new URLSearchParams({ url: options.url })
if (options.width) params.set('width', String(options.width))
if (options.height) params.set('height', String(options.height))
if (options.fullPage) params.set('fullPage', 'true')
if (options.type) params.set('type', options.type)
if (options.quality) params.set('quality', String(options.quality))
if (options.colorScheme) params.set('colorScheme', options.colorScheme)
if (options.waitUntil) params.set('waitUntil', options.waitUntil)
if (options.waitForSelector) params.set('waitForSelector', options.waitForSelector)
if (options.delay) params.set('delay', String(options.delay))
const response = await fetch(
`${this.baseUrl}/api/v1/screenshot?${params}`,
{ headers: { 'x-api-key': this.apiKey } }
)
if (!response.ok) {
const error = await response.json()
throw new Error(`Screenshot failed (${response.status}): ${error.message ?? error.error}`)
}
return {
buffer: Buffer.from(await response.arrayBuffer()),
contentType: response.headers.get('content-type') ?? 'image/png',
creditsRemaining: Number(response.headers.get('x-credits-remaining') ?? 0),
screenshotId: response.headers.get('x-screenshot-id') ?? '',
durationMs: Number(response.headers.get('x-duration-ms') ?? 0)
}
}
}
// Usage
const api = new ScreenshotAPI(process.env.SCREENSHOTAPI_KEY!)
const result = await api.capture({
url: 'https://github.com',
width: 1280,
height: 720,
type: 'webp',
quality: 85
})
await writeFile('github.webp', result.buffer)
console.log(`Credits remaining: ${result.creditsRemaining}`)
console.log(`Duration: ${result.durationMs}ms`)Common Patterns
Batch Screenshots
Take screenshots of multiple URLs in parallel:
const urls = [
'https://example.com',
'https://github.com',
'https://news.ycombinator.com'
]
const results = await Promise.allSettled(
urls.map(url => api.capture({ url }))
)
for (const [i, result] of results.entries()) {
if (result.status === 'fulfilled') {
await writeFile(`screenshot-${i}.png`, result.value.buffer)
console.log(`✓ ${urls[i]}`)
} else {
console.error(`✗ ${urls[i]}: ${result.reason.message}`)
}
}Express.js Middleware
Serve screenshots as an image proxy:
import express from 'express'
const app = express()
const api = new ScreenshotAPI(process.env.SCREENSHOTAPI_KEY!)
app.get('/screenshot', async (req, res) => {
const url = req.query.url as string
if (!url) return res.status(400).json({ error: 'url is required' })
try {
const result = await api.capture({ url, type: 'webp', quality: 80 })
res.set('Content-Type', result.contentType)
res.set('Cache-Control', 'public, max-age=3600')
res.send(result.buffer)
} catch (error) {
res.status(500).json({ error: 'Screenshot failed' })
}
})Next.js API Route
Use in a Next.js API route for server-side screenshot generation:
import { NextResponse } from 'next/server'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const url = searchParams.get('url')
if (!url) {
return NextResponse.json({ error: 'url is required' }, { status: 400 })
}
const response = await fetch(
`https://screenshotapi.to/api/v1/screenshot?url=${encodeURIComponent(url)}`,
{ headers: { 'x-api-key': process.env.SCREENSHOTAPI_KEY! } }
)
if (!response.ok) {
return NextResponse.json({ error: 'Screenshot failed' }, { status: 500 })
}
const buffer = await response.arrayBuffer()
return new NextResponse(buffer, {
headers: {
'Content-Type': response.headers.get('content-type') ?? 'image/png',
'Cache-Control': 'public, max-age=3600'
}
})
}Streaming to S3
Upload screenshots directly to AWS S3:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
const s3 = new S3Client({ region: 'us-east-1' })
const result = await api.capture({ url: 'https://example.com' })
await s3.send(new PutObjectCommand({
Bucket: 'my-screenshots',
Key: `screenshots/${Date.now()}.png`,
Body: result.buffer,
ContentType: result.contentType
}))Error Handling
try {
const result = await api.capture({ url: 'https://example.com' })
// Success
} catch (error) {
if (error instanceof Error) {
if (error.message.includes('402')) {
console.error('Out of credits — purchase more at screenshotapi.to')
} else if (error.message.includes('403')) {
console.error('Invalid API key — check your configuration')
} else {
console.error('Screenshot failed:', error.message)
}
}
}Browser Usage
Never expose your API key in client-side JavaScript. Always proxy requests through your own backend.
Instead of calling ScreenshotAPI directly from the browser, create a backend endpoint that proxies the request:
// Frontend
const response = await fetch(`/api/screenshot?url=${encodeURIComponent(url)}`)
const blob = await response.blob()
const imageUrl = URL.createObjectURL(blob)This keeps your API key secure on the server side.