Clean by default
Consent walls, sign-in modals, newsletter popups and paywall scrims are removed before capture. Known CMPs are declined properly; anything else is caught by shape — fixed, painted, high z-index, covering the page.
Screenshot API
A screenshot API that removes consent walls, sign-in modals and paywall overlays before it captures. Most screenshot APIs succeed 93% of the time and return something usable 69% of the time — we measured it, and fixed it.
Left is the page as it loads. Right is what the API returns. No signup, no key.
We benchmarked 29 URLs across headless, stealth and headful browsers, from both a residential line and a datacenter address. Every number on this page came out of that run.
Consent walls, sign-in modals, newsletter popups and paywall scrims are removed before capture. Known CMPs are declined properly; anything else is caught by shape — fixed, painted, high z-index, covering the page.
Declining on your behalf for a throwaway render is defensible. Agreeing on your behalf is not. Reject buttons that are really paywall funnels are detected by their own label and skipped in favour of hiding.
Drop a render straight into an <img src> without publishing an API key to every browser that loads the page. Mint a signed URL server-side and the signature covers every parameter.
Viewport, device pixel ratio, full-page, PNG / JPEG / WebP, quality, dark mode, locale, timezone, element waits and delays. Sensible defaults so the simple call stays one line.
An MCP server, an OpenAPI description, llms.txt and a machine-readable api-catalog. Your agent can discover and call it without you writing a wrapper first.
Some pages are behind bot protection and no browser trick gets past them — we tested that too, and say so rather than pretending. You get a clear error, not a picture of a challenge page.
curl -X POST http://localhost:8301/v1/render \
-H "X-API-Key: $RENDERSHED_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.theguardian.com/international"}' \
-o shot.pngconst res = await fetch("http://localhost:8301/v1/render", {
method: "POST",
headers: {
"X-API-Key": process.env.RENDERSHED_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://www.booking.com",
width: 1440,
response: "json", // base64 instead of raw bytes
}),
});
const png = Buffer.from(await res.arrayBuffer());import os, requests
res = requests.post(
"http://localhost:8301/v1/render",
headers={"X-API-Key": os.environ["RENDERSHED_KEY"]},
json={"url": "https://www.bbc.com/news", "format": "jpeg", "quality": 80},
timeout=90,
)
open("shot.jpg", "wb").write(res.content)<!-- signed server-side; no key reaches the browser -->
<img src="http://localhost:8301/v1/render?url=https%3A%2F%2Fstripe.com&width=1200&sig=..."
width="1200" height="750" alt="stripe.com" loading="lazy">
| Name | Type | Default | Description |
|---|---|---|---|
url | string | required | The page to render. http and https only. |
width | int | 1440 | Viewport width, 200–3840. |
height | int | 900 | Viewport height, 200–4320. |
dpr | float | 1 | Device pixel ratio, up to 3. |
full_page | bool | false | Capture the whole document, not just the viewport. |
format | enum | png | png, jpeg or webp. |
quality | int | — | 1–100, for jpeg and webp. |
overlay_mode | enum | dismiss | off, hide or dismiss. |
block_ads | bool | true | Drop known ad and tracker requests. |
dark_mode | bool | false | Render with prefers-color-scheme: dark. |
wait_for_selector | string | — | Wait for a CSS selector before capture. |
delay_ms | int | 0 | Extra settle time, up to 10000. |
locale | string | en-US | Browser locale. |
timezone | string | UTC | IANA timezone. |
An agent that can see a page is more useful than one that cannot. Everything needed to discover and call this without a wrapper:
/openapi.json OpenAPI 3.1 description/llms.txt plain-language summary for models/index.md this page as markdown/.well-known/api-catalog RFC 9727 catalog/.well-known/mcp/server-card.json MCP server cardCached renders are free and never count against your quota. They cost us a disk read, so charging for them twice would be charging for nothing.
$0forever
100 / month
$9.99/ month
3,000 / month
$39.99/ month
20,000 / month
$99/ month
75,000 / month
Most of them return the page with the cookie banner still on it. We benchmarked a 29-URL corpus: 93% of renders technically succeeded, but only 69% were images you could actually use. Seven were ruined by consent overlays and exactly one by bot protection. rendershed treats that gap as the product.
Never. It either declines, where a genuine reject control exists, or it hides the banner cosmetically, which consents to nothing. Reject buttons that actually lead to a paid subscription are detected and skipped.
Sometimes, and we do not claim otherwise. We measured headless, stealth and headful browsers from both residential and datacenter addresses: the browser makes no difference, the IP makes some, and a small number of sites are simply not renderable. Those return an error rather than an image of a challenge page.
Mint a signed URL with POST /v1/sign and use it as the src. The signature covers every parameter, so the URL cannot be edited into a different render, and your API key never reaches the browser.
Yes. Rendershed exposes an MCP server so an AI agent can render a page and look at it as part of a task, plus an OpenAPI description and llms.txt for discovery.
Free for 100 renders a month, then $9.99 for 3,000, $39.99 for 20,000 and $99 for 75,000. Cached renders are free and never count against your quota, because serving one costs us a disk read.