Element Screenshot
Sometimes you don't need the entire page — just a specific part of it. A pricing table, a hero banner, a product card, or a chart. Element screenshots let you capture exactly that element, cropped to its boundaries, without any manual image editing afterwards.
Capturing a specific element
The selector parameter takes a CSS selector and crops the screenshot to that element's bounding box.
| Parameter | Type | Description |
|---|---|---|
selector | string | CSS selector of the element to capture. Max 500 characters. |
The API finds the first element matching your selector and captures only that element. Everything else is excluded from the output image. You can use any valid CSS selector: class names, IDs, data attributes, or more complex selectors.
Example: Capture a hero section
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&selector=.hero-section" \
-o hero.png
Example: Capture by ID
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&selector=%23pricing-table" \
-o pricing.png
In GET requests, the # character in selectors must be URL-encoded as %23. In POST requests with JSON body, use it directly: "selector": "#pricing-table".
Example: Capture by data attribute
const response = await fetch('https://api.screenshotrun.com/v1/screenshots', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://example.com',
selector: '[data-testid="product-card"]',
}),
});
const { data } = await response.json();
console.log(data.links.image);
import requests
response = requests.post(
"https://api.screenshotrun.com/v1/screenshots",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"url": "https://example.com",
"selector": "[data-testid="product-card"]",
},
)
data = response.json()["data"]
print(data["links"]["image"])
$response = Http::withToken('YOUR_API_KEY')
->post('https://api.screenshotrun.com/v1/screenshots', [
'url' => 'https://example.com',
'selector' => '[data-testid="product-card"]',
]);
$data = $response->json('data');
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"selector": "[data-testid="product-card"]"
}'
require "net/http"
require "json"
uri = URI("https://api.screenshotrun.com/v1/screenshots")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Content-Type"] = "application/json"
request.body = {
url: "https://example.com",
selector: "[data-testid="product-card"]",
}.to_json
response = http.request(request)
data = JSON.parse(response.body)["data"]
body, _ := json.Marshal(map[string]any{
"url": "https://example.com",
"selector": "[data-testid="product-card"]",
})
req, _ := http.NewRequest("POST",
"https://api.screenshotrun.com/v1/screenshots",
bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var result map[string]any
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result["data"])
var client = HttpClient.newHttpClient();
var body = """
{
"url": "https://example.com",
"selector": "[data-testid="product-card"]"
}
""";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.screenshotrun.com/v1/screenshots"))
.header("Authorization", "Bearer YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
var response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
What if the selector matches multiple elements?
The API captures the first matching element. If you need a specific one, make your selector more precise — for example, .product-card:nth-child(2) for the second card, or .sidebar .widget for a widget inside the sidebar.
What if the element isn't found?
The API returns an error if no element matches your selector. Double-check the selector in your browser's console with document.querySelector('.your-selector') before using it in the API.
Click before capture
Some pages have elements that need interaction before you can see the content you want. A cookie consent banner covers the page. A tab needs to be clicked to show a section. A dropdown needs to be opened. The click_selector parameter clicks an element before the screenshot is taken.
| Parameter | Type | Description |
|---|---|---|
click_selector | string | CSS selector of an element to click before capturing. Max 500 characters. |
Example: Dismiss a cookie banner
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"click_selector": "#accept-cookies"
}'
Example: Switch to a tab
Click a tab to reveal its content, then capture the page with the tab content visible.
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/pricing",
"click_selector": ".tab-yearly",
"delay": 1
}'
Add a short delay after a click if the UI needs time to animate or load new content. See Timing & Delay for details.
Scroll to element
If the element you want to capture or see is below the fold, the scroll_to parameter scrolls it into view before the screenshot.
| Parameter | Type | Description |
|---|---|---|
scroll_to | string | CSS selector of an element to scroll into view before capturing. Max 500 characters. |
Example: Scroll to pricing and capture it
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"scroll_to": "#pricing-section",
"selector": "#pricing-section"
}'
This scrolls the pricing section into view (which may trigger lazy-loaded images inside it), then captures just that section.
Hiding elements
Popups, banners, sticky headers, chat widgets, cookie overlays — these elements often clutter your screenshots. The hide_selectors parameter hides them by applying display: none before the screenshot.
| Parameter | Type | Description |
|---|---|---|
hide_selectors | array | Array of CSS selectors to hide. Max 20 selectors. |
Example: Hide multiple distracting elements
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"hide_selectors": [".cookie-banner", "#newsletter-popup", ".ads-container", ".sticky-header"]
}'
For cookie banners, ads, and chat widgets, consider using the built-in blocking parameters (block_cookies, block_ads, block_chats) instead. They handle the most common cases automatically without you needing to know the exact selectors.
Combining interaction parameters
All interaction parameters can be used together for complex scenarios. Here's a real-world example.
Example: Full cleanup pipeline
Accept cookies, hide the chat widget and promotional banner, scroll to the pricing section, and capture just the pricing table.
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"click_selector": "#accept-cookies",
"hide_selectors": [".chat-widget", ".promo-banner"],
"scroll_to": "#pricing",
"selector": "#pricing",
"delay": 1,
"format": "png"
}'
Tips for finding selectors
- Open the page in Chrome or Firefox
- Right-click the element you want and choose "Inspect"
- Look for a unique
class,id, ordata-*attribute - Test your selector in the console:
document.querySelector('.your-selector') - If it returns the right element, use that selector in the API
Prefer IDs (#pricing) over generic tag selectors (div > section) — they're more reliable and less likely to break when the site changes its layout.