POST /v1/screenshot
Render a page with a headless Playwright browser and return a screenshot.
Storage modes: If Cloudflare R2 is configured (CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_R2_ACCESS_KEY_ID, CLOUDFLARE_R2_SECRET_ACCESS_KEY, CLOUDFLARE_R2_BUCKET_NAME all set), the screenshot is uploaded and the response contains imageUrl. Otherwise the image is returned as a base64 string in the response body.
The screenshot engine first tries @ss/engine/media and falls back to an inline Playwright implementation. If neither is available the endpoint returns HTTP 503.
Request
POST /v1/screenshot
Content-Type: application/json
x-api-key: YOUR_KEYBody
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes | The URL to screenshot. Must be a valid http:// or https:// URL. | |
fullPage | boolean | No | true | Capture the full scrollable page height. Set to false for viewport-only. |
width | number | No | 1280 | Viewport width in pixels. |
mobile | boolean | No | false | Emulate a mobile device (iPhone viewport, mobile UA). |
waitFor | number | No | 1000 | Additional delay in milliseconds after domcontentloaded before taking the screenshot. |
cookies | string | No | JSON array of cookie objects ([{"name":"…","value":"…","domain":"…"}]). Injected before page load. | |
element | string | No | CSS selector. When provided, only the first matching element is captured instead of the full page. | |
format | "png" | "jpeg" | No | "png" | Image format. |
Example request, full page
curl -X POST https://api.superscraper.dev/v1/screenshot \
-H "x-api-key: ss_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.yelp.com/biz/acme-plumbing-austin",
"fullPage": true,
"width": 1440,
"waitFor": 1500
}'Example request, mobile viewport
curl -X POST https://api.superscraper.dev/v1/screenshot \
-H "x-api-key: ss_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"mobile": true,
"format": "jpeg"
}'Example request, element capture
curl -X POST https://api.superscraper.dev/v1/screenshot \
-H "x-api-key: ss_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/pricing",
"element": ".pricing-table"
}'Response
HTTP 200 on success.
Body, R2 configured (URL response)
| Field | Type | Description |
|---|---|---|
url | string | The URL that was screenshotted |
imageUrl | string | Public URL of the uploaded image in Cloudflare R2 |
width | number | Captured image width in pixels |
height | number | Captured image height in pixels |
format | string | Image format: "png" or "jpeg" |
latencyMs | number | Time to render and capture in milliseconds |
dailyLimit | number | Your tier's daily screenshot quota |
Body, R2 not configured (base64 response)
| Field | Type | Description |
|---|---|---|
url | string | The URL that was screenshotted |
base64 | string | Raw base64-encoded image bytes |
width | number | Captured image width in pixels |
height | number | Captured image height in pixels |
format | string | Image format: "png" or "jpeg" |
latencyMs | number | Time to render and capture in milliseconds |
dailyLimit | number | Your tier's daily screenshot quota |
Example response, R2 configured
{
"url": "https://www.yelp.com/biz/acme-plumbing-austin",
"imageUrl": "https://screenshots.superscraper.dev/screenshots/tenant_abc/f47ac10b-58cc.png",
"width": 1440,
"height": 4820,
"format": "png",
"latencyMs": 3210,
"dailyLimit": 1000
}Example response, base64 fallback
{
"url": "https://example.com",
"base64": "iVBORw0KGgoAAAANSUhEUgAAB...",
"width": 1280,
"height": 3400,
"format": "png",
"latencyMs": 2840,
"dailyLimit": 10
}Daily limits by tier
| Plan | Screenshots / day |
|---|---|
| Free | 10 |
| Hobby | 100 |
| Pro | 1 000 |
| Scale | 5 000 |
| Custom | 50 000 |
The response includes your plan's dailyLimit for screenshots so clients can track usage.
Errors
| Status | Error | Cause |
|---|---|---|
| 400 | `url` is required | url field missing |
| 400 | Invalid URL | URL is not a valid http(s):// URL |
| 400 | Invalid JSON body | Malformed request body |
| 401 | API key required | Missing x-api-key header |
| 429 | Rate limit exceeded | Too many requests in the sliding window |
| 500 | Screenshot failed: <message> | Playwright error during capture |
| 503 | Screenshot engine unavailable | Playwright and @ss/engine/media are both not installed |
Notes
- R2 upload failures fall back gracefully to base64, a failed upload never causes a 500.
- When
elementis specified, theheightfield reflects the element's bounding box height. - Mobile emulation uses an iPhone UA and
isMobile: truein Playwright context. - Cookies must be valid JSON (
[{"name":"sid","value":"abc","domain":"example.com"}]), not Netscape cookie-jar format.