Odel
shotanvil examples

shotanvil examples

@psykeproUpdated 3w ago

Screenshot/PDF/HTML rendering API. API key or x402 required — keyless access disabled.

Server endpointStreamable HTTPAPI keyProbed

This is the third-party server itself — Odel doesn't run it. Hitting this URL directly talks straight to the upstream server with no auth or proxying. Connect through Odel to front it with managed auth.

shotanvil-examples

Usage examples and a live-synced OpenAPI spec copy for the shotanvil screenshot API — 1 screenshot = 1 request, a free tier that's actually free, from $9/mo.

Base URL: https://api.shotanvil.com

Access paths

GET /take and POST /render-html accept three access paths, checked in this order:

  1. x402 — send an X-Payment header (pay-per-call, no signup, testnet-settled).
  2. API key — send X-Api-Key: <key> or ?access_key=<key>.
  3. Keyless — no credential, IP-rate-limited, only when the operator has keyless access enabled.

An invalid API key always fails with 401 and never falls through to keyless, even when keyless is enabled — a typo'd paying key never silently downgrades to a lower tier.

Get an API key at shotanvil.com.

Quickstart

Take a screenshot:

curl "https://api.shotanvil.com/take?url=https://example.com" \
  -H "X-Api-Key: $SHOTANVIL_API_KEY" \
  -o screenshot.png

Get text + metadata as JSON instead of raw bytes:

curl "https://api.shotanvil.com/take?url=https://example.com&response_format=json" \
  -H "X-Api-Key: $SHOTANVIL_API_KEY"

Render inline HTML:

curl -X POST https://api.shotanvil.com/render-html \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $SHOTANVIL_API_KEY" \
  -d '{"html": "<html><body><h1>Hello</h1></body></html>"}' \
  -o out.png

More runnable examples: examples/curl.sh, examples/node/screenshot.mjs.

Common GET /take parameters

ParamTypeNotes
urlstring, requiredTarget page URL, http/https only.
formatstringpng (default), jpeg, webp, or pdf.
full_pageboolCapture the full scrollable page height, not just the viewport.
viewport_width / viewport_heightint320–3840 / 240–2160.
cache_ttlintSeconds to cache this exact render, 0–86400.
freshboolBypass the cache read for this request.
block_adsboolBlock ad-network requests via an EasyList-derived blocklist.
block_cookie_bannersboolInject a CSS kill-list that hides common cookie-consent banners.
dark_modeboolEmulate prefers-color-scheme: dark before navigation.
response_formatstringbinary (default) returns raw bytes; json wraps image (base64) + extracted text/metadata.

Full parameter reference, request/response schemas, and every field's worked example live in openapi.json — open it in any OpenAPI viewer (e.g. editor.swagger.io) for the browsable version.

Rate limits

Each API key has a per-second rate limit and a daily call cap. GET /usage reports the current key's usage for the day. Exceeding either returns 429 with a retry_after_s field.

Keeping openapi.json in sync

openapi.json in this repo is a point-in-time copy, fetched from the live GET https://api.shotanvil.com/openapi.json endpoint — it is not hand-written and will drift as the API evolves.

Before relying on it for anything beyond casual browsing, or before any future update to this repo, re-fetch and diff:

curl -sS https://api.shotanvil.com/openapi.json -o /tmp/openapi.latest.json
diff openapi.json /tmp/openapi.latest.json

If they differ, review the diff, replace openapi.json with the fresh copy, and commit — do not hand-edit openapi.json directly.

License

Examples in this repo are MIT-licensed — copy and adapt freely. openapi.json describes the shotanvil API and is provided for reference only.