API Documentation

The ScreenshotAPI lets you capture pixel-perfect website screenshots with a simple HTTP request. This guide covers everything you need to get started.

Authentication

All API requests require an API key. Include it in the X-API-Key header:

curl -H "X-API-Key: ss_your_api_key_here" https://api.pandan.is/api/screenshot

Get your API key by creating a free account. You can also pass the key as a query parameter: ?api_key=ss_your_key

Base URL

https://api.pandan.is

All endpoints are relative to this base URL.

Take Screenshot

POST /api/screenshot

Capture a screenshot of any website. Returns the image/PDF directly in the response body.

Request Parameters

ParameterTypeDefaultDescription
url required string The URL to capture. Must be http:// or https://
width integer 1280 Viewport width in pixels (320–3840)
height integer 720 Viewport height in pixels (200–2160)
format string png Output format: png, jpeg, or pdf
fullPage boolean false Capture the entire scrollable page
delay integer 0 Wait time in ms before capture (max 10000)
quality integer JPEG quality 1–100 (only for jpeg format)

Response

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

Response headers include:

Example Request

curl -X POST https://api.pandan.is/api/screenshot \
  -H "X-API-Key: ss_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://github.com",
    "width": 1920,
    "height": 1080,
    "format": "png",
    "fullPage": false
  }' \
  --output screenshot.png

Health Check

GET /api/health

Check API status. No authentication required.

// Response
{
  "status": "ok",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "version": "1.0.0",
  "queue": {
    "running": 2,
    "queued": 0,
    "maxConcurrent": 5
  }
}

Register

POST /api/auth/register

Create a new account and receive an API key.

curl -X POST https://api.pandan.is/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "your_password"}'

Login

POST /api/auth/login

Sign in and receive a JWT token for dashboard access.

Account Info

GET /api/me

Get your account details, usage stats, and API keys. Requires JWT authentication via Authorization: Bearer <token> header.

cURL Example

# Basic screenshot
curl -X POST https://api.pandan.is/api/screenshot \
  -H "X-API-Key: ss_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' \
  --output screenshot.png

# Full-page JPEG with quality
curl -X POST https://api.pandan.is/api/screenshot \
  -H "X-API-Key: ss_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "format": "jpeg", "quality": 85, "fullPage": true}' \
  --output full-page.jpg

# PDF export
curl -X POST https://api.pandan.is/api/screenshot \
  -H "X-API-Key: ss_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "format": "pdf"}' \
  --output page.pdf

Python Example

import requests

API_KEY = "ss_your_api_key"
BASE_URL = "https://api.pandan.is"

def take_screenshot(url, **kwargs):
    response = requests.post(
        f"{BASE_URL}/api/screenshot",
        headers={"X-API-Key": API_KEY},
        json={"url": url, **kwargs}
    )
    response.raise_for_status()
    return response.content

# Basic screenshot
img = take_screenshot("https://github.com")
with open("screenshot.png", "wb") as f:
    f.write(img)

# Full-page with custom size
img = take_screenshot(
    "https://github.com",
    width=1920,
    height=1080,
    fullPage=True,
    format="jpeg",
    quality=90
)
with open("full.jpg", "wb") as f:
    f.write(img)

Node.js Example

import fs from 'fs';

const API_KEY = 'ss_your_api_key';

async function screenshot(url, options = {}) {
  const res = await fetch('https://api.pandan.is/api/screenshot', {
    method: 'POST',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ url, ...options })
  });

  if (!res.ok) {
    throw new Error(await res.text());
  }

  return Buffer.from(await res.arrayBuffer());
}

// Usage
const img = await screenshot('https://github.com', {
  width: 1920,
  format: 'png'
});
fs.writeFileSync('screenshot.png', img);

PHP Example

<?php

function takeScreenshot($url, $options = []) {
    $apiKey = 'ss_your_api_key';
    $payload = array_merge(['url' => $url], $options);

    $ch = curl_init('https://api.pandan.is/api/screenshot');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "X-API-Key: $apiKey",
            'Content-Type: application/json'
        ],
        CURLOPT_POSTFIELDS => json_encode($payload)
    ]);

    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

// Usage
$screenshot = takeScreenshot('https://github.com', [
    'width' => 1920,
    'format' => 'jpeg',
    'quality' => 85
]);
file_put_contents('screenshot.jpg', $screenshot);

Rate Limits

Rate limits are applied per API key based on your plan:

PlanScreenshots/MonthRequests/MinutePrice
Free1005$0
Pro5,00030$9/mo
Business25,00060$29/mo
Scale100,000120$79/mo

When you exceed the rate limit, you'll receive a 429 response. The X-Usage-Remaining header in each response tells you how many screenshots remain in your current billing period.

Error Handling

The API returns standard HTTP status codes:

200 Success — Screenshot captured

400 Bad Request — Invalid parameters (missing URL, bad format, etc.)

401 Unauthorized — Missing or invalid API key

429 Rate Limited — Monthly limit exceeded or too many requests

504 Timeout — Target page took too long to load

Error responses are JSON:

{
  "error": "Monthly limit exceeded",
  "limit": 100,
  "used": 100,
  "plan": "free",
  "message": "Upgrade your plan for more screenshots"
}

Ready to start?

Get your free API key and start capturing screenshots in seconds.

Get Free API Key →