API Documentation

Everything you need to integrate Pixcap's screenshot API into your application.

Introduction

Pixcap provides a simple REST API to capture high-quality screenshots of any public website. Make an HTTP request with a target URL, and receive a pixel-perfect screenshot in return.

Base URL

https://pixcap.dev/api/v1

Authentication

All API requests require authentication using an API key. You can pass your key in two ways:

Header (Recommended)

X-API-Key: pix_your_api_key_here

Query Parameter

?api_key=pix_your_api_key_here
Keep your API key secure. Never expose it in client-side code or public repositories.

Quick Start

Capture your first screenshot in seconds:

cURL

curl "https://pixcap.dev/api/v1/screenshot?url=https://github.com" \
  -H "X-API-Key: pix_your_api_key" \
  -o screenshot.png

Node.js

const response = await fetch(
  'https://pixcap.dev/api/v1/screenshot?url=https://github.com',
  { headers: { 'X-API-Key': 'pix_your_api_key' } }
);
const buffer = await response.arrayBuffer();
fs.writeFileSync('screenshot.png', Buffer.from(buffer));

Python

import requests

response = requests.get(
    'https://pixcap.dev/api/v1/screenshot',
    params={'url': 'https://github.com'},
    headers={'X-API-Key': 'pix_your_api_key'}
)

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

GET /screenshot

Capture a screenshot and receive the image directly in the response body.

GET /api/v1/screenshot

Example

GET /api/v1/screenshot?url=https://stripe.com&width=1440&format=png

Response Headers

Header Description
Content-Type image/png or image/jpeg
X-Screenshot-Width Actual width of screenshot
X-Screenshot-Height Actual height of screenshot
X-Response-Time Time to capture (e.g., "2340ms")
X-Credits-Remaining Your remaining credit balance

POST /screenshot

Capture a screenshot and receive a JSON response with base64-encoded image.

POST /api/v1/screenshot

Request Body

{
  "url": "https://github.com",
  "width": 1920,
  "height": 1080,
  "format": "png",
  "fullPage": false
}

Response

200 OK
{
  "success": true,
  "data": {
    "image": "iVBORw0KGgoAAAANSUhEUgAA...",
    "metadata": {
      "url": "https://github.com",
      "width": 1920,
      "height": 1080,
      "format": "png",
      "responseTimeMs": 2340,
      "timestamp": "2024-01-15T10:30:00.000Z"
    },
    "credits_remaining": 95
  }
}

Parameters

Parameter Type Required Description
url string Required The URL to capture. Must be http or https.
width integer Optional Viewport width (320-3840). Default: 1280
height integer Optional Viewport height (200-2160). Default: 800
format string Optional "png" or "jpeg". Default: "png"
quality integer Optional JPEG quality (1-100). Default: 80
full_page boolean Optional Capture full scrollable page. Default: false
delay integer Optional Wait time in ms after load (0-10000)
selector string Optional CSS selector to capture specific element
dark_mode boolean Optional Emulate dark mode. Default: false
scale number Optional Device scale factor (1-3). Default: 1
cookies array Optional Array of cookie objects to set before loading. Each: {name, value, domain?, path?}
block_selectors array Optional CSS selectors to hide (e.g., [".modal", ".cookie-banner"])
wait_for_selector string Optional Wait for this CSS selector to appear before capturing
dismiss_cookie_consent boolean Optional Auto-dismiss common cookie consent banners. Default: false

Advanced Options

Setting Cookies

Pass cookies to capture authenticated pages or maintain session state:

// POST request with cookies
{
  "url": "https://example.com/dashboard",
  "cookies": [
    {
      "name": "session_id",
      "value": "abc123xyz",
      "domain": "example.com"
    },
    {
      "name": "auth_token",
      "value": "Bearer_token_here",
      "domain": ".example.com",
      "path": "/"
    }
  ]
}

Blocking Elements

Hide modals, popups, banners, or any other elements before capturing:

// Hide cookie banners and modals
{
  "url": "https://example.com",
  "blockSelectors": [
    ".cookie-banner",
    ".newsletter-popup",
    "#modal-overlay",
    "[data-testid='promo-banner']"
  ]
}

Waiting for Content

Wait for dynamic content to load before capturing (useful for SPAs):

// Wait for main content to render
{
  "url": "https://spa-example.com",
  "waitForSelector": ".main-content-loaded",
  "delay": 500
}

Auto-Dismiss Cookie Consent

Automatically click common "Accept" buttons on cookie consent banners:

// Dismiss cookie banners automatically
{
  "url": "https://news-site.com",
  "dismissCookieConsent": true
}

This works with most major cookie consent providers including OneTrust, Cookiebot, and common custom implementations.

Bulk Screenshots

Capture screenshots of an entire website by providing a sitemap XML URL. Perfect for creating visual archives, monitoring site-wide changes, or generating preview images at scale.

How it works: Submit a sitemap URL, and we'll capture screenshots of every page (up to 100). Download everything as a ZIP file with directory structure matching your website.

Key Features

Create Bulk Job

Submit a sitemap URL to start capturing screenshots of all pages.

POST /api/v1/bulk-screenshot

Request Body

You can provide either a url (auto-detects sitemap) or sitemap_url (explicit sitemap):

// Option 1: Auto-detect sitemap (recommended)
{
  "url": "example.com",
  "options": { "maxPages": 50 }
}

// Option 2: Explicit sitemap URL
{
  "sitemap_url": "https://example.com/sitemap.xml",
  "options": { "maxPages": 50 }
}
Auto-detection: When using url, we check robots.txt and common paths like /sitemap.xml to find the sitemap automatically. Works with or without https://.
Parameter Type Required Description
url string Option 1 Website URL - sitemap will be auto-detected
sitemap_url string Option 2 Direct URL to sitemap XML file
options.maxPages integer Optional Maximum pages to capture (1-100). Default: 100
options.width integer Optional Viewport width. Default: 1280
options.height integer Optional Viewport height. Default: 800
options.format string Optional "png" or "jpeg". Default: "png"
options.fullPage boolean Optional Capture full scrollable page. Default: false

Response

202 Accepted
{
  "success": true,
  "data": {
    "job_id": "f147c641-f644-429c-8395-2ed9cdf30154",
    "status": "pending",
    "sitemap_url": "https://example.com/sitemap.xml",
    "total_urls": 42,
    "credits_reserved": 42,
    "credits_remaining": 58,
    "status_url": "/api/v1/bulk-screenshot/f147c641.../status"
  }
}

Check Job Status

Poll this endpoint to track the progress of your bulk screenshot job.

GET /api/v1/bulk-screenshot/:jobId/status

Response

200 OK
{
  "success": true,
  "data": {
    "jobId": "f147c641-f644-429c-8395-2ed9cdf30154",
    "status": "completed",
    "sitemapUrl": "https://example.com/sitemap.xml",
    "progress": {
      "totalUrls": 42,
      "processed": 42,
      "successful": 40,
      "failed": 2,
      "percentage": 100
    },
    "credits": {
      "reserved": 42,
      "used": 40,
      "refunded": 2
    },
    "download": {
      "expiresAt": "2024-01-16T10:30:00.000Z",
      "fileSize": 15728640
    }
  }
}

Job Status Values

Status Description
pending Job created, waiting to start
processing Screenshots being captured
packaging Creating ZIP file
completed Ready for download
failed Job failed (credits refunded)

Download ZIP

Download the completed screenshot archive. Available for 24 hours after completion.

GET /api/v1/bulk-screenshot/:jobId/download

ZIP Structure

screenshots-example-com-2024-01-15/
  _manifest.json        # Job metadata and URL list
  index.png             # https://example.com/
  about/
    index.png           # https://example.com/about/
  blog/
    index.png           # https://example.com/blog/
    my-post.png         # https://example.com/blog/my-post

Example Workflow

# 1. Create a bulk job (sitemap auto-detected)
curl -X POST "https://pixcap.dev/api/v1/bulk-screenshot" \
  -H "X-API-Key: pix_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "example.com", "options": {"maxPages": 20}}'

# 2. Check status (poll until completed)
curl "https://pixcap.dev/api/v1/bulk-screenshot/{job_id}/status" \
  -H "X-API-Key: pix_your_api_key"

# 3. Download ZIP when ready
curl "https://pixcap.dev/api/v1/bulk-screenshot/{job_id}/download" \
  -H "X-API-Key: pix_your_api_key" \
  -o screenshots.zip

VPN Connectors

Capture screenshots of internal websites without exposing them to the internet. Deploy a lightweight connector inside your network to screenshot private dashboards, staging environments, and internal applications.

How it works: The connector establishes an outbound WebSocket connection to Pixcap cloud. When you make a screenshot request with a connector_id, we route it through your connector. Your internal URLs are never exposed to the internet.

Architecture

┌─────────────────┐      ┌──────────────────┐      ┌─────────────────┐
│  Your App       │      │  Pixcap Cloud    │      │  Connector      │
│                 │      │                  │      │  (Your Network) │
└────────┬────────┘      └────────┬─────────┘      └────────┬────────┘
         │                        │                         │
         │ 1. API Request         │                         │
         │ with connector_id      │                         │
         │───────────────────────>│                         │
         │                        │                         │
         │                        │ 2. Route via WebSocket  │
         │                        │────────────────────────>│
         │                        │                         │
         │                        │              3. Capture screenshot
         │                        │                 of internal URL
         │                        │                         │
         │                        │ 4. Return image         │
         │                        │<────────────────────────│
         │                        │                         │
         │ 5. Screenshot response │                         │
         │<───────────────────────│                         │

Key Benefits

Quick Start

Get up and running in under 5 minutes:

1. Create a Connector

Log in to your dashboard, scroll to the VPN Connectors section, and click "Create New Connector". Copy the token—it's only shown once.

2. Deploy the Connector

docker run -d \
  -e PIXCAP_CONNECTOR_TOKEN=pxc_your_token \
  --restart unless-stopped \
  --name pixcap-connector \
  dashah2/pixcap-connector

3. Take a Screenshot

Once your connector shows "Online" in the dashboard, make a request with your connector_id:

curl "https://pixcap.dev/api/v1/screenshot?url=http://internal.example.com&connector_id=conn_YOUR_ID" \
  -H "X-API-Key: pix_YOUR_API_KEY" \
  -o screenshot.png

Installation

Docker (Recommended)

docker run -d \
  -e PIXCAP_CONNECTOR_TOKEN=pxc_your_token \
  --restart unless-stopped \
  --name pixcap-connector \
  dashah2/pixcap-connector

Docker Compose

version: '3.8'
services:
  pixcap-connector:
    image: dashah2/pixcap-connector:latest
    environment:
      - PIXCAP_CONNECTOR_TOKEN=${PIXCAP_CONNECTOR_TOKEN}
    restart: unless-stopped

npm

npm install -g pixcap-connector
PIXCAP_CONNECTOR_TOKEN=pxc_your_token pixcap-connector

From Source

git clone https://github.com/dan-shah/pixcap.git
cd dashah2/pixcap-connector
npm install
PIXCAP_CONNECTOR_TOKEN=pxc_your_token npm start

Configuration

Configure the connector using environment variables:

Variable Default Description
PIXCAP_CONNECTOR_TOKEN Required Your connector token from the dashboard
PIXCAP_API_URL wss://pixcap.dev/ws/connector WebSocket endpoint URL
SCREENSHOT_TIMEOUT 30000 Screenshot timeout in milliseconds
PUPPETEER_EXECUTABLE_PATH (auto-detect) Path to Chrome/Chromium executable
DEFAULT_VIEWPORT_WIDTH 1280 Default viewport width
DEFAULT_VIEWPORT_HEIGHT 800 Default viewport height

API Reference

Use the connector_id parameter to route screenshot requests through your connector.

GET Request

GET /api/v1/screenshot?url=...&connector_id=conn_xxx
curl "https://pixcap.dev/api/v1/screenshot?url=http://internal-app.local&connector_id=conn_abc123" \
  -H "X-API-Key: pix_your_api_key" \
  -o screenshot.png

POST Request

POST /api/v1/screenshot
{
  "url": "http://internal-app.local:3000/dashboard",
  "connectorId": "conn_abc123",
  "width": 1920,
  "height": 1080
}

Connector Parameter

Parameter Type Description
connector_id / connectorId string Your connector ID (from the dashboard). When specified, the request is routed through your connector instead of Pixcap cloud.

Response Headers

When a request is routed through a connector, an additional header is included:

Header Description
X-Connector-Used The connector ID that processed the request

Connector Error Codes

Code Status Description
CONNECTOR_NOT_FOUND 404 Connector ID doesn't exist or doesn't belong to your account
CONNECTOR_OFFLINE 503 Connector is not currently connected
CONNECTOR_TIMEOUT 504 Connector didn't respond in time

Manage Connectors

Create and manage connectors via API or dashboard.

List Connectors

GET /api/v1/connectors

Create Connector

POST /api/v1/connectors
{
  "name": "Office Network"
}

Delete Connector

DELETE /api/v1/connectors/:connectorId

Regenerate Token

POST /api/v1/connectors/:connectorId/regenerate-token

Troubleshooting

Connector shows "Offline"

  1. Check the connector is running: docker logs pixcap-connector
  2. Verify your token is correct and hasn't been regenerated
  3. Ensure outbound WebSocket connections are allowed (port 443)
  4. Check for firewall rules blocking wss://pixcap.dev

Screenshots timeout

  1. Increase SCREENSHOT_TIMEOUT environment variable
  2. Check if the target URL is accessible from the connector host
  3. Verify Chrome/Chromium is installed correctly
  4. Test connectivity: docker exec pixcap-connector curl http://your-internal-url

Browser launch fails

Set the Chrome path explicitly:

# Linux
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium

# macOS
PUPPETEER_EXECUTABLE_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"

# Docker (usually auto-detected)
# The Docker image includes Chromium

Connection keeps dropping

  1. The connector includes auto-reconnect with exponential backoff
  2. Check for proxy or firewall issues with WebSocket connections
  3. Review logs for disconnection reasons: docker logs -f pixcap-connector
Need help? Check the GitHub issues or contact support@pixcap.dev

Register

Create a new account and receive your API key.

POST /api/v1/keys/register

Request

{
  "email": "you@company.com"
}

Response

201 Created
{
  "success": true,
  "data": {
    "message": "Account created successfully",
    "email": "you@company.com",
    "api_key": "pix_a1b2c3d4e5f6...",
    "credits": 100
  }
}
Save your API key! It's only shown once during registration.

API Keys

You can create up to 5 API keys per account.

Create New Key

POST /api/v1/keys/create

Deactivate Key

DELETE /api/v1/keys/:keyId

Error Codes

Code Status Description
API_KEY_REQUIRED 401 No API key provided
INVALID_API_KEY 401 API key is invalid or inactive
INSUFFICIENT_CREDITS 402 No credits remaining
INVALID_URL 400 URL is not valid
URL_BLOCKED 400 URL is blocked (localhost, internal IPs)
RATE_LIMIT_EXCEEDED 429 Too many requests
CAPTURE_ERROR 500 Failed to capture screenshot

Rate Limits

To ensure fair usage and platform stability:

Endpoint Limit Window
/screenshot 60 requests 1 minute
/bulk-screenshot 10 jobs 1 hour
General API 100 requests 1 minute
Registration 10 requests 15 minutes

Rate limit headers are included in all responses: