Screenshot API
One POST turns a public URL into a screenshot. Pick an authentication route, send JSON, get a presigned image link.
Quick start
Issue a key on your account page, then call the endpoint with Bearer auth:
# API Key auth — issue your key on the account page
curl -X POST https://websitescreenshot.litelake.com/api/open/screenshot \
-H "Authorization: Bearer lws_dev_…" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","format":"png","device":"pc","full_page":false}'Authentication
Three ways in, one contract: the request body and response are identical, only the endpoint and the daily quota differ.
Anonymous trial — POST /api/public/screenshot
No account needed. 10 captures per day per IP, one capture in flight at a time.
Signed-in — POST /api/user/screenshot
The tool page uses your session after sign-in and counts against the free tier: 1,000 captures per day.
API Key — POST /api/open/screenshot
Bearer auth (Authorization: Bearer lws_…) with the full parameter surface. Internal-tier keys are unlimited; responses carry X-RateLimit-* headers and 429s include Retry-After.
Parameters
| Parameter | Type | Description |
|---|---|---|
| url | string | Required. Full public URL starting with http:// or https://, up to 2048 characters. |
| format | "png" | "jpg" | Image format. Defaults to png. |
| device | "pc" | "mobile" | Device preset: pc = 1920×1080 with a desktop user agent, mobile = 390×844 with a mobile user agent. Defaults to pc. |
| full_page | boolean | Capture the full scrollable page instead of the first screen. Defaults to false. |
Response
HTTP 200 with an envelope: data.image_url is a presigned download link valid for 1 hour; cached=true means the 1-day cache returned the same capture.
{
"code": 200, "message": "ok",
"data": {
"image_url": "https://…(presigned GET, valid 1h)",
"cached": false,
"final_url": "https://example.com/",
"title": "Example Domain",
"width": 1920, "height": 1080,
"task_id": "…",
"cache_expires_at": "2026-10-12T08:00:00Z"
}
}Error codes
The public/open endpoints return real HTTP status codes plus a 4-digit business code in body.code. 429 responses carry a Retry-After header; successful open calls carry X-RateLimit-Limit / Remaining / Reset.
| Code | HTTP | Meaning |
|---|---|---|
| 4001 | 400 | url_invalid — the URL is not a full http/https address. |
| 4002 | 400 | ssrf_blocked — the target is a private or reserved address; only public sites are supported. |
| 4003 | 400 | page_load_failed — the site could not be loaded or refused the capture (including too many redirects). |
| 4004 | 400 | invalid_options — a parameter is outside the supported range. |
| 4005 | 400 | empty_output — the capture produced no image. |
| 5041 | 504 | page_timeout — the target site was too slow (75-second product-level limit). |
| 4290 | 429 | Minute-level rate limit; retry after the Retry-After window. |
| 4291 | 429 | Daily quota exhausted; Retry-After points to the next 00:00 UTC. |
| 4292 | 429 | Concurrency limit — the same identity already has a capture in flight. |
| 5001 | 503 | The capture backend is busy or unreachable. Submit again later. |
| 5004 | 503 | A service dependency (storage) is temporarily unavailable; the request was rejected instead of served incorrectly. Retry shortly. |
| 5002 | 500 | Saving the screenshot to storage failed; retrying usually works. |
Get an API key
Sign in and issue up to three active keys on your account page. The full key is shown only once, at issuance. Open your account page
Limits & notes
- Screenshots are cached for 1 day — identical requests in the window return the stored image instead of re-capturing.
- Anonymous callers can run one capture at a time (HTTP 429, code 4292 otherwise).
- Full-page capture renders the whole scrollable page; extremely long pages can be slow — switch to first screen or JPG if needed.
- Captures time out at about 75 seconds. If a site keeps timing out, retry later, or turn off full page / switch to JPG.