Keyword: element screenshot API ยท Updated August 1, 2026

Element Screenshot API: Capture Specific UI Components with CSS Selectors

Most automated screenshots capture too much. A support workflow needs the failed pricing card, not the whole pricing page. A sales report needs the chart, not the dashboard chrome. An AI agent may need proof that one component rendered after a click. An element screenshot API turns that into one repeatable request: wait for a CSS selector, optionally click the UI into the right state, and crop the final image to the element bounds.

Why this is timely

Browser automation is becoming more targeted. Playwright documents screenshot capture at both page and locator level, which matches the way developers debug individual components instead of whole pages. The current Playwright MCP documentation also exposes screenshot workflows for AI agents, including screenshots tied to element references. Chrome's DevTools for agents guidance, updated in May 2026, shows the same direction: agents need inspectable page state, emulation, and page-level evidence rather than only raw navigation.

SnapshotFlow fits the API side of that workflow. The backend verifies the target URL, renders it in Chromium, waits for wait_for_selector, can click a selector, inject CSS or JavaScript, hide noisy elements, and then capture only the element matched by selector. The Node SDK exposes the same capability as camelCase options such as waitForSelector, selector, click, and hideSelectors.

Scope: this guide is for component-level evidence. For full scrollable pages, use the full-page screenshot API guide. For pixel regression thresholds, use the visual regression testing guide. For many URLs with shared settings, use the batch screenshot API guide.

When an element screenshot is better than a full page

Use selector-based capture when the target is a specific rendered component and the surrounding page would make the evidence harder to review.

TaskSnapshotFlow parametersWhy it helps
Pricing card proofwait_for_selector=.pricing-card, selector=.pricing-cardCrops directly to the plan card that changed.
Dashboard chart exportselector=#revenue-chart, hide_selectors=.intercom,.toastKeeps chat bubbles, toasts, and navigation out of reports.
Menu or modal stateclick=[data-open-menu], selector=[role=menu]Captures UI that appears only after an interaction.
Receipt or invoice widgethtml=<base64>, selector=.receiptRenders generated HTML without publishing a route first.
Agent or support evidenceresponse_type=url, format=webpReturns a compact hosted image URL for tickets and reviews.

1. Capture one element with cURL

Start with a selector that exists after the page finishes rendering. Use wait_for_selector to avoid racing the app, then use selector to crop the final screenshot to that element.

curl --get "https://api.snapshotflow.com/screenshot" \ -H "X-Api-Key: $SNAPSHOTFLOW_API_KEY" \ --data-urlencode "url=https://example.com/pricing" \ --data-urlencode "response_type=url" \ --data-urlencode "format=webp" \ --data-urlencode "quality=82" \ --data-urlencode "width=1440" \ --data-urlencode "height=900" \ --data-urlencode "wait_until=networkidle2" \ --data-urlencode "wait_for_selector=.pricing-card[data-plan='pro']" \ --data-urlencode "selector=.pricing-card[data-plan='pro']" \ --data-urlencode "block_ads=true" \ --data-urlencode "block_cookie_banners=true"

Expected behavior: SnapshotFlow validates the URL, opens it in Chromium, waits for the Pro pricing card, crops the screenshot to that element, stores the WebP, and returns a plain-text download URL. If the selector never appears, the API returns SELECTOR_NOT_FOUND with HTTP 422 instead of returning a misleading full-page image.

2. Capture a component with the Node SDK

The official Node SDK is a thin HTTP wrapper over the SnapshotFlow API. It accepts camelCase option names and converts them to the API's snake_case parameters.

import { SnapshotFlow } from "snapshotflow"; const client = new SnapshotFlow({ apiKey: process.env.SNAPSHOTFLOW_API_KEY, }); const imageUrl = await client.takeUrl({ url: "https://example.com/pricing", responseType: "url", format: "webp", quality: 82, width: 1440, height: 900, waitUntil: "networkidle2", waitForSelector: ".pricing-card[data-plan='pro']", selector: ".pricing-card[data-plan='pro']", blockAds: true, blockCookieBanners: true, }); console.log(imageUrl);

