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_xxxxxxxxxxxxxxxxCapture 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
| Field | Type | Notes |
|---|---|---|
| url | string | Required. The page to capture. |
| captureType | enum | full-page (default), viewport, or element-selector. |
| selector | string | CSS selector. Required when capturing an element. |
| viewport | object | { width, height } in px. Defaults to 1920×1080. |
| format | enum | png (default), jpeg, webp. |
| blockBanners | boolean | Strip cookie/consent banners. Default true. |
| webhookUrl | string | Override 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).
| Status | Meaning |
|---|---|
| 400 | Invalid request body. |
| 401 | Missing, invalid, or revoked API key. |
| 403 | Plan does not include API access. |
| 422 | No element matched the selector. |
| 429 | Monthly capture limit exceeded. |
| 500 | Capture failed unexpectedly. |