How Indian Agencies Can Take Bulk Client Website Screenshots with ScreenshotAPI
Prepare client URLs, capture them in repeatable batches with ScreenshotAPI’s CSV or JSON workflows, and review every result before delivery.
Indian agencies can take bulk client website screenshots with ScreenshotAPI by preparing a validated URL list, then submitting it as CSV through the dashboard or CSV API, or as JSON through the bulk API. The documented JSON limit is 50 URLs per request. ScreenshotAPI says CSV bulk capture is available on a paid tier; confirm current plan eligibility, quotas, and any limits that apply to your account before scheduling a large client run. ScreenshotAPI bulk documentation · ScreenshotAPI help.
1. Choose CSV or JSON
| Method | Best fit | Documented considerations |
|---|---|---|
| CSV upload | Spreadsheet-led workflows, one-off audits, and teams that want to inspect a list before submission. | Upload through the dashboard or API. ScreenshotAPI’s help page describes CSV bulk capture as a paid-tier feature. Verify current eligibility and applicable limits. |
| JSON bulk API | Scripts, scheduled reporting pipelines, and per-URL configuration. | Maximum 50 URLs in one JSON bulk request. Split larger lists into multiple requests and track each batch. |
The vendor lists SEO audits, before-and-after comparisons, and client reporting as bulk screenshot use cases. These are vendor-described applications; choose the workflow based on the deliverable and your client’s requirements.
2. Prepare and validate the URL list
Start with a source of truth such as a client-approved spreadsheet, sitemap export, or agency inventory. Keep a client identifier alongside each URL in your own tracking sheet so returned screenshots can be matched to the right report.
- Use fully qualified URLs beginning with
https://. The CSV documentation requires aurlcolumn. - Remove blank rows, duplicate URLs, and accidental whitespace. Decide explicitly whether both
wwwand non-wwwURLs should be captured. - Confirm each URL is the intended production, staging, or regional page. Avoid silently mixing environments in one client report.
- For JSON, split lists into groups of at most 50 URLs.
- Check access requirements before capture. Pages behind authentication or network restrictions may need appropriate supported headers or other configuration.
- Store the original URL list and batch identifiers so failures can be retried without repeating successful work.
CSV’s required field and example output columns are documented by ScreenshotAPI. A processed CSV can include the URL, status, screenshot link, and error message. See the CSV requirements and output example.
3. Set consistent capture options
For comparable client pages, use the same settings unless the report intentionally compares different device sizes or page states. ScreenshotAPI’s bulk documentation lists these optional per-URL settings:
| Setting | When to use it | Practical note |
|---|---|---|
file_type |
Choose PNG, JPG, or PDF output. | Use one format for a consistent report. Consider file size and how the client will review or archive the result. |
width, height |
Set the browser viewport dimensions. | Keep them fixed for like-for-like comparisons; viewport dimensions affect responsive layouts. |
delay |
Allow a page extra time before capture. | Use only where the site needs time to render dynamic content. Longer waits add processing time. |
injected_css |
Apply CSS for a particular reporting view. | Record the injected styles in the report methodology because they change the rendered page. |
headers |
Send custom request headers, such as a required user agent or authorization value. | Handle credentials as secrets and avoid putting them in shared spreadsheets or client-facing reports. |
fresh |
Request a current screenshot instead of a previously returned cached one. | ScreenshotAPI’s getting-started guide says to use fresh=true when you want a current screenshot for a request returned before. Getting-started documentation. |
| Full-page capture and other single-shot options | Capture beyond the initial viewport or configure a specialized page state. | The vendor says single screenshot options apply to bulk processing. Check the current parameter documentation for exact names and constraints. |
The exact supported options can change; refer to the vendor’s current bulk API documentation and single-capture docs when building production requests.
4. Submit a JSON batch
Use JSON when you want to automate submission and specify settings per URL. The official example uses a POST request to https://api.screenshotapi.net/v1/bulk/json?token=YOUR_TOKEN, with a JSON body containing a urls array. This example captures two pages as PNGs at the same viewport size. Keep each request to no more than 50 URLs.
cURL
curl -X POST 'https://api.screenshotapi.net/v1/bulk/json?token=YOUR_TOKEN' \\
-H 'Content-Type: application/json' \\
--data '{
"urls": [
{
"url": "https://client-one.example/",
"file_type": "png",
"width": 1440,
"height": 900,
"fresh": true
},
{
"url": "https://client-two.example/",
"file_type": "png",
"width": 1440,
"height": 900,
"fresh": true
}
]
}'
Python
import os
import requests
api_token = os.environ["SCREENSHOTAPI_TOKEN"]
payload = {
"urls": [
{
"url": "https://client-one.example/",
"file_type": "png",
"width": 1440,
"height": 900,
"fresh": True,
},
{
"url": "https://client-two.example/",
"file_type": "png",
"width": 1440,
"height": 900,
"fresh": True,
},
]
}
response = requests.post(
"https://api.screenshotapi.net/v1/bulk/json",
params={"token": api_token},
json=payload,
timeout=120,
)
response.raise_for_status()
print(response.text)
Node.js
const token = process.env.SCREENSHOTAPI_TOKEN;
if (!token) throw new Error("Set SCREENSHOTAPI_TOKEN first");
const response = await fetch(
`https://api.screenshotapi.net/v1/bulk/json?token=${encodeURIComponent(token)}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
urls: [
{
url: "https://client-one.example/",
file_type: "png",
width: 1440,
height: 900,
fresh: true
},
{
url: "https://client-two.example/",
file_type: "png",
width: 1440,
height: 900,
fresh: true
}
]
})
}
);
if (!response.ok) {
throw new Error(`Bulk request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.text());
These examples use reserved .example domains. Replace them with URLs you are authorized to capture, and keep the token in an environment variable or secret store. The response and subsequent status or result retrieval depend on the API’s current response format; follow the returned job or result data rather than assuming a fixed response schema.
5. Submit a CSV batch
CSV works well when the agency prepares the capture list in a spreadsheet and wants to retain a reviewable input file. Include a header named url. The vendor documents optional columns for file type, viewport dimensions, injected CSS, delay, and headers. Its example also includes fresh.
url,file_type,width,height,fresh
https://client-one.example/,png,1440,900,true
https://client-two.example/,png,1440,900,true
Upload the CSV in the ScreenshotAPI dashboard for a manual workflow. For programmatic upload, the documented endpoint is https://api.screenshotapi.net/v1/bulk/csv?token=YOUR_TOKEN and the multipart file field is named csv.
cURL CSV upload
curl -X POST 'https://api.screenshotapi.net/v1/bulk/csv?token=YOUR_TOKEN' \\
-F 'csv=@client-urls.csv'
Python CSV upload
import os
import requests
with open("client-urls.csv", "rb") as csv_file:
response = requests.post(
"https://api.screenshotapi.net/v1/bulk/csv",
params={"token": os.environ["SCREENSHOTAPI_TOKEN"]},
files={"csv": ("client-urls.csv", csv_file, "text/csv")},
timeout=120,
)
response.raise_for_status()
print(response.text)
Node.js CSV upload
import { readFile } from "node:fs/promises";
const token = process.env.SCREENSHOTAPI_TOKEN;
if (!token) throw new Error("Set SCREENSHOTAPI_TOKEN first");
const csv = await readFile("client-urls.csv");
const form = new FormData();
form.append("csv", new Blob([csv], { type: "text/csv" }), "client-urls.csv");
const response = await fetch(
`https://api.screenshotapi.net/v1/bulk/csv?token=${encodeURIComponent(token)}`,
{ method: "POST", body: form }
);
if (!response.ok) {
throw new Error(`CSV upload failed: ${response.status} ${await response.text()}`);
}
console.log(await response.text());
Do not manually set the multipart Content-Type in the Node example; the runtime must add the boundary. Confirm the current API response and account eligibility before relying on this upload in a scheduled job.
6. Monitor the run and review deliverables
- Record the submission time, client or project identifier, batch number, and input file version.
- Monitor progress in the dashboard or through the status API as described by ScreenshotAPI. The documentation says progress can include percent complete and successful and failed URL counts.
- Wait for processing to finish. Completion time can vary with URL count and configuration.
- Retrieve the processed CSV through the dashboard or API. The vendor also documents an email with a direct download link when all screenshots are ready.
- Review each row’s status, screenshot link, and error message. Do not treat a completed batch as proof that every URL succeeded.
- Open representative outputs at the same viewport and verify page state, framing, and format before assembling the client report.
- Retry failed rows in a separate batch and preserve the first run’s results for traceability.
ScreenshotAPI’s documentation describes monitoring and output handling, but the exact status API route and response schema should be taken from the current vendor docs or account dashboard rather than assumed. Bulk processing details.
7. Make the workflow repeatable across clients
- Keep a client-specific URL inventory and a separate capture manifest with viewport, format, freshness, delay, and any CSS or headers used.
- Standardize settings for recurring monthly or before-and-after reports. If settings change, note the change alongside the report.
- Chunk JSON inputs into batches of 50 or fewer, and give each batch a stable internal identifier.
- Use a small pilot batch when a client site has authentication, unusual rendering, or time-sensitive content. Inspect failures before scaling the run.
- Protect tokens and authorization headers. Limit access to source sheets and output links according to the agency’s client data practices.
- Ask ScreenshotAPI directly about India-specific invoicing, taxes, data handling, retention, and regional terms if these matter to procurement. The documentation reviewed here does not establish those terms.
8. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| CSV row is rejected or fails | The required url header is absent, a URL is incomplete, or it lacks the https:// protocol. |
Validate the header and normalize every URL before upload. |
| JSON batch is rejected | The body is invalid JSON, the urls value is not an array, or the request exceeds the documented 50-URL limit. |
Validate JSON syntax and split the input into batches of at most 50. |
| CSV bulk access is unavailable | CSV bulk is documented as a paid-tier feature, or the current plan has different eligibility. | Check current plan information and account entitlements before building a production workflow. |
| A page appears stale | A prior screenshot may have been returned from cache. | Use fresh=true where supported to request a current screenshot, as described in the vendor’s getting-started documentation. |
| Page is blank or incomplete | The page may need more render time, or content may depend on client-side loading or access conditions. | Try a suitable delay, verify the URL and access requirements, and inspect the returned error details. Avoid increasing delay globally without evidence it is needed. |
| Screenshot differs across client pages | Viewport or per-URL settings differ, or the websites render different responsive layouts. | Compare the input settings and standardize dimensions, format, and other relevant options. |
| Authentication or custom content is missing | The target may require headers or a supported authentication configuration. | Check the current parameter docs, provide only necessary credentials securely, and confirm the account is authorized to capture the page. |
| Some rows succeed while others fail | Bulk processing can have URL-specific errors. | Use the output status and error message fields to isolate failures and submit only those rows again. |
| API request returns an HTTP error | Token, endpoint, request method, multipart field name, or payload may be incorrect. | Check the token and endpoint, ensure CSV uses the csv multipart field, and inspect the response body. Never publish tokens in logs or reports. |
9. Performance, reliability, and cost
Performance: Batch size, page complexity, configuration, and render delays affect how long processing takes. JSON requests are limited to 50 URLs at once; larger sets require multiple batches. The vendor does not provide an independently verified completion-time guarantee in the reviewed materials, so plan slack into client deadlines.
Reliability: Treat each URL as an independently reviewable result. Track successes and failures, preserve the input manifest, and make retries selective. For recurring reporting, record whether freshness was requested so that comparisons have a clear basis.
Cost and eligibility: The reviewed official help documentation says CSV bulk capture is available on a paid tier. It does not establish current plan prices or quotas, so consult the live plan page or vendor before estimating client costs. JSON’s 50-URL request limit is a request constraint, not a pricing statement. Confirm applicable limits for the plan, especially for large or enterprise runs.
India-specific purchasing: No India-specific billing, tax, data residency, or partner-program terms are established by the sources used here. Ask the provider for written confirmation if your agency needs those terms for procurement or client commitments.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request takes a URL and returns an image or PDF. The parameter names used by other screenshot APIs also work, which can make switching easier. See the ScreenshotNeo site and ScreenshotNeo API documentation.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses identify the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Can I upload a spreadsheet of client URLs?
Yes. Prepare it as a CSV with a url column and upload it through the dashboard or documented CSV API. CSV bulk availability is described as paid-tier; check current eligibility.
How many URLs can one JSON request contain?
The documented maximum is 50 URLs per JSON bulk request. Divide larger lists into separate requests.
Does a completed batch mean every screenshot succeeded?
No. Review per-URL statuses, screenshot links, and error messages in the processed results.
Does the documentation confirm India-specific tax or data residency terms?
No. Ask ScreenshotAPI for current written terms if local invoicing, taxes, or data location affect your decision.