Save a binary component image

Use take() when your job writes the image into local storage, S3, a ticket attachment, or an internal report pipeline.

const shot = await client.take({ url: "https://example.com/dashboard", format: "png", width: 1440, height: 900, waitForSelector: "#revenue-chart", selector: "#revenue-chart", hideSelectors: [".intercom-launcher", ".toast", ".sidebar-resizer"], cache: false, }); await shot.save("revenue-chart.png");

3. Common selector screenshot patterns

Capture a post-click state

For menus, tabs, accordions, and modals, click one selector before cropping another selector.

curl --get "https://api.snapshotflow.com/screenshot" \ -H "X-Api-Key: $SNAPSHOTFLOW_API_KEY" \ --data-urlencode "url=https://example.com/account" \ --data-urlencode "click=[data-testid='billing-tab']" \ --data-urlencode "wait_for_selector=[data-testid='billing-panel']" \ --data-urlencode "selector=[data-testid='billing-panel']" \ --data-urlencode "response_type=base64"

Render private HTML and crop one widget

If the component does not have a public URL, pass raw HTML through the SDK. The SDK base64-encodes the HTML before sending it to the API.

const receipt = await client.take({ html: ` <main class="receipt"> <h1>Receipt #1042</h1> <p>Plan: Pro</p> <p>Total: $49.00</p> </main> <style> body { margin: 0; font-family: Inter, Arial, sans-serif; } .receipt { width: 480px; padding: 32px; border: 1px solid #d8dee9; } </style> `, selector: ".receipt", format: "png", omitBackground: false, }); await receipt.save("receipt-1042.png");

Choose selector before clip coordinates

SnapshotFlow also supports clip_x, clip_y, clip_width, and clip_height. Use those when the target is a fixed coordinate region, such as a canvas area. For normal web UI, selector is safer because it follows layout shifts across responsive widths.

Operational advice and edge cases

  • Prefer test-oriented selectors. A stable data-testid, data-snapshot, or semantic component class is less brittle than a deeply nested CSS path.
  • Use wait_for_selector and selector together. Waiting for the same element you capture makes failures easier to interpret.
  • Expect one matching element. If the selector matches multiple elements, the browser captures the first match. Make the selector specific when evidence quality matters.
  • Clean the frame deliberately. hide_selectors, block_ads, block_trackers, and block_cookie_banners are useful when overlays are not the subject of the screenshot. Do not hide UI that reviewers need to inspect.
  • Use cache=false during investigation. Cached captures are useful for repeated reads, but a fix verification run should request a fresh render.
  • Keep viewport settings explicit. Element size and wrapping depend on width, height, device_scale_factor, and mobile emulation. Store those settings next to the image URL.
  • Do not use selector screenshots for PDF output. SnapshotFlow's selector crop is for image capture. For PDFs, use format=pdf with PDF options and capture the page print output instead.
Security note: pass headers, cookies, and authenticated URLs only from a trusted server-side job. Keep API keys and session values out of client-side code, public tickets, and logs.

FAQ

Can I capture an element inside a page that requires JavaScript?

Yes. SnapshotFlow renders pages in Chromium. Use wait_until=networkidle2 or a more specific wait_for_selector so the app hydrates before the element crop happens.

What happens if the selector is missing?

The API returns SELECTOR_NOT_FOUND with HTTP 422 for missing selector, click, or wait_for_selector targets. Treat that as a useful signal that the page changed, the selector is wrong, or the wait condition is too early.

Can I use this for visual regression testing?

Yes, but the comparison workflow is separate. Capture a stable element as a baseline, then use the visual regression guide for thresholds, diffs, and CI behavior.

Sources and further reading

Next step

If your workflow needs component-level evidence, start with one stable selector and one known viewport. After the first capture is reliable, add click, hide, cache, and response-type settings only for the states your reviewers actually need.

Read /screenshot docs