SnapRender: see any web page
Real Chrome screenshots of any URL, saved as an image file you can look at and send to the user. Cookie consent pop-ups and ads are blocked by default. It also reads pages as clean markdown.
Setup (once)
- Get a free key (200 captures a month, no card): https://snap-render.com/auth/signup
- Put it in
~/.openclaw/openclaw.json:
OpenClaw then sets{ skills: { entries: { snaprender: { apiKey: "sk_live_..." } } } }$SNAPRENDER_API_KEYfor every run. If your agent runs commands in a sandbox, also setSNAPRENDER_API_KEYin the sandbox environment (skill keys are not passed into sandboxes).
Capture a page
Use the exec tool with curl, not the browser tool: one request, no browser to drive, and the result is a ready image file.
Replace TARGET_URL and keep everything else as is:
mkdir -p snaprender && OUT="$PWD/snaprender/shot-$(date +%Y%m%d-%H%M%S)-$$.jpg"
code=$(jq -n --arg url 'TARGET_URL' \
'{url: $url, format: "jpeg", quality: 80, block_ads: true, block_cookie_banners: true}' \
| curl -sS -X POST "https://app.snap-render.com/v1/screenshot" \
-H "X-API-Key: $SNAPRENDER_API_KEY" -H "Content-Type: application/json" \
-d @- -o "$OUT" -w '%{http_code}')
if [ "$code" = 200 ]; then echo "saved $OUT ($(wc -c < "$OUT" | tr -d " ") bytes)"; else echo "error $code: $(cat "$OUT")"; rm -f "$OUT"; fi
Then:
- Send it to the user with the
messagetool, giving the printed path as the media file. Never paste image data into the chat. - Look at it yourself with
view_imageand the same path when the user asks what the page shows, whether it looks broken, or to compare pages.
Rules:
- Build the JSON with
jq --argas above. Never put user input straight into the shell string or the JSON. - Use
$SNAPRENDER_API_KEYexactly as written. Never print or echo the key. - Each capture gets its own file (named by time), so comparisons never overwrite each other.
Options
Add fields to the jq object, for example {url: $url, device: "iphone_15_pro", dark_mode: true, ...}.
| Field | Values | Default |
|---|---|---|
device |
iphone_14, iphone_15_pro, pixel_7, ipad_pro, macbook_pro |
desktop 1280x800 |
full_page |
true captures the whole scrollable page |
false |
dark_mode |
true |
false |
width, height |
320-3840, 200-10000 | 1280, 800 |
format |
jpeg, png, webp, pdf (match the file extension) |
jpeg |
quality |
1-100 (jpeg, webp) | 80 here |
delay |
ms to wait after load, up to 10000 (slow or animated pages) | 0 |
hide_selectors |
CSS selectors to hide, comma separated | none |
click_selector |
CSS selector to click before the capture | none |
block_ads, block_cookie_banners |
false to keep them |
true |
cache |
true reuses a recent identical capture, free of charge |
false |
Common requests:
- "on my phone" or "mobile":
device: "iphone_15_pro" - "the whole page":
full_page: true - "desktop vs mobile": run the command twice, once with a
device, and send both files - "as a PDF":
format: "pdf", and name the file.pdf
Read a page as markdown
For "what does this page say", summaries or quotes. Lighter on context than an image.
jq -n --arg url 'TARGET_URL' '{url: $url, type: "markdown", max_length: 20000}' \
| curl -sS -X POST "https://app.snap-render.com/v1/extract" \
-H "X-API-Key: $SNAPRENDER_API_KEY" -H "Content-Type: application/json" -d @- \
| jq -r 'if .content then .content else . end'
type can also be text, article (title, author, text), links (every link on the page) or metadata (title, description, social tags). Add selector: "main" to read one part of the page.
Watch a page for changes
SnapRender can capture a page on a schedule and compare each capture with the previous one, so nothing has to keep running on your side:
jq -n --arg url 'TARGET_URL' '{url: $url, interval: "daily", change_threshold: 0.5, notify_email: true}' \
| curl -sS -X POST "https://app.snap-render.com/v1/schedules" \
-H "X-API-Key: $SNAPRENDER_API_KEY" -H "Content-Type: application/json" -d @- | jq .
interval:hourly,dailyorweekly(the free plan has daily and weekly, for one page).change_threshold: percent of the page that must change to count as a change (0.5 is a good default).notify_email: trueemails the account owner when the page changes.- Later,
GET /v1/scheduleslists them andGET /v1/schedules/ID/capturesshows each capture with the percent changed.
Credits left
curl -sS "https://app.snap-render.com/v1/usage" -H "X-API-Key: $SNAPRENDER_API_KEY" | jq '{plan, usage}'
Errors and odd results
| What you see | Meaning | What to do |
|---|---|---|
error 401 |
Key missing or wrong | Check skills.entries.snaprender.apiKey, or the sandbox environment |
error 429 |
Monthly quota or per-minute limit reached | Wait a minute, or upgrade at https://snap-render.com/pricing |
error 400 |
Bad URL or option | Read the message and fix that field |
| The image shows a "verify you are human" or security check page | The site's firewall (often Cloudflare) blocks automated visits | Tell the user. If it is their own site, they can let SnapRender in: https://snap-render.com/docs/allow-snaprender |
| Blank or half-loaded image | Slow page | Retry with delay: 3000 |
Docs: https://snap-render.com/docs. Pricing: https://snap-render.com/pricing
