Start with the boundary
Separate screenshot transport from browser automation.
Browserless exposes a browser platform. Latchshot exposes a guarded render endpoint. The contracts overlap for a direct public-URL screenshot, but not for arbitrary browser execution. Inventory the current request body before changing providers.
Good migration candidate
Public URL in, image bytes out.
- Input
- One public HTTP or HTTPS page on port 80 or 443
- Controls
- Viewport, PNG or JPEG, quality, full page, bounded lazy-content scrolling, lifecycle wait, and a short delay
- Output
- Application-owned image bytes returned synchronously
Keep Browserless
The request operates a browser.
- Runtime
- CDP, Puppeteer, Playwright, BrowserQL, or function execution is part of the job
- Page state
- Inline HTML, headers, cookies, authentication, scripts, selectors, or clip coordinates are required
- Reach
- Private targets, non-standard ports, proxy geography, or browser-region selection is required
Browserless is a product of its respective owner. This page maps only the public-URL screenshot slice. Confirm the current Browserless Screenshot API documentation and the exact request your application sends.
Move the token out of the endpoint URL.
Browserless commonly authenticates its REST endpoint with a query token. Latchshot requires the key in an HTTPS Bearer header. Keep both credentials server-side and never place either one in browser code, logs, a target URL, or a public issue.
Before: Browserless Screenshot API
curl -fSL \
"https://production-sfo.browserless.io/screenshot?token=$BROWSERLESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com",
"options": {
"type": "jpeg",
"quality": 80,
"fullPage": true
},
"viewport": { "width": 1440, "height": 900 },
"gotoOptions": { "waitUntil": "networkidle0", "timeout": 15000 },
"waitForTimeout": 1000
}' \
-o before.jpg
After: Latchshot render endpoint
curl -fSL \
'https://latchshot.fly.dev/v1/render' \
-H "Authorization: Bearer $LATCHSHOT_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com",
"kind": "screenshot",
"format": "jpeg",
"quality": 80,
"width": 1440,
"height": 900,
"fullPage": true,
"scrollPage": true,
"waitUntil": "networkidle",
"timeout": 15000,
"delay": 1000
}' \
-o after.jpg
Both examples return the image directly. If the surrounding code converts the Browserless response to a buffer, base64 string, object-store upload, or application artifact, keep that ownership step unchanged.
Map the intersection, not the whole browser API.
Start with the smallest known-good screenshot request. Add only the controls your output requires, then compare representative pages at identical viewport and output settings.
| Browserless concept | Latchshot | Migration note |
|---|---|---|
?token=… | Authorization: Bearer … | Move the secret from the endpoint query into the request header. |
url | url | Public HTTP(S) only; private and special-use destinations are rejected. |
options.type=png | kind=screenshot, format=png | Direct binary PNG response. |
options.type=jpeg | kind=screenshot, format=jpeg | Direct binary JPEG response. |
options.quality | quality | JPEG only; integer from 1–100. Latchshot defaults to 85. |
viewport.width | width | 320–2560 pixels. |
viewport.height | height | 240–1440 pixels. |
viewport.deviceScaleFactor | scale | Use 1 or 2; verify resulting image dimensions and storage size. |
options.fullPage | fullPage | Latchshot bounds final document height at 20,000 pixels. |
gotoOptions.waitUntil=load | waitUntil=load | Direct lifecycle mapping. |
gotoOptions.waitUntil=domcontentloaded | waitUntil=domcontentloaded | Direct lifecycle mapping and Latchshot default. |
networkidle0 or networkidle2 | waitUntil=networkidle | No exact 0-versus-2 request-count distinction; retest pages with persistent connections. |
gotoOptions.timeout | timeout | Both use milliseconds. Latchshot accepts 3000–30000 ms and also enforces a hard process deadline. |
waitForTimeout | delay | Both use milliseconds. Latchshot caps the post-lifecycle delay at 3000 ms. |
options.captureBeyondViewport | fullPage | Use the higher-level full-page result only; Latchshot does not expose Puppeteer's clip behavior. |
optimizeForSpeed | No exact equivalent | Compare actual output bytes and latency; do not infer equivalent encoding behavior. |
scrollPage | scrollPage | Requires fullPage=true. Latchshot makes one deterministic sweep capped at 48 steps, 5 seconds, and 20,000 pixels; it does not expose custom speed, direction, selectors, or actions. |
On a narrow screen, scroll the option table horizontally.
Latchshot can return bounded A4, Letter, or Legal PDF bytes, but Browserless PDF options are not screenshot options and are not mapped by this guide. Compare margins, backgrounds, page size, headers, footers, and print CSS before changing a PDF workflow.
Stop when the request needs a browser primitive.
Latchshot has no equivalent for these Browserless capabilities. Removing one can change the image, expose data, or break the surrounding workflow.
- Alternate input: inline
html, local files, data URLs, or application content that is not already available as a permitted public URL. - Browser sessions: CDP, Puppeteer, Playwright, reconnectable sessions, BrowserQL, or custom function execution.
- Page state: cookies, arbitrary headers, login state, authenticated pages, request interception, or application secrets supplied to the target.
- Page actions: injected JavaScript or CSS, clicks, typing, custom, element-directed, or multi-step scrolling, selectors, element screenshots, or clip coordinates.
- Network placement: private hosts, non-standard target ports, proxy selection, region-specific browser endpoints, or geolocation.
- Browserless workflows: downloads, content extraction, performance APIs, provider-side caching, and non-screenshot REST endpoints.
Keep Browserless for those jobs. Route only the proven public-URL screenshot subset to Latchshot; a split-provider architecture is safer than silently degrading the output.
The fit check is free. Review the exact $99 pilot scope and acceptance boundary, then open a public migration-fit question on GitHub with the request contract, required provider behavior, and expected volume. For one eligible JavaScript/TypeScript or Python backend call site in a public GitHub repository you control, choose the optional $99 implementation pilot. API usage is separate. Never include a key, private or signed URL, customer data, or sensitive artifact.
Cut over by capability, then by traffic.
- Log the option names—not secret values—present in current Browserless screenshot calls. Keep every request that hits the stop list on Browserless.
- Create a representative public-page sample: ordinary, slow, font-heavy, animated, consent-overlay, tall, persistent-connection, and known-failure targets.
- Render both providers at the same viewport, format, quality, lifecycle wait, and delay. Compare dimensions, visible content, fonts, lazy content, bytes, and latency.
- Keep application-owned base64 conversion, storage, CDN, or downstream attachment logic unchanged. Store Latchshot's render, navigation, scroll, font, script, and quota headers with job diagnostics.
- Route a bounded percentage of eligible jobs to Latchshot. Exercise rollback before removing the Browserless credential or code path.
Retry only 429, 502, 503, and 504, with a strict attempt cap inside the caller's deadline. Treat 400, 401, 403, and target-policy failures as permanent until the request changes.
Compare the eligible slice, not platform headline prices.
Latchshot counts successful direct renders. Failed direct renders do not consume monthly quota, and automatic overages are disabled during the beta. The current plans are Free at 100 successful renders each UTC month, Launch at $19 for 2,500, Build at $49 for 12,000, and Scale at $149 for 50,000.
Those prices do not prove a saving. Include Browserless jobs that cannot migrate, regional or concurrency needs, storage and transfer, retry volume, integration work, and the value of browser primitives on the stop list.
Model only the eligible slice. Use your successful monthly volume, avoidable provider spend, and supported-workload share in the browser-local cost and migration fit calculator. Inputs and results stay in your browser; the output is an estimate, not a quote or savings guarantee.
The reference run completed 197 of 200 preflighted public HTML roots at 2.42-second p50 and 7.68-second p95 end to end. It is engineering evidence, not an SLA or a prediction for your pages.
Create one Free-plan key, save it when it is returned, and spend the 100 monthly successful renders on a representative comparison set.
Test only the screenshot subset.
Use Latchshot for bounded public-URL image bytes. Keep Browserless wherever the request still operates a browser.