Invoice #1024
Thank you for your business.
',
type: 'pdf',
width: 1200
})
// pdf.image is an ArrayBuffer of the PDF bytes
```
Error Handling [#error-handling]
The SDK throws typed errors for API, network, and timeout failures. Every error extends `ScreenshotAPIError`.
```typescript
import {
ScreenshotAPI,
AuthenticationError,
InvalidAPIKeyError,
InsufficientCreditsError,
ScreenshotFailedError,
ScreenshotTimeoutError,
ScreenshotNetworkError
} from 'screenshotapi-to'
const client = new ScreenshotAPI({
apiKey: process.env.SCREENSHOTAPI_KEY!,
timeout: 30_000
})
try {
await client.screenshot({ url: 'https://example.com' })
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Missing or malformed API key (401)')
} else if (error instanceof InvalidAPIKeyError) {
console.error('API key is revoked or invalid (403)')
} else if (error instanceof InsufficientCreditsError) {
console.error(`Out of credits (402). Balance: ${error.balance}`)
} else if (error instanceof ScreenshotFailedError) {
console.error(`Capture failed server-side (500): ${error.message}`)
} else if (error instanceof ScreenshotTimeoutError) {
console.error(`Timed out after ${error.timeoutMs}ms`)
} else if (error instanceof ScreenshotNetworkError) {
console.error('Could not reach ScreenshotAPI')
} else {
throw error
}
}
```
| Error | When |
| -------------------------- | ------------------------------------------------- |
| `AuthenticationError` | `401` — API key missing or malformed |
| `InsufficientCreditsError` | `402` — no credits remaining (exposes `.balance`) |
| `InvalidAPIKeyError` | `403` — API key revoked or invalid |
| `ScreenshotFailedError` | `500` — capture failed server-side |
| `ScreenshotTimeoutError` | Request exceeded `timeout` (exposes `.timeoutMs`) |
| `ScreenshotNetworkError` | Network/connection failure |
| `ScreenshotAPIError` | Base class for all of the above |
Framework Recipes [#framework-recipes]
Next.js (App Router) [#nextjs-app-router]
Proxy screenshots through a route handler so your key stays on the server.
```typescript
// app/api/screenshot/route.ts
import { ScreenshotAPI } from 'screenshotapi-to'
const client = new ScreenshotAPI({ apiKey: process.env.SCREENSHOTAPI_KEY! })
export async function GET(request: Request) {
const url = new URL(request.url).searchParams.get('url')
if (!url) {
return Response.json({ error: 'url is required' }, { status: 400 })
}
try {
const { image, contentType } = await client.screenshot({ url, type: 'webp' })
return new Response(image, {
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=3600'
}
})
} catch {
return Response.json({ error: 'Screenshot failed' }, { status: 500 })
}
}
```
Express [#express]
```typescript
import express from 'express'
import { ScreenshotAPI } from 'screenshotapi-to'
const app = express()
const client = new ScreenshotAPI({ apiKey: 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 { image, contentType } = await client.screenshot({ url, type: 'webp', quality: 80 })
res.set('Content-Type', contentType)
res.set('Cache-Control', 'public, max-age=3600')
res.send(Buffer.from(image))
} catch {
res.status(500).json({ error: 'Screenshot failed' })
}
})
```
Cloudflare Workers [#cloudflare-workers]
`save()` isn't available at the edge — use `screenshot()` and return the `ArrayBuffer` directly.
```typescript
import { ScreenshotAPI } from 'screenshotapi-to'
export default {
async fetch(request: Request, env: { SCREENSHOTAPI_KEY: string }): Promise