Start with the response contract
Move only the direct image response.
ApiFlash can return image bytes, or JSON containing a provider-hosted screenshot URL and optional extracted content. It also supplies caching and storage controls. Latchshot has a smaller contract: one authenticated server request returns PNG, JPEG, or PDF bytes synchronously, and your application owns any later storage or delivery.
Good migration candidate
Your backend needs one image now.
- Input
- A public HTTP or HTTPS page on port 80 or 443
- Controls
- Viewport, scale, full page, lifecycle wait, short delay, bounded cleanup, and PNG or JPEG output
- Output
- Image bytes returned to an authenticated server call
Keep ApiFlash
The surrounding workflow matters.
- Delivery
- A hosted JSON URL, provider cache, S3 upload, or WebP output is required
- Browser work
- Selectors, crop, custom or element-directed scrolling, custom/exhaustive blockers, cookies, headers, CSS, JavaScript, or a proxy is required
- Extraction
- HTML, text, target-status policy, geolocation, or another ApiFlash result is consumed
ApiFlash is a product of its respective owner. This page is a migration reference for the smaller Latchshot contract. Confirm the current ApiFlash documentation and parameters used by your application.
Move the credential out of the URL.
ApiFlash accepts a GET query or POST form request and carries access_key alongside the other parameters. Latchshot accepts JSON over POST and requires the credential in an Authorization header. Both can return image bytes directly.
Before: ApiFlash binary response
curl -fsSL -G \
'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode "access_key=$APIFLASH_ACCESS_KEY" \
--data-urlencode 'url=https://example.com' \
-d 'format=png' \
-d 'width=1440' \
-d 'height=900' \
-d 'wait_until=network_idle' \
-o before.png
After: Latchshot binary response
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": "png",
"width": 1440,
"height": 900,
"waitUntil": "networkidle"
}' \
-o after.png
ApiFlash documents JPEG as its default image format; Latchshot defaults to PNG. Do not rely on either default during comparison or cutover.
Translate names, units, and behavior.
Several controls overlap, but similar names do not guarantee identical pixels or timeout behavior. Start from the smallest request and compare representative pages.
| ApiFlash concept | Latchshot | Migration note |
|---|---|---|
access_key query/form field | Authorization: Bearer … | Keep the replacement key out of URLs, client code, and logs. |
| GET query or POST form | POST JSON | Change the body encoding and send Content-Type: application/json. |
url | url | Include http:// or https://; Latchshot rejects private/special-use targets and non-web ports. |
response_type=image | Binary response | The closest response contract; persist the bytes yourself if a durable URL is needed. |
response_type=json | No exact equivalent | Latchshot does not return a provider-hosted screenshot URL or extracted-content URLs. |
width | width | Latchshot accepts 320–2560 pixels and defaults to 1440 rather than ApiFlash's documented 1920. |
height | height | Latchshot accepts 240–1440 pixels and defaults to 900 rather than ApiFlash's documented 1080. |
format=png/jpeg | kind=screenshot, format=png/jpeg | Both return image bytes; make the format explicit. |
format=webp | No exact equivalent | Keep ApiFlash or transcode downstream. |
full_page | fullPage | Boolean; validate tall-page limits, lazy content, and final dimensions. |
scale_factor=1/2 | scale=1/2 | Same available values; confirm output pixel dimensions and storage. |
delay in seconds | delay in milliseconds | Convert the unit: 2 seconds becomes 2000. Latchshot caps the delay at 3000 ms, not ApiFlash's documented 10 seconds. |
wait_until=dom_loaded | waitUntil=domcontentloaded | Equivalent browser lifecycle event name. |
wait_until=page_loaded | waitUntil=load | Equivalent load-event name. |
wait_until=network_idle | waitUntil=networkidle | Closest choice, not a promise of identical idle thresholds; retest dynamic pages. |
wait_until_timeout in seconds | No exact equivalent | Latchshot's millisecond timeout governs navigation and returns an error on timeout; ApiFlash documents capturing whatever has loaded when its criterion timeout expires. |
thumbnail_width | No independent resize | Capture at the needed viewport or resize the returned bytes downstream. |
quality | quality | JPEG only; use an integer from 1–100. Latchshot defaults to 85. |
block_ads | blockAds | Best-effort blocking of requests to known third-party ad hosts, not an exhaustive or custom filter list. |
block_trackers | blockTrackers | Best-effort blocking of known third-party analytics and tracker hosts. |
block_cookie_banners | hideCookieBanners | Hides common consent overlays without clicking consent or setting consent cookies. |
ttl, fresh | No provider cache | Build cache keys, freshness, and storage in your application if needed. |
transparent, crop, element | No exact equivalent | Do not silently replace region, element, or transparent-background output with a viewport capture. |
On a narrow screen, scroll the option table horizontally.
Stop if ApiFlash supplies more than image capture.
Latchshot has no equivalent for these ApiFlash capabilities. Removing one can change the page, response, delivery contract, quota behavior, or security model.
- Cache and hosting:
ttl,fresh, cache-hit quota behavior,response_type=json, and provider-hosted screenshot URLs. - Storage and output: S3-compatible upload, WebP, transparent-background mode, thumbnail resize, and crop output.
- Page selection and modification:
wait_for,element, overlap handling, custom or element-directed scrolling, injected CSS or JavaScript, and custom target-status failure ranges. Latchshot's separatescrollPageoption only performs bounded full-page lazy-content activation. - Page state and cleanup: custom headers, cookies, user agents, languages, custom/exhaustive blocker lists, chat/popup cleanup beyond known widgets and common overlays, or cookie handling beyond common-overlay hiding.
- Network and location: custom or managed proxies, IP country, geolocation, time zone, authenticated pages, private hosts, and non-standard target ports.
- Extraction: HTML or text extraction and the additional URLs carried in ApiFlash's JSON response.
Keep ApiFlash for any job that needs those features. A split-provider design is safer than weakening an existing workflow to force a migration.
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 one eligible job at a time.
- Inventory the exact ApiFlash request, response type, cache, storage, extraction, and page-modification parameters.
- Reject every job that depends on the stop list. Do not mistake a hosted JSON URL for a direct image response.
- Render a representative public-page set through both providers with explicit formats, viewports, scale, and waits.
- Compare dimensions, visible content, fonts, navigation completion, latency, error behavior, and the surrounding storage or delivery path.
- Route a bounded share of eligible jobs to Latchshot and keep the ApiFlash path until rollback has been exercised.
Retry only 429, 502, 503, and 504, with a strict attempt cap. Treat authentication, validation, and target-policy failures as permanent until the request changes.
Price the complete workflow.
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.
That is not proof that migration is cheaper. ApiFlash documents cache hits for identical requests as not counting against monthly quota. Include cache hit rate, storage, transfer, image conversion, engineering work, retries, and every ApiFlash-only job that remains.
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 use the 100 monthly successful renders on a representative eligible set.
Test the smaller contract.
Move only synchronous public-page PNG or JPEG captures whose caller already consumes bytes. Keep ApiFlash wherever its cache, hosted response, WebP, browser controls, extraction, proxy, or storage features are part of the job.