How to Capture Mobile Viewport Screenshots for Indian Ecommerce Websites with ApiFlash
Capture an Indian ecommerce page at a defined mobile viewport with ApiFlash. Configure language, timing, banners, caching, and output format.
To capture an Indian ecommerce website at a mobile viewport with ApiFlash, call its /v1/urltoimage endpoint with a valid access key, a complete target URL, and explicit width and height values. Keep full_page=false for a viewport-sized screenshot. Add language, timezone, location, and wait settings only when they are part of the scenario you want to inspect.
The example below uses 390 × 844 pixels as an illustrative viewport. It is not a prescribed or representative Indian phone size; choose dimensions and browser conditions from your own device analytics or test plan. ApiFlash documents controls for these settings, but that does not guarantee a particular store will load or display a particular localized experience.
1. Make a reproducible mobile viewport request
Use the HTTPS endpoint and URL-encode parameter values. The default response is image data. For a JSON response containing the screenshot URL and optional extracted content links, add response_type=json.
https://api.apiflash.com/v1/urltoimage?access_key=YOUR_ACCESS_KEY&url=https%3A%2F%2Fexample.in%2Fproduct&width=390&height=844&full_page=false&format=png&accept_language=en-IN&time_zone=Asia%2FKolkata
Replace the example URL with a page you are authorized to capture, and store your access key outside public source code. ApiFlash’s documented default viewport is 1920 × 1080, so omitting dimensions does not produce a mobile capture. Its documented dimensions range from 0 to 16,350 pixels, subject to a maximum width-times-height area of 33,177,600 pixels.
cURL
curl --get 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_ACCESS_KEY' \
--data-urlencode 'url=https://example.in/product' \
--data-urlencode 'width=390' \
--data-urlencode 'height=844' \
--data-urlencode 'full_page=false' \
--data-urlencode 'format=png' \
--data-urlencode 'accept_language=en-IN' \
--data-urlencode 'time_zone=Asia/Kolkata' \
--output mobile.png
Python
import os
import requests
params = {
"access_key": os.environ["APIFLASH_ACCESS_KEY"],
"url": "https://example.in/product",
"width": 390,
"height": 844,
"full_page": "false",
"format": "png",
"accept_language": "en-IN",
"time_zone": "Asia/Kolkata",
}
response = requests.get(
"https://api.apiflash.com/v1/urltoimage",
params=params,
timeout=60,
)
response.raise_for_status()
with open("mobile.png", "wb") as image_file:
image_file.write(response.content)
Install the dependency with python -m pip install requests. The timeout in this client is your HTTP client’s limit; the API’s capture wait settings are separate.
Node.js
const params = new URLSearchParams({
access_key: process.env.APIFLASH_ACCESS_KEY,
url: 'https://example.in/product',
width: '390',
height: '844',
full_page: 'false',
format: 'png',
accept_language: 'en-IN',
time_zone: 'Asia/Kolkata',
});
const response = await fetch(
`https://api.apiflash.com/v1/urltoimage?${params}`,
);
if (!response.ok) {
throw new Error(`ApiFlash returned HTTP ${response.status}: ${await response.text()}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('mobile.png', image));
Run as an ES module on a Node.js version that provides the built-in fetch. Keep the key in the APIFLASH_ACCESS_KEY environment variable.
2. Choose what “mobile” means for the capture
Viewport dimensions, user agent, pixel density, locale, and location are different controls. Set each one that matters to the comparison; do not infer exact handset or shopper emulation from viewport dimensions alone.
| Control | What to set | Practical note |
|---|---|---|
width, height |
Explicit CSS viewport dimensions, such as 390 and 844 | Use the same values across the pages in a comparison. ApiFlash’s defaults are desktop sized. |
full_page |
false for the visible viewport |
With true, ApiFlash captures the whole page and ignores the supplied height. |
scale_factor |
1 or 2 |
2 creates a higher definition image and a larger file. Check output dimensions and format limits. |
user_agent |
Only when a specific user-agent scenario matters | The documented behavior sets the User-Agent header; it is not a certification of exact device emulation. |
accept_language |
A language preference such as en-IN |
This sets the Accept-Language header. A site may use account, cookie, IP, or application settings instead. |
time_zone |
A timezone database name such as Asia/Kolkata |
Useful for pages whose visible state depends on local time. |
| Geolocation and proxy | Set latitude/longitude emulation or a proxy where appropriate | These are separate controls. The documented ip_location option is available only on custom enterprise plans and associates a country with the proxy IP. |
Language, timezone, geolocation, proxy, cookies, and headers are not interchangeable. A language header alone does not establish that a request came from India, and an Indian location setting does not guarantee a store will select a particular currency, language, or inventory.
3. Wait for the page state you need
ApiFlash’s default wait_until is network_idle. The other documented choices are dom_loaded and page_loaded. Ecommerce pages can load product details or navigation asynchronously, so a selector wait is often more targeted than waiting an arbitrary duration.
curl --get 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_ACCESS_KEY' \
--data-urlencode 'url=https://example.in/product' \
--data-urlencode 'width=390' \
--data-urlencode 'height=844' \
--data-urlencode 'full_page=false' \
--data-urlencode 'wait_until=dom_loaded' \
--data-urlencode 'wait_for=.product-details' \
--data-urlencode 'wait_until_timeout=20' \
--data-urlencode 'delay=1' \
--output mobile.png
URL-encode the CSS selector when constructing a URL manually; curl --data-urlencode does this for you. The wait_for selector must appear within 15 seconds or the capture aborts. wait_until_timeout accepts 1–30 seconds; when the condition is not met, capture proceeds with the state available at timeout. A short delay can help with an animation, but ApiFlash recommends using wait_for or wait_until when possible.
When to use each wait strategy
- Use
dom_loadedwhen the document structure is enough and background requests may continue. - Use
page_loadedwhen the page’s load event is the milestone you need. - Use
network_idlewhen network quiet is a sensible proxy for ready; long polling or analytics can make it a poor fit. - Use
wait_forwhen a known product, price, or navigation selector marks the state to inspect. - Use
delaysparingly for a known short animation or transition.
4. Decide how to handle banners, ads, and deferred content
These options change the observed page. For evidence of what a shopper sees, first preserve the ordinary view. Use suppression as a separate diagnostic capture and label the difference in your records.
| Option | Effect | Use with care |
|---|---|---|
no_cookie_banners=true |
Suppresses common cookie banners and popups | Do not use when measuring the consent experience or banner obstruction. |
no_ads=true |
Blocks popular ad networks and hides common ad spaces | Ad suppression can change layout and content. |
scroll_page=true |
Scrolls through the page before capture | May trigger lazy content, but changes scroll-dependent state; viewport capture still differs from an untouched initial view. |
For a viewport screenshot that should show the initial fold, keep scrolling off. For a diagnostic run that needs lazy-loaded images or animated sections to initialize, use scrolling and compare it with the unmodified capture.
5. Select image format, freshness, and response type
- Format: choose
png,jpeg, orwebp. JPEG and WebP accept a quality value from 0 to 100. - Dimensions: the documented maximum dimension is 16,350 pixels in each direction, subject to the area limit. For WebP, each dimension after applying
scale_factoris limited to 16,350 pixels. - Cache: identical requests may return a cached screenshot for 86,400 seconds by default. Set
ttlfrom 0 to 2,592,000 seconds (30 days), or usefresh=trueto bypass cached screenshots. - Response: the default is image data. Use
response_type=jsonif your workflow needs the screenshot URL and optional extracted content links.
For repeatable QA, record the complete request settings and whether the result was served fresh. A changed URL or query parameter may be a different request; do not assume it is a cache hit. Choose PNG for lossless detail, or JPEG/WebP with an appropriate quality when smaller transfer size matters.
6. Compare captures consistently
When comparing product pages, hold the target URL constant and change one condition at a time. Record at least:
- Viewport width and height, plus user-agent scenario and scale factor.
- Accept-Language and timezone; record geolocation and proxy settings separately.
- Wait condition, selector, and timeout.
- Whether cookie banners or ads were suppressed, and whether the page was scrolled.
- Format, quality, cache TTL, and whether freshness was forced.
The right viewport and locale combination should come from your own audience analytics or test plan. ApiFlash’s documented settings explain how to configure a request; they do not identify a representative Indian shopper profile.
7. Troubleshoot errors and unexpected images
| Symptom or response | Likely cause | What to check |
|---|---|---|
| Desktop-sized image | Width and height were omitted | Set both dimensions explicitly; the documented defaults are 1920 × 1080. |
| Image height does not match the requested viewport | full_page=true |
Set full_page=false; full-page mode ignores the supplied height. |
| HTTP 400 | Invalid parameters or an uncapturable URL | Check URL encoding, required parameters, dimensions and area, selector syntax, and whether the target URL can be reached. |
| HTTP 401 | Invalid or revoked access key | Check the key, environment variable, and account settings. Do not publish the key. |
| HTTP 402 | Quota exhausted | Check quota and account plan; the successful response includes quota headers and a quota endpoint is documented. |
| HTTP 403 | Requested feature is unsupported by the plan | Check the plan requirements for the option you used. |
| HTTP 429 | Rate limit exceeded | ApiFlash documents 20 requests per second with a burst size of 400. Throttle requests and retry with backoff. Identical requests that fail to capture are separately limited to five attempts per hour. |
| HTTP 500 | Internal capture failure | Retry cautiously, inspect the target and parameters, and avoid an unbounded retry loop. |
| Selector wait aborts | The selector did not appear within the documented 15-second limit | Confirm the selector exists in the rendered page, or wait for a more stable element. Remember that the selector limit is separate from the 1–30 second wait-until timeout. |
| Wrong language, currency, or products | The site may use account, cookie, IP, or its own localization rules | Set relevant request controls, inspect the resulting page, and avoid treating language or timezone alone as proof of an India-specific experience. |
| Bot check, CAPTCHA, blank page, or timeout | The target may block automation or fail to load in the capture environment | Verify the target is reachable and permitted for your use. ApiFlash’s FAQ says strict bot protections may still block access; no particular store is guaranteed to capture. |
| Old screenshot | A cached result was returned | Use fresh=true or adjust TTL when the capture must reflect current page state. |
8. Performance, reliability, and cost considerations
Keep viewport dimensions close to the actual inspection need: larger pixel areas and scale_factor=2 create larger images and can increase transfer and storage costs in your own pipeline. JPEG or WebP quality settings can reduce file size when pixel-perfect lossless output is unnecessary. Caching identical requests can avoid repeated capture work, while fresh=true is appropriate when the page may have changed.
Do not treat a successful API response as proof that the intended product state is visible. Inspect the returned image, especially for consent dialogs, bot checks, blank states, missing prices, or delayed inventory widgets. For batches, respect the documented rate limit, use bounded retries with backoff for transient failures, and account for the separate limit on repeated identical failed captures. ApiFlash plan prices and allowances can change; consult its current official product page before budgeting.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can return PNG, JPEG, WebP, or PDF from one GET request. Its capture options include viewport control, full-page and element capture, waits, locale settings, and caching. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.in/product -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.in/product"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.in/product' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Only clean shots are billed, and each response says the page verdict and billing status.
Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
Frequently asked questions
Does setting accept_language=en-IN guarantee an India-specific storefront?
No. It sets the Accept-Language header. A site may use other signals, including account state, cookies, IP address, or application settings.
Should I use a full-page capture for a mobile viewport check?
No. Keep full_page=false for the viewport. Full-page mode captures the page and ignores the requested height.
Can ApiFlash capture every Indian ecommerce site?
No such guarantee is documented. Strict bot protections may block access, and target behavior varies. Inspect the result for the specific URL and scenario.
How do I get a JSON response instead of image bytes?
Add response_type=json; the documented JSON response includes the screenshot URL and may include extracted content links.


