API reference
Two endpoints and one idea: give it a URL, get back an image of the page rather than of a consent wall.
Quickstart
# No key needed. Paste this as it is.
curl -X POST https://shots.rendershed.com/v1/render \
-H "Content-Type: application/json" \
-d '{"url": "theguardian.com/international"}' \
-o shot.png
# A free key raises the limit from 20 renders an hour to 100 a month
# and keeps working from any address:
# -H "X-API-Key: $RENDERSHED_KEY"
The scheme is optional — example.com works, and
https is assumed, falling back to http if nothing answers.
Authentication
A key is optional. A call without one runs on the anonymous tier — 20 renders an hour, metered against your address — so every example here works pasted. A key raises the limit and detaches it from where you are calling from. Note the difference: no key is anonymous, a wrong key is rejected.
| Tier | Limit | Extras |
|---|---|---|
| anonymous | 20 / hour per IP | viewport capture only |
| free key | 100 / month | same features, any address |
| paid | 3,000 – 75,000 / month | base64, retina, longer cache, full page |
Server to server, send your key as a header:
X-API-Key: rsk_live_...
Authorization: Bearer rsk_live_... # either works
For an <img> tag, mint a signed URL instead so no key
reaches the browser. The signature covers every parameter, so the URL
cannot be edited into a different render, and signed GETs are the only
responses a CDN will cache.
curl -X POST https://shots.rendershed.com/v1/sign \
-H "X-API-Key: $RENDERSHED_KEY" -H "Content-Type: application/json" \
-d '{"url": "stripe.com", "width": 1200}'
# {"url": "/v1/render?url=...&width=1200&kid=...&sig=...", "plan": "growth"}
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/render | Render a page. Key in a header. |
GET | /v1/render | Render a page from a signed query string. CDN-cacheable. |
POST | /v1/sign | Mint a signed URL. |
GET | /healthz | Service and cache status. |
Parameters
| 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. |
cache_ttl | int | 86400 | Seconds a render may be served from cache. Capped by your plan. |
fresh | bool | false | Bypass the cache for this call. The result is still stored. |
response | enum | binary | json returns base64 in a JSON envelope. Paid plans. |
Overlay removal
overlay_mode decides how hard the renderer works to give you
the page instead of what is covering it.
| Mode | Behaviour |
|---|---|
off | Leaves the page exactly as it loads. |
hide | Hides known consent containers with CSS. Consents to nothing. |
dismiss | Default. Hides, plus verified reject clicks, plus a generic modal sweep. |
It never clicks “accept”. Where a reject control is really a paid upsell — the Guardian's is labelled “Reject all and subscribe” — it is detected by its own label and skipped in favour of hiding, because clicking it navigates away from the page you asked for.
Responses
By default the body is the image. Ask for JSON when your pipeline needs base64 rather than bytes:
curl -X POST https://shots.rendershed.com/v1/render \
-H "X-API-Key: $RENDERSHED_KEY" -H "Content-Type: application/json" \
-d '{"url": "example.com", "response": "json"}'
{
"image_b64": "iVBORw0KGgoAAAANSUhEUg...",
"format": "png",
"bytes": 17883,
"cached": false,
"width": 1440,
"height": 900,
"ms": 1194
}
| Header | Meaning |
|---|---|
X-Rendershed-Cache |
HIT or MISS. A HIT costs nothing and is not billed. |
X-Rendershed-Ms |
Render time in milliseconds, from the original render. |
X-Rendershed-Suppressed |
Which overlays were removed, or how many were hidden. |
Cache-Control |
Set on signed GET responses so a CDN can store them. |
Caching
Renders are cached on the parameters that change pixels. Asking for the same image as JSON instead of binary, or with a different TTL, still hits. A cached render is free and does not count against your quota — not the monthly allowance and not the hourly limit either. It costs us a disk read, so charging for it would be charging for nothing.
Pass fresh: true to bypass the cache for one call.
The result is still stored for the next one.
Errors
| Status | Meaning |
|---|---|
400 |
Invalid parameters, or a URL that will not be fetched (bad scheme, blocked port, non-public host) |
401 |
No API key, or a signed URL with no signature |
402 |
The plan does not include the requested feature |
403 |
Invalid API key, or a signature that does not match |
429 |
Quota exceeded for the hour |
502 |
The page could not be rendered |
503 |
The render fleet is unreachable |
504 |
The render exceeded its deadline |
Errors are JSON with an error field. A page behind
bot protection returns a clear failure rather than an image of a challenge
screen.
Plans and limits
| Plan | Renders | Notes |
|---|---|---|
free |
100 / month | PNG, JPEG, WebP, Overlay removal, Signed URLs, 24-hour cache |
starter |
3,000 / month | base64 / JSON response, 7-day cache, Retina (2x) output, Email support |
growth |
20,000 / month | 30-day cache, Higher concurrency, Priority queue, MCP server access |
scale |
75,000 / month | Full-page capture, 4K and 3x output, Overage at $0.001 / render, Self-hosted option |
Full-page capture is Scale only: an unbounded document height is an unbounded surface to rasterise, and a long page can cost ten times a viewport capture.
MCP
An agent can call rendershed directly through the Model Context Protocol.
The render_url tool returns the image plus a note about what
was removed, so the agent knows whether it is looking at the page or at a
wall.
https://mcp.rendershed.com/mcp # streamable HTTP
/openapi.jsonOpenAPI 3.1/llms.txtsummary for modelsserver-card.jsonMCP card