API Documentation

Everything you need to start capturing screenshots programmatically.

Contents

Base URL

https://screenshotapi-api-production.up.railway.app

Authentication

All API requests require an API key sent via the Authorization header.

Header format
Authorization: Bearer YOUR_API_KEY

Get your API key by signing up at our pricing page. Your free account includes 100 screenshots per month.

Keep your API key secret. Do not expose it in client-side code. Always make API calls from your server.

Screenshot Endpoint

GET/v1/screenshot

Capture a screenshot of any public website. Returns the image directly as binary data.

Parameters

ParameterTypeDefaultDescription
urlrequiredstring--The URL to capture. Must be a valid HTTP or HTTPS URL.
widthinteger1280Viewport width in pixels. Min: 320, Max: 3840.
heightinteger800Viewport height in pixels. Min: 200, Max: 2160.
formatstringpngOutput format: png, jpeg, or webp.
fullpagebooleanfalseCapture the entire scrollable page.
qualityinteger80Image quality for JPEG/WebP (1-100). Ignored for PNG.
waitinteger1000Additional wait time in ms after page load (0-10000).
blockadsbooleanfalseBlock cookie banners and ads before capturing. Removes common consent dialogs, ad slots, and overlay popups.
output_widthinteger--Resize the output image to this width in pixels (min: 16, max: 3840). Great for generating thumbnails.
output_heightinteger--Resize the output image to this height in pixels (min: 16, max: 3840). Maintains aspect ratio when only one dimension is set.
cssstring--Custom CSS to inject before capture. Max 10KB. Example: "header { display: none; }" to hide elements.
jsstring--Custom JavaScript to execute before capture. Max 10KB. Example: "document.querySelector('.popup').remove()"
wait_for_selectorstring--Wait for a CSS selector to appear before capturing (max 10s timeout). Example: "#main-content"
retriesinteger1Number of retry attempts on transient failures (timeouts, network errors). Min: 0, Max: 3. Set to 0 to disable retries.

Response

Returns the screenshot as binary image data with the appropriate Content-Type header.

HeaderDescription
Content-Typeimage/png, image/jpeg, or image/webp
Content-LengthSize of the image in bytes
X-Screenshot-Time-MsTime taken to capture the screenshot in milliseconds
Example request
curl "https://screenshotapi-api-production.up.railway.app/v1/screenshot\
  ?url=https://github.com\
  &width=1920&height=1080\
  &format=jpeg&quality=90\
  &fullpage=true" \
  -H "Authorization: Bearer sk_live_abc123" \
  -o github.jpeg
POST/v1/screenshot

Same endpoint also accepts POST with a JSON body. Useful for complex requests.

POST example
curl -X POST "https://screenshotapi-api-production.up.railway.app/v1/screenshot" \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://github.com","width":1920,"height":1080,"format":"png","fullPage":true}' \
  -o github.png

Async Screenshots / Webhook

POST/v1/screenshot/async

Capture screenshots asynchronously. The API returns immediately with a job ID. You can either poll the status endpoint or provide a callback_url to receive the result via webhook.

When to use async mode: Batch processing, serverless functions with short timeouts, or when you want non-blocking screenshot capture in your application.

Additional Parameters

ParameterTypeDefaultDescription
callback_urlstring--URL to POST the result to when the screenshot is complete. Must be a publicly accessible HTTPS endpoint.

All standard screenshot parameters (url, width, height, format, etc.) are also supported.

Immediate Response (202 Accepted)

Response
{
  "id": "job_1710000000_abc12345",
  "status": "pending",
  "status_url": "/v1/status/job_1710000000_abc12345",
  "message": "Screenshot job queued. Poll the status_url or wait for webhook callback."
}

Status Endpoint

GET/v1/status/:jobId

Check the status of an async job. Jobs expire after 1 hour.

Completed job response
{
  "id": "job_1710000000_abc12345",
  "status": "completed",
  "created_at": "2026-03-14T10:00:00.000Z",
  "completed_at": "2026-03-14T10:00:03.500Z",
  "duration_ms": 3500,
  "result": {
    "content_type": "image/png",
    "size_bytes": 245760,
    "data_base64": "/9j/4AAQSkZ..."
  }
}

Webhook Callback Payload

When a callback_url is provided, the API will POST the result to your endpoint when the screenshot is ready.

Webhook POST body
{
  "id": "job_1710000000_abc12345",
  "status": "completed",
  "content_type": "image/png",
  "size_bytes": 245760,
  "duration_ms": 3500,
  "data_base64": "/9j/4AAQSkZ..."
}

Example: Async with Polling

Node.js
const API_KEY = 'YOUR_API_KEY';
const BASE = 'https://screenshotapi-api-production.up.railway.app';

// 1. Start async job
const res = await fetch(`${BASE}/v1/screenshot/async`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com',
    format: 'png',
    width: 1920,
    height: 1080,
  }),
});

const { id, status_url } = await res.json();
console.log('Job started:', id);

// 2. Poll for result
let job;
do {
  await new Promise(r => setTimeout(r, 1000));
  const status = await fetch(`${BASE}${status_url}`);
  job = await status.json();
} while (job.status === 'pending' || job.status === 'processing');

// 3. Save result
if (job.status === 'completed') {
  const buffer = Buffer.from(job.result.data_base64, 'base64');
  require('fs').writeFileSync('screenshot.png', buffer);
  console.log('Done!');
}

PDF Endpoint

GET/v1/pdf

Generate a PDF of any public website. Returns the PDF directly as binary data.

Parameters

