Screenshot one element
Capture just one part of a page, such as a price block, a chart or a table, by giving its CSS selector, and the image is cropped to that element alone, with no menu, sidebar or empty space around it. You pay per use, with no subscription.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
capture just a CSS selector
Why aim at an element instead of cropping
Cropping a full screenshot after the fact relies on fixed pixel positions, and those break the instant the layout shifts, an ad loads or a cookie banner pushes everything down by forty pixels. CSS selectors have named the parts of a page since the early days of styled web pages, and that same addressing turns out to be the most durable way to aim a screenshot. As long as the element keeps its class or id, the capture keeps working, usually far longer than any coordinate survives a redesign.
What you get and where it helps
You give a page address and the selector of the block you want. The page is loaded, the element is located, the tool waits until it has finished rendering and then captures only its box, with no header, sidebar or blank space around it. Pricing tools capture just the price block on a competitor's product page on a schedule. Analytics teams save a picture of one chart at the end of each reporting period, and quality teams check a single component after a change. If the selector matches nothing, you get a clear error instead of a silent blank.
Why selector-based capture is the reliable approach
CSS selectors have identified page elements since the earliest days of styled HTML, and that same addressing scheme turns out to be the most durable way to target a screenshot — far more reliable than fixed pixel coordinates, which break the instant a page's layout changes, an ad loads, or a cookie banner shifts everything down by forty pixels. Selector-based capture keeps working as long as the element's class or id stays intact, which is usually far longer than any fixed coordinate survives a redesign.
What you can do with it
Competitor price monitoring
A pricing tool captures just the price element on a competitor's product page on a schedule, ignoring the rest of the page entirely.
Dashboard chart archiving
An analytics tool saves a visual snapshot of a single chart element at the end of each reporting period for historical reference.
Component-level QA
A QA process captures one specific UI component after a code change to confirm it renders correctly without reviewing the full page manually.
FAQ
What if my selector matches multiple elements?
The task targets the matching element found on the rendered page; for predictable results, use a selector specific enough to identify a single element, such as an id.
Is there a free tier?
There's no free tier — free tiers get abused and slow everyone down. No subscription, no tokens, no invented credits, and a failed task is never charged.
Can I monitor the same element over time?
Yes, scheduling repeated requests against the same URL and selector is a common pattern for price or content monitoring.
Does it wait for the element to finish rendering?
Yes, the task waits for the targeted element to finish rendering before capturing it, which matters for elements that load asynchronously.
What happens if the selector doesn't match anything?
The task retries up to three times and then returns a clear error rather than failing silently; you are never charged for a failed capture.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/screenshot-element \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","selector":"h1"}'const res = await fetch("https://api.kit.forhosting.com/web/screenshot-element", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://example.com",
"selector": "h1"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/screenshot-element",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://example.com",
"selector": "h1"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/screenshot-element", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://example.com","selector":"h1"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://example.com","selector":"h1"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/screenshot-element", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://example.com",
"selector": "h1"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.screenshot_element",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |
Technical notes
This endpoint targets a single CSS selector and returns exactly that element, cropped precisely, nothing extraneous included.
When the whole page is noise
Cropping a full screenshot after the fact is fragile — it breaks the moment the layout shifts a pixel — while targeting the element directly at capture time stays accurate no matter what surrounds it.
How targeting works
Send POST /web/screenshot-element with a URL and a CSS selector, and the task loads the page, locates the matching element in the rendered DOM, waits for it to finish rendering, and captures only its bounding box — no header, no sidebar, no unrelated whitespace. It's asynchronous like every task here: an immediate task_id, and the final image delivered by signed webhook or a signed link valid for 24 hours.
Built for repeated, targeted checks
A failed capture, whether the selector doesn't match or the page times out, is never billed; the task retries three times automatically and then returns a clear, specific error so a broken selector doesn't fail silently in a monitoring pipeline. At a $0.040 base per request plus $0.001 per URL, capturing the same selector on a schedule — hourly, daily, after every deploy — stays affordable enough to automate without a second thought.
Integration use cases
Widget preview thumbnails
An embeddable widget provider generates a clean preview image of just the widget for its own marketing site, with none of the host page around it.
Technical questions
How does the element screenshot API know what to capture?
You provide a CSS selector along with the URL, and the task locates that exact element in the rendered page and captures only its bounding box.
How is pricing structured?
A $0.040 base per request plus $0.001 per URL, published and predictable for scheduling recurring captures.
How do I get the image back?
Through a signed webhook when the task completes, or a signed link that stays valid for 24 hours.