How to capture a mobile-sized webpage screenshot with ApiFlash
Set ApiFlash’s viewport dimensions for a mobile-sized webpage screenshot. Learn how to configure the request, wait for page content, and handle common limits.
To capture a mobile-sized webpage screenshot with ApiFlash, call its https://api.apiflash.com/v1/urltoimage endpoint with your access key and target URL, then set width and height to the desired viewport dimensions. For example, width=390 and height=844 request a viewport with those pixel dimensions. Add a mobile browser user_agent if the site responds differently to mobile User-Agent strings. These settings control the documented viewport and User-Agent; they do not guarantee a complete simulation of a specific physical phone.
1. Set up a mobile-sized ApiFlash request
- Get an ApiFlash access key from its dashboard.
- Choose the viewport width and height in pixels. ApiFlash defaults to 1920 × 1080, so set both explicitly for a mobile-sized viewport.
- Pass the full target page URL. Encode query parameter values when needed.
- Leave
full_pagefalse or unset for a screenshot of the viewport. Set it totrueonly when you want the full page height. - Choose an output format and wait strategy appropriate for the page.
The documented endpoint accepts GET query parameters or POST form data. The example below is a request template; replace the placeholders with your own values.
https://api.apiflash.com/v1/urltoimage?access_key=YOUR_ACCESS_KEY&url=https%3A%2F%2Fexample.com&width=390&height=844&format=png
2. Complete examples in common languages
cURL
This GET request saves the response image to mobile.png. cURL encodes the URL parameter value.
curl -G 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_ACCESS_KEY' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'width=390' \
--data-urlencode 'height=844' \
--data-urlencode 'format=png' \
-o mobile.png
Python
Install the HTTP client with python -m pip install requests. This example checks for an HTTP error before writing the response body.
import requests
response = requests.get(
"https://api.apiflash.com/v1/urltoimage",
params={
"access_key": "YOUR_ACCESS_KEY",
"url": "https://example.com",
"width": 390,
"height": 844,
"format": "png",
},
timeout=90,
)
response.raise_for_status()
with open("mobile.png", "wb") as image:
image.write(response.content)
Node.js
This example uses the built-in fetch available in current Node.js releases. It checks the response status before saving the image.
import { writeFile } from 'node:fs/promises';
const params = new URLSearchParams({
access_key: 'YOUR_ACCESS_KEY',
url: 'https://example.com',
width: '390',
height: '844',
format: 'png',
});
const response = await fetch(
`https://api.apiflash.com/v1/urltoimage?${params}`,
);
if (!response.ok) {
throw new Error(`ApiFlash returned HTTP ${response.status}`);
}
await writeFile('mobile.png', Buffer.from(await response.arrayBuffer()));
Keep the access key in a server-side environment variable or secret store when integrating this into an application. ApiFlash accepts it as a request parameter, so putting a real key in public browser code can expose it.
3. Choose viewport, device identification, and page height
| Setting | What it does | When to use it |
|---|---|---|
width, height |
Set viewport dimensions in pixels. Documented defaults are 1920 × 1080. | Set both for a mobile-sized viewport, such as 390 × 844. |
user_agent |
Sets the User-Agent header to identify as a chosen browser or device. | Use a mobile browser User-Agent when the site selects content based on that header. |
full_page |
Captures the full page height; when true, the specified height is ignored. | Leave false or unset for a fixed mobile viewport screenshot. |
scale_factor |
Accepts 1 or 2; 2 produces a higher-definition image and larger file. | Use 2 when you need a sharper output and can accept the larger image. |
Viewport dimensions and a mobile User-Agent are useful for mobile-oriented captures, but the documentation does not establish that they reproduce every physical-device behavior, such as touch input or a particular device profile. If you need to inspect responsive layout, capture the same URL at multiple viewport sizes and compare the results.
4. Format, quality, and image-size limits
ApiFlash supports png, jpeg, and webp. JPEG is the documented default, with a default quality of 80. The quality setting adjusts JPEG and WebP quality; it is not relevant to PNG in the same way. Choose PNG for lossless output or when image details and sharp edges matter, and choose JPEG or WebP when a smaller image is useful. Use scale_factor=2 for a higher-definition result, accounting for its larger file size.
The documented maximum dimension is 16,350 pixels, and the maximum width-times-height area is 33,177,600 pixels. WebP maximum dimensions apply after the scale factor. A very large viewport combined with a scale factor of 2 can therefore exceed limits even when the CSS viewport dimensions look reasonable.
5. Wait for dynamic page content
ApiFlash says it waits for network idle by default. For content that appears after the initial load, use wait_for with a CSS selector that identifies the content to capture. Use delay for an additional fixed wait only when a selector or load-state wait does not fit the page. The documented delay defaults to zero and goes up to 10 seconds.
curl -G 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_ACCESS_KEY' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'width=390' \
--data-urlencode 'height=844' \
--data-urlencode 'wait_for=.product-card' \
--data-urlencode 'format=png' \
-o mobile.png
Selectors must be URL-encoded by the client or command-line tool. A selector that never appears can prevent the desired capture from completing, so choose an element rendered on the target page and verify its spelling.
6. Useful optional controls
| Need | Relevant ApiFlash controls | Considerations |
|---|---|---|
| Fresh content | fresh=true, ttl |
fresh=true requests a new capture but does not remove the earlier cached result for the same parameters. TTL controls cache retention from 0 to 2,592,000 seconds. |
| Structured response | response_type=json |
Returns JSON with screenshot links and, where available, extracted HTML and text instead of only image data. |
| Cleaner page | no_cookie_banners, no_ads, no_tracking |
Availability of some features may depend on plan. |
| Page customization | CSS or JavaScript injection, cookies, headers | Custom headers apply to all requests and can interfere with external font requests. |
| Targeting and output | Element selection, cropping, S3 export | Check plan support; unsupported plan features can return HTTP 403. |
| Regional rendering | Proxy, location, time-zone settings | Proxy settings may help with some sites, but do not guarantee access through bot protection. |
For screenshots of authenticated or personalized pages, use the documented cookies or headers controls carefully. Avoid sharing credentials or private screenshot URLs in logs or public source code.
7. Quota, cache, rate limits, and reliability
ApiFlash documents a rate of 20 requests per second with a burst size of 400. Requests above the steady rate are delayed; requests beyond the burst can receive HTTP 429. Identical failed captures are limited to five requests per hour. Successful captures expose quota headers, and a quota endpoint is documented. The FAQ says cached and failed screenshots do not count toward monthly quota; exhausting plan quota returns HTTP 402.
For batch work, throttle requests below the documented rate and handle 429 responses with backoff. Cache results when the page and capture settings do not need refreshing. Set fresh=true only when you need a new capture. Configure a finite client timeout and record the response status and relevant quota headers so a failed capture is distinguishable from a successful image response.
ApiFlash renders using Chrome on Linux. System fonts can differ from Windows or macOS, so serving the fonts your site requires can make results more consistent. Custom headers sent to all requests can also break external font fetching. Sites with bot protection may block capture; a proxy may help depending on the protection, but is not a guaranteed workaround.
8. Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| Authentication error | Missing, invalid, or incorrectly encoded access key. | Check the key and ensure the HTTP client encodes query values correctly. |
| Screenshot looks desktop-sized | width and height were omitted or not passed as expected. |
Set both explicitly and inspect the final request parameters. |
| Responsive page still looks different from a phone | Viewport and User-Agent settings do not guarantee all device-specific behavior. | Check the dimensions, set a suitable mobile User-Agent, and treat the result as a browser capture configuration rather than proof of physical-device equivalence. |
| Expected content is missing | Content rendered after the capture wait condition. | Wait for a reliable CSS selector with wait_for; use a short delay only if needed. |
| Capture does not complete for a selector | The wait_for selector is invalid or absent. |
Verify the selector against the page and choose an element that appears reliably. |
| HTTP 403 | A requested feature may not be available on the current plan. | Review the plan support for that option. |
| HTTP 429 | Request rate or burst exceeded. | Reduce concurrency and retry with backoff. |
| HTTP 402 | Monthly plan quota is exhausted. | Check quota usage and the quota response details before scheduling additional captures. |
| Bot check, CAPTCHA, or blocked page | The site’s bot protection prevented access. | Try an allowed proxy configuration if appropriate; success is not guaranteed. |
| Fonts differ from local browser | Linux system fonts differ, or custom headers interfere with font requests. | Serve site fonts directly and check whether custom headers affect external assets. |
| Image rejected for size | Dimension or total area limit exceeded, possibly after scale factor. | Reduce viewport dimensions or use scale factor 1. |
9. Cost and operational planning
The ApiFlash homepage listed a free plan with 100 screenshots per month, Lite at $7 per month for 1,000, Medium at $35 for 10,000, and Large at $180 for 100,000 at the time this research was gathered. Plan prices and quotas can change, so check the live ApiFlash site before budgeting. The FAQ says cached and failed captures do not count toward monthly quota, which matters when estimating successful capture volume.
Keep expected volume below the plan quota, account for retries and cache behavior, and avoid unnecessarily large output dimensions or scale factors. For recurring jobs, monitor successful-capture quota headers and HTTP errors rather than assuming each requested URL produced a billable screenshot.
10. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. It accepts a URL in one GET request and returns a PNG, JPEG, WebP, or PDF. Its parameter names also work with the names used by other screenshot APIs, which can make switching easier. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
With ScreenshotNeo, cookie banners are accepted like a visitor would accept them, then removed along with 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, inspect page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month with no card.
11. FAQ
Does a mobile User-Agent make the capture identical to a real phone?
No such guarantee is established by the documented settings. The viewport dimensions and User-Agent control the documented request behavior, but do not establish touch input or a complete device profile.
Should I use full-page mode for a mobile screenshot?
Only if you need the entire page height. For a screenshot of the visible mobile-sized viewport, leave full_page false or unset.
Can I get screenshot metadata instead of image bytes?
Yes. Set response_type=json to receive JSON with screenshot links and, where available, extracted HTML and text.


