Return Screenshots and HTML in One API Request
Use ScreenshotOne’s metadata_content=true option to request a screenshot and synchronized HTML content URL in one call, with implementation notes and alternatives.
Direct answer: ScreenshotOne can return a website screenshot and an HTML-content URL from one API request. Enable the feature with metadata_content=true. The screenshot is returned normally, while the HTML location is provided in a response header or in JSON, depending on the client integration.
A combined request is useful when the image and markup must describe the same page load. It can reduce request count, avoid paying twice for the same capture, and reduce the chance that two separate requests observe different page states.
How the combined response works
- Send your normal ScreenshotOne screenshot request.
- Add
metadata_content=true. - Read the screenshot response body.
- Look for the HTML-content URL in the response headers or JSON response supported by your client.
- Fetch that URL and store the HTML with the screenshot and request metadata.
The exact authentication fields, endpoint URL, response schema, header name, and limits are integration details. The announcement describing this feature does not publish them, so verify those values in the current ScreenshotOne API documentation before shipping.
Why one request can be better than two
| Approach | Requests | Synchronization | Cost consideration |
|---|---|---|---|
| Separate screenshot and HTML calls | Two | The page can change between loads, so pixels and markup may not match. | Two capture requests may be charged. |
| Combined request | One | Both artifacts originate from the same capture operation. | Designed to avoid duplicate request charges for the same task. |
Synchronization matters for visual regression systems, archiving, debugging, accessibility checks, and any workflow that links a pixel-level finding to the DOM that produced it.
Request pattern
Add the documented parameter to your existing screenshot request. The following is a shape of the request, not a complete endpoint or authentication example:
GET {SCREENSHOTONE_SCREENSHOT_ENDPOINT}
?{AUTHENTICATION_PARAMETER}={YOUR_KEY}
&url=https%3A%2F%2Fexample.com
&metadata_content=true
Use the endpoint, credential parameter, URL encoding rules, and output options from the current vendor documentation. Do not assume that a JSON response is always used: the HTML-content URL may be exposed as a response header or as a JSON field.
Header-first response handling
When the API returns an image body, inspect response headers before attempting to parse the body as JSON. A robust client should:
- Save the body as an image when the content type is an image.
- Search documented response headers for the HTML-content URL.
- Record the complete response headers for diagnostics, excluding secrets.
- Fall back to JSON parsing only when the content type indicates JSON or the integration explicitly documents a JSON envelope.
JSON response handling
Some integrations return a JSON object containing the screenshot representation and the HTML-content URL. Follow the documented field names exactly. Treat the HTML URL as data returned by the service; validate its scheme and host according to your security policy before fetching it.
Fetching and storing both artifacts safely
- Create a capture ID in your application.
- Send the request with
metadata_content=true. - Persist the screenshot bytes immediately.
- Extract the HTML URL from the documented header or JSON field.
- Fetch the HTML with a bounded timeout and redirect limit.
- Store the HTML, screenshot, source URL, capture time, API status, and request options together.
Keep the screenshot and HTML under the same capture ID. This makes later comparisons deterministic even when the source page changes.
DIY alternatives when you control the browser
If you are not using a combined API feature, the equivalent workflow is to load a page once in a browser, wait for the state you need, capture the screenshot, and serialize the loaded document from that same page instance. This avoids opening two independent browser sessions.
Playwright example (Node.js)
import { chromium } from 'playwright';
import { writeFile } from 'node:fs/promises';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
try {
await page.goto('https://example.com', { waitUntil: 'networkidle', timeout: 60000 });
await page.screenshot({ path: 'page.png', fullPage: true });
const html = await page.content();
await writeFile('page.html', html, 'utf8');
} finally {
await browser.close();
}
This method gives you the exact DOM observed by that browser page. It also means you operate the browser, wait strategy, proxy, cookies, JavaScript, resource blocking, retries, and infrastructure yourself.
Or skip the browser setup
ScreenshotNeo provides a one-call website screenshot API and can return PNG, JPEG, WebP, or PDF output. It is useful when you need the screenshot artifact without maintaining browser workers. See the ScreenshotNeo API documentation for options.
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. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots each month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Options to decide before implementation
- Page readiness: define whether the screenshot waits for load, network idle, a selector, or a fixed delay.
- Dynamic content: record the viewport, timezone, locale, cookies, and authentication state so a later capture can be reproduced.
- HTML retention: HTML can contain personal data, tokens embedded by applications, or user-generated content. Set retention and access controls before storing it.
- Large documents: stream or spool downloads and enforce maximum sizes. Do not let an unexpectedly large HTML response exhaust worker memory.
- Redirects: preserve the final URL and validate the returned HTML URL before fetching it.
- Retries: retry transient transport failures with exponential backoff, but avoid blindly repeating non-retryable authentication or validation errors.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No HTML URL found | The client only reads the image body, or the URL is in a header it ignores. | Inspect headers and confirm the documented JSON/header response mode. |
| JSON parsing fails | The response body is an image, not a JSON envelope. | Check the content type before parsing; save image bytes directly. |
| Screenshot and HTML differ | Two independent page loads were used, or the page changed after capture. | Use metadata_content=true or capture both from one browser page. |
| HTML fetch returns an error | The content URL expired, redirects are blocked, or outbound access is restricted. | Fetch promptly, allow documented redirects, and permit the required host through your network policy. |
| Intermittent timeouts | The target page has slow third-party resources or never reaches the chosen readiness condition. | Use a bounded wait strategy, reduce unnecessary resources, and retry only transient failures. |
| Unexpected billing | The workflow still makes a second screenshot request. | Log request IDs and count capture calls; ensure the HTML fetch uses the returned content URL rather than starting another capture. |
Performance, reliability, and cost notes
- A single capture generally reduces network round trips and queue work compared with two captures.
- Fetching the HTML afterward is a separate download even though it is produced by the same capture request; size and latency depend on the page.
- Cache artifacts by source URL plus all rendering inputs that affect output, including viewport, device scale, cookies, and wait settings.
- Store response status, headers, timing, and capture options so failures can be diagnosed without reproducing the page immediately.
- For high-volume jobs, cap concurrency, apply backpressure, and use idempotency keys where the provider supports them.
- Measure request count and bytes transferred separately. A combined capture can reduce capture charges while the HTML download still consumes bandwidth and storage.
FAQ
Does metadata_content=true return the HTML inline?
The feature returns an HTML-content URL through a response header or JSON, depending on the integration. Fetch that URL to obtain the document.
Can I use the HTML URL without saving the screenshot?
Technically the artifacts can be processed independently, but retaining both under one capture ID preserves the relationship and simplifies audits.
Why not just request the page HTML directly?
A direct HTTP request may miss JavaScript-rendered content and does not prove that the markup matches the rendered screenshot. A browser capture observes the same rendered page state.
Is this the same as ScreenshotNeo returning HTML?
ScreenshotNeo’s documented product is a screenshot and PDF API with page information available through its tools. The metadata_content=true option described above is the ScreenshotOne feature.
Summary checklist
- Add
metadata_content=trueto the ScreenshotOne request. - Read the image body and inspect headers or JSON for the HTML-content URL.
- Fetch the URL with timeouts, size limits, redirect controls, and secure storage.
- Keep both artifacts and all rendering inputs under one capture ID.
- Use one browser page for both outputs when implementing the workflow yourself.