ParameterTypeDefaultDescription
urlrequiredstring--The URL to convert to PDF.
formatstringA4Paper size: A4, Letter, Legal, Tabloid, A3.
landscapebooleanfalseUse landscape orientation.
backgroundbooleantruePrint background colors and images.
waitinteger1000Additional wait time in ms after page load.
Example request
curl "https://screenshotapi-api-production.up.railway.app/v1/pdf\
  ?url=https://example.com\
  &format=A4&landscape=true" \
  -H "Authorization: Bearer sk_live_abc123" \
  -o page.pdf

Usage Endpoint

GET/v1/usage

Check your current usage and remaining quota.

Example response
{
  "plan": "pro",
  "used": 1523,
  "limit": 10000,
  "remaining": 8477,
  "reset_date": "2026-04-01"
}

Error Handling

Errors return JSON with an error field.

StatusMeaning
400Bad request (missing/invalid parameters)
401Invalid or missing API key
429Rate limit exceeded or monthly quota reached
504Page load timed out (30 second limit)
500Internal server error
Error response
{
  "error": "URL parameter is required"
}

Rate Limits

API requests are rate-limited per API key. Rate limit headers are included in every response.

HeaderDescription
X-RateLimit-LimitMax requests per minute
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetUnix timestamp when the window resets

Screenshot endpoints are limited to 30 requests per minute. Other endpoints are limited to 120 requests per minute.

Node.js SDK

Our official Node.js SDK makes integration dead simple. Supports CommonJS, ESM, and TypeScript out of the box with zero dependencies.

Installation

npm
npm install screenshotapi-node

Quick Start

Node.js
const { ScreenshotAPI } = require('screenshotapi-node');

const client = new ScreenshotAPI('YOUR_API_KEY');

// Capture a screenshot
const buffer = await client.screenshot('https://example.com', {
  width: 1920,
  height: 1080,
  format: 'png',
  fullPage: true,
});
require('fs').writeFileSync('screenshot.png', buffer);

// Generate a PDF
const pdf = await client.pdf('https://example.com', {
  format: 'A4',
  landscape: true,
});
require('fs').writeFileSync('page.pdf', pdf);

// Async screenshot with polling
const result = await client.screenshotAsync('https://example.com', {
  format: 'png',
});
console.log('Job ID:', result.id);

// Check status
const status = await client.getStatus(result.id);
console.log('Status:', status.status);

// Check usage
const usage = await client.getUsage();
console.log(`Used ${usage.used}/${usage.limit} screenshots`);

Available Methods

MethodDescription
screenshot(url, options)Capture a screenshot, returns Buffer
pdf(url, options)Generate a PDF, returns Buffer
screenshotAsync(url, options)Start async screenshot job
getStatus(jobId)Check async job status
getUsage()Get current usage and quota

Full documentation: See the SDK README on GitHub for complete API reference, TypeScript types, and advanced usage.

Python SDK

Our official Python SDK provides a clean, Pythonic interface to the ScreenshotAPI. Zero dependencies -- uses only the Python standard library.

Installation

pip
pip install screenshotapi

Quick Start

Python
from screenshotapi import ScreenshotAPI

client = ScreenshotAPI("YOUR_API_KEY")

# Capture a screenshot
data = client.screenshot("https://example.com", width=1920, height=1080, format="png")
with open("screenshot.png", "wb") as f:
    f.write(data)

# Generate a PDF
pdf_data = client.pdf("https://example.com", format="A4", landscape=True)
with open("page.pdf", "wb") as f:
    f.write(pdf_data)

# Async screenshot
job = client.screenshot_async("https://example.com", format="png")
print(f"Job ID: {job['id']}")

# Check status
status = client.get_status(job["id"])
print(f"Status: {status['status']}")

# Check usage
usage = client.get_usage()
print(f"Used {usage['used']}/{usage['limit']} screenshots")

Available Methods

MethodDescription
screenshot(url, **kwargs)Capture a screenshot, returns bytes
pdf(url, **kwargs)Generate a PDF, returns bytes
screenshot_async(url, **kwargs)Start async screenshot job
get_status(job_id)Check async job status
get_usage()Get current usage and quota

Full documentation: See the Python SDK README on GitHub for complete API reference and advanced usage.

Code Examples

Node.js

const fs = require('fs');

async function captureScreenshot(url) {
  const response = await fetch(
    `https://screenshotapi-api-production.up.railway.app/v1/screenshot?url=${encodeURIComponent(url)}&format=png`,
    {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error);
  }

  const buffer = Buffer.from(await response.arrayBuffer());
  fs.writeFileSync('screenshot.png', buffer);
  console.log('Screenshot saved!');
}

captureScreenshot('https://example.com');

Python

import requests

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://screenshotapi-api-production.up.railway.app'

def capture_screenshot(url, output='screenshot.png', **kwargs):
    params = {'url': url, 'format': 'png', **kwargs}
    headers = {'Authorization': f'Bearer {API_KEY}'}

    response = requests.get(
        f'{BASE_URL}/v1/screenshot',
        params=params,
        headers=headers
    )
    response.raise_for_status()

    with open(output, 'wb') as f:
        f.write(response.content)

    print(f'Screenshot saved to {output}')
    print(f'Time: {response.headers.get("X-Screenshot-Time-Ms")}ms')

# Basic screenshot
capture_screenshot('https://example.com')

# Full page, mobile viewport
capture_screenshot(
    'https://example.com',
    output='mobile.png',
    width=375,
    height=812,
    fullpage='true'
)

PHP

<?php
$apiKey = 'YOUR_API_KEY';
$url = urlencode('https://example.com');

$ch = curl_init("https://screenshotapi-api-production.up.railway.app/v1/screenshot?url=$url&format=png");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $apiKey"
]);

$screenshot = curl_exec($ch);
curl_close($ch);

file_put_contents('screenshot.png', $screenshot);
echo "Screenshot saved!\n";

Need help? Contact us at support@screenshotapi.dev