Back to dashboard

PageSnap API

Capture screenshots programmatically over a simple REST API. Available on the Pro and Business plans. Manage your keys and webhook in the dashboard API tab.

Authentication

Pass your secret key as a bearer token. Keys start with ps_live_ and are shown only once at creation — store them securely and never expose them in client-side code.

Authorization: Bearer ps_live_xxxxxxxxxxxxxxxx

Capture a screenshot

POST /api/v1/screenshots— synchronous; the response contains the image. Each call counts against your plan's monthly capture quota.

curl -X POST https://pagesnap.dev/api/v1/screenshots \
  -H "Authorization: Bearer ps_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "captureType": "full-page",
    "format": "png"
  }'

Body parameters

FieldTypeNotes
urlstringRequired. The page to capture.
captureTypeenumfull-page (default), viewport, or element-selector.
selectorstringCSS selector. Required when capturing an element.
viewportobject{ width, height } in px. Defaults to 1920×1080.
formatenumpng (default), jpeg, webp.
blockBannersbooleanStrip cookie/consent banners. Default true.
webhookUrlstringOverride the account webhook URL for this request.

Response

{
  "success": true,
  "id": "665f...e21",
  "url": "https://example.com",
  "imageUrl": "data:image/png;base64,iVBORw0KG...",
  "format": "png",
  "captureType": "full-page",
  "processingTime": 2143,
  "fileSize": 184320,
  "createdAt": "2026-06-20T12:00:00.000Z",
  "remaining": 1987
}

In production imageUrl is a base64 data URL; in local development it is a hosted file URL.

Retrieve a capture

GET /api/v1/screenshots/:id — fetch metadata for a capture you created.

curl https://pagesnap.dev/api/v1/screenshots/665f...e21 \
  -H "Authorization: Bearer ps_live_xxxxxxxxxxxxxxxx"

Webhooks

Configure a webhook URL in the dashboard to receive a screenshot.completed or screenshot.failed event after each API capture. The request body is signed with HMAC-SHA256.

POST <your-webhook-url>
X-PageSnap-Event: screenshot.completed
X-PageSnap-Signature: sha256=<hex>

{
  "id": "evt_...",
  "event": "screenshot.completed",
  "created": 1750420800,
  "data": {
    "screenshot": { "id": "665f...e21", "url": "...", "imageUrl": "..." }
  }
}

Verifying the signature

Recompute the HMAC over the raw request body using your signing secret and compare it to the X-PageSnap-Signature header.

import crypto from "crypto";

function isValid(rawBody, signatureHeader, secret) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signatureHeader),
    Buffer.from(expected)
  );
}

Errors & limits

Standard HTTP status codes. Captures count against your monthly quota (the same limit as the web app).

StatusMeaning
400Invalid request body.
401Missing, invalid, or revoked API key.
403Plan does not include API access.
422No element matched the selector.
429Monthly capture limit exceeded.
500Capture failed unexpectedly.