API reference
One endpoint captures a screenshot and returns the image. Two more let you fetch it again for seven days. The machine-readable description is at /openapi.json.
Authentication
Create a key in the dashboard under API keys. Send it as a bearer token. Keys start with sk_, are shown once and can be revoked at any time. Keep them on your server; never ship one in browser or mobile code.
Authorization: Bearer sk_…
Capture a screenshot
POST /v1/screenshots with a JSON body. The response body is the image. The X-Screenshot-Id and X-Expires-At headers identify the stored copy. Requests take a few seconds and time out after about 45 seconds.
curl --fail-with-body "https://your-domain.com/v1/screenshots" \-H "Authorization: Bearer $SCREENSHOT_API_KEY" \-H "Content-Type: application/json" \-d '{"url":"https://example.com","device":"desktop","format":"png"}' \-o screenshot.png
const response = await fetch(`https://your-domain.com/v1/screenshots`, {method: "POST",headers: {Authorization: `Bearer ${process.env.SCREENSHOT_API_KEY}`,"Content-Type": "application/json",},body: JSON.stringify({url: "https://example.com",device: "mobile",format: "webp",fullPage: true,}),});if (!response.ok) throw new Error((await response.json()).error.message);const id = response.headers.get("X-Screenshot-Id");const image = Buffer.from(await response.arrayBuffer());
Options
| Field | Values | Default | Description |
|---|---|---|---|
| url | string | required | Public http or https URL, up to 2,048 characters. Credentials in the URL and private or local hosts are rejected. |
| device | device id | desktop | Viewport and frame preset, for example macbook-pro-14, iphone-17-pro or ipad-air-11. See the device list in the docs. |
| format | png | jpeg | webp | png | Image format of the response. |
| fullPage | boolean | false | Capture the whole scrollable page. Very large pages are rejected. |
| cleanup | boolean | true | Best-effort removal of cookie banners and common ad requests before capture. |
| frame | boolean | false | Draw the capture inside the matching device: MacBook, iMac, iPhone, iPad and more. |
Unknown fields are rejected so typos do not silently change the result.
Devices
Pass any id as device. Sizes are CSS pixels, the same viewport the hardware reports. Phones, tablets and MacBooks are captured at 2x (sharp on Retina) unless fullPage is set. With frame the capture is placed inside sourced device artwork where available. Full-page captures always disable frames.
Standard
| Id | Device | Viewport | Frame |
|---|---|---|---|
| desktop | Desktop | 1440 × 1000 | laptop |
| hd | HD | 1280 × 720 | desktop monitor |
| laptop | Laptop | 1366 × 768 | laptop |
| laptop-wide | Laptop wide | 1536 × 864 | laptop |
| full-hd | Full HD | 1920 × 1080 | desktop monitor |
| qhd | QHD | 2560 × 1440 | desktop monitor |
| tablet | Tablet | 768 × 1024 | tablet |
| mobile | Mobile | 390 × 844 | phone |
Mac
| Id | Device | Viewport | Frame |
|---|---|---|---|
| macbook-air-13 | MacBook Air 13″ | 1470 × 956 | MacBook |
| macbook-air-15 | MacBook Air 15″ | 1710 × 1107 | MacBook |
| macbook-pro-14 | MacBook Pro 14″ | 1512 × 982 | MacBook |
| macbook-pro-16 | MacBook Pro 16″ | 1728 × 1117 | MacBook |
| imac-24 | iMac 24″ | 2240 × 1260 | iMac |
| studio-display | Studio Display | 2560 × 1440 | Studio Display |
iPhone
| Id | Device | Viewport | Frame |
|---|---|---|---|
| iphone-17-pro-max | iPhone 17 Pro Max / 16 Pro Max | 440 × 956 | iPhone |
| iphone-17-pro | iPhone 17 Pro / 17 / 16 Pro | 402 × 874 | iPhone |
| iphone-air | iPhone Air | 420 × 912 | iPhone |
| iphone-16-plus | iPhone 16 Plus / 15 Plus | 430 × 932 | iPhone |
| iphone-16 | iPhone 16 / 15 / 15 Pro | 393 × 852 | iPhone |
| iphone-16e | iPhone 16e / 14 / 13 | 390 × 844 | iPhone |
| iphone-13-mini | iPhone 13 mini | 375 × 812 | iPhone |
| iphone-se | iPhone SE | 375 × 667 | iPhone |
iPad
| Id | Device | Viewport | Frame |
|---|---|---|---|
| ipad-pro-13 | iPad Pro 13″ | 1032 × 1376 | iPad |
| ipad-pro-11 | iPad Pro 11″ | 834 × 1210 | iPad |
| ipad-air-13 | iPad Air 13″ | 1024 × 1366 | iPad |
| ipad-air-11 | iPad Air 11″ / iPad | 820 × 1180 | iPad |
| ipad-mini | iPad mini | 744 × 1133 | iPad |
| ipad-classic | iPad 9th gen | 810 × 1080 | iPad |
Android
| Id | Device | Viewport | Frame |
|---|---|---|---|
| android | Android phone | 412 × 915 | Android phone |
| android-compact | Android compact | 360 × 800 | Android phone |
Retrieve a screenshot
Use the ID from the capture response. Metadata and image are only available to the key owner and until the expiry time.
curl "https://your-domain.com/v1/screenshots/$ID" \-H "Authorization: Bearer $SCREENSHOT_API_KEY"curl "https://your-domain.com/v1/screenshots/$ID/image" \-H "Authorization: Bearer $SCREENSHOT_API_KEY" \-o screenshot.png
{"id": "3f0c0f1e-…","status": "succeeded","options": { "url": "https://example.com/", "device": "desktop", "format": "png", "fullPage": false, "frame": false, "cleanup": true },"createdAt": "2026-11-10T09:00:00.000Z","expiresAt": "2026-11-17T09:00:00.000Z"}
status is succeeded, failed or, briefly while a capture is being finalized, pending or finalizing.
Errors
Errors are JSON with a stable code. Quote the requestId when reporting a problem.
{"error": {"code": "invalid_request","message": "Invalid capture options.","requestId": "b9e1…"}}
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The body or an option is invalid. |
| 401 | unauthorized | The API key is missing, invalid or revoked. |
| 404 | not_found | The screenshot does not exist, has expired or is not yours. |
| 409 | key_limit_reached | Dashboard only: too many active API keys. |
| 502 | capture_failed | The website could not be captured, for example it blocked the browser or returned an error. |
| 503 | capture_unavailable | Capture is temporarily unavailable. Retry shortly. |
| 503 | capture_finalization_pending | The result is being finalized. Fetch it later with the X-Screenshot-Id header. |
| 504 | capture_timeout | The page did not finish loading in time. |
Limits and behavior
- Screenshots are private and expire seven days after creation.
- Images larger than 10 MB, and pages larger than 4096 px wide or 10,000 px tall in full-page mode, are rejected.
- Only public http and https addresses are captured. Private, loopback and internal hosts are refused.
- Cleanup is best effort. Some sites block automated browsers.
- There are no account quotas during launch, but the service can slow or refuse requests under load. Retry 503 and 504 with backoff.