RenderScreenshot Python SDK
Official Python SDK for RenderScreenshot - Screenshot API for developers.
Installation
pip install git+https://github.com/Render-Screenshot/rs-python.git
The package is not on PyPI yet. Until it is, install it from GitHub.
Quick Start
from renderscreenshot import Client, TakeOptions
# Initialize client with your live API key
client = Client("rs_live_xxxxx")
# Take a screenshot
options = (
TakeOptions.url("https://example.com")
.preset("og_card")
.block_ads()
)
image = client.take(options)
# Save to file
with open("screenshot.png", "wb") as f:
f.write(image)
Features
- Simple API - Fluent builder pattern for easy configuration
- Full Type Hints - Complete type annotations for IDE support
- Presets - Built-in presets for common use cases (OG cards, Twitter cards, etc.)
- Device Emulation - Emulate iPhone, Pixel, iPad, and more
- Content Blocking - Block ads, trackers, cookie banners, and chat widgets
- PDF Generation - Convert pages to PDF with full customization
- Batch Processing - Process multiple URLs efficiently
- Cache Management - Control caching and purge cached screenshots
- Webhook Support - Verify and parse webhook payloads
- Signed URLs - Generate signed URLs for embedding
Usage
Basic Screenshot
from renderscreenshot import Client, TakeOptions
client = Client("rs_live_xxxxx")
# Simple screenshot
image = client.take(TakeOptions.url("https://example.com"))
# With options
options = (
TakeOptions.url("https://example.com")
.width(1200)
.height(630)
.format("png")
)
image = client.take(options)
Using Presets
# OG Card (1200x630)
options = TakeOptions.url("https://example.com").preset("og_card")
# Twitter Card
options = TakeOptions.url("https://example.com").preset("twitter_card")
# Full Page Screenshot
options = TakeOptions.url("https://example.com").preset("full_page")
Device Emulation
# iPhone 14 Pro
options = TakeOptions.url("https://example.com").device("iphone_14_pro")
# Pixel 7
options = TakeOptions.url("https://example.com").device("pixel_7")
# iPad Pro
options = TakeOptions.url("https://example.com").device("ipad_pro_12")
Content Blocking
options = (
TakeOptions.url("https://example.com")
.block_ads()
.block_trackers()
.block_cookie_banners()
.block_chat_widgets()
)
Dark Mode
options = (
TakeOptions.url("https://example.com")
.dark_mode()
.preset("og_card")
)
PDF Generation
options = (
TakeOptions.url("https://example.com")
.format("pdf")
.pdf_paper_size("a4")
.pdf_margin("1in")
.pdf_print_background()
)
pdf = client.take(options)
JSON Response
# Get metadata along with screenshot URL
response = client.take_json(
TakeOptions.url("https://example.com").preset("og_card")
)
print(f"Request ID: {response['id']}") # req_...
image = response["image"]
print(f"Screenshot URL: {image['url']}")
print(f"Size: {image['width']}x{image['height']}")
print(f"File size: {image['size']} bytes")
# Optional sections
cache = response.get("cache", {})
print(f"Cache hit: {cache.get('hit')}, key: {cache.get('key')}")
usage = response.get("usage", {})
print(f"Credits used: {usage.get('credits')}, remaining: {usage.get('remaining')}")
The response has id, status, image (url, width, height, size,
format), and optional metadata, cache (hit, key, url, expires_at)
and usage (credits, remaining) objects.
Batch Processing
# Multiple URLs with shared options
urls = ["https://example1.com", "https://example2.com", "https://example3.com"]
options = TakeOptions.url("").preset("og_card")
results = client.batch(urls, options)
# Per-URL options
requests = [
{"url": "https://example1.com", "options": {"width": 1200}},
{"url": "https://example2.com", "options": {"preset": "full_page"}},
]
results = client.batch(requests)
# Check batch status
status = client.get_batch("batch_123")
print(f"Completed: {status['completed']}/{status['total']}")
Signed URLs
Signed URLs call the GET /v1/screenshot render endpoint without an API key,
so you can put them in <img> tags or og:image meta tags. Signing needs your
public key ID (rs_pub_...) and your secret signing key (rs_secret_...) from
the dashboard. Your live API key is not used for signing. Keep the secret key on
your server.
from datetime import datetime, timedelta
client = Client(
"rs_live_xxxxx",
signing_key="rs_secret_xxxxx",
public_key_id="rs_pub_xxxxx",
)
# Generate a signed URL that expires in 24 hours (max 30 days)
options = TakeOptions.url("https://example.com").preset("og_card")
signed_url = client.generate_url(
options,
datetime.now() + timedelta(hours=24),
)
# Or pass the credentials per call
signed_url = client.generate_url(
options,
datetime.now() + timedelta(hours=24),
signing_key="rs_secret_xxxxx",
public_key_id="rs_pub_xxxxx",
)
# Use in HTML: <img src="{signed_url}" />
generate_url() raises RenderScreenshotError (code invalid_request) when
signing_key or public_key_id is missing. A signed URL only carries the
options that the GET endpoint reads (target, viewport size and scale, preset,
device, full_page, element, format, quality, delay, timeout, click, hide,
remove, ad and cookie-banner blocking, dark mode, user agent, locale, timezone,
cache and PDF options). Use client.take() for all other options.
Cache Management
# Get cached screenshot
image = client.cache.get("cache_key")
# Delete cache entry
deleted = client.cache.delete("cache_key")
# Bulk purge
result = client.cache.purge(["key1", "key2", "key3"])
# Purge by URL pattern
result = client.cache.purge_url("https://mysite.com/blog/*")
# Purge by date
from datetime import datetime
result = client.cache.purge_before(datetime(2024, 1, 1))
Webhook Verification
from renderscreenshot import verify_webhook, parse_webhook
# In your webhook handler
def handle_webhook(request):
signature = request.headers.get("X-Webhook-Signature")
timestamp = request.headers.get("X-Webhook-Timestamp")
payload = request.get_data(as_text=True)
if not verify_webhook(payload, signature, timestamp, WEBHOOK_SECRET):
return "Invalid signature", 401
event = parse_webhook(payload)
if event["type"] == "screenshot.completed":
response = event["data"]["response"]
print(f"Screenshot ready: {response['url']}")
elif event["type"] == "screenshot.failed":
error = event["data"]["error"]
print(f"Failed ({error['code']}): {error['message']}")
elif event["type"] in ("batch.completed", "batch.failed"):
print(f"Batch {event['data']['batch_id']}: {event['data'].get('summary')}")
return "OK", 200
Request Format
take(), take_json() and batch() send the nested JSON body that the API
expects (for example {"viewport": {"width": 1200}, "output": {"format": "png"}}).
TakeOptions.to_params() returns this body. TakeOptions.to_query_string() and
TakeOptions.to_flat_params() return the flat query parameters for
GET /v1/screenshot. take_json() sends Accept: application/json.
Context Manager
# Automatically closes the client when done
with Client("rs_live_xxxxx") as client:
image = client.take(TakeOptions.url("https://example.com"))
All Options
Target
url(str)- URL to capturehtml(str)- HTML content to render
Viewport
width(int)- Viewport width in pixelsheight(int)- Viewport height in pixelsscale(float)- Device scale factor (1-3)mobile(bool)- Enable mobile emulation
Capture
full_page(bool)- Capture full scrollable pageelement(str)- CSS selector for element captureformat(str)- Output format:png,jpeg,webp,pdfquality(int)- JPEG/WebP quality (1-100)
Wait
wait_for(str)- Wait condition:load,networkidle,domcontentloadeddelay(int)- Additional delay in millisecondswait_for_selector(str)- Wait for CSS selector to appearwait_for_timeout(int)- Maximum wait time in seconds (1-60)
Presets
preset(str)- Use preset:og_card,twitter_card,full_page, etc.device(str)- Emulate device:iphone_14_pro,pixel_7, etc.
Blocking
block_ads(bool)- Block ad network domainsblock_trackers(bool)- Block analytics/trackingblock_cookie_banners(bool)- Auto-dismiss cookie popupsblock_chat_widgets(bool)- Block chat widgetsblock_urls(list)- Block URLs matching patternsblock_resources(list)- Block resource types:font,media,image,script,stylesheet
Page Manipulation
inject_script(str)- Inject JavaScriptinject_style(str)- Inject CSSclick(str)- Click element before capturehide(list)- Hide elements (visibility: hidden)remove(list)- Remove elements from DOM
Browser
dark_mode(bool)- Enable dark modereduced_motion(bool)- Enable reduced motionmedia_type(str)- Media type:screen,printuser_agent(str)- Custom user agenttimezone(str)- IANA timezonelocale(str)- BCP 47 localegeolocation(lat, lng, accuracy)- Spoof geolocation
Network
headers(dict)- Custom HTTP headerscookies(list)- Cookies to setauth_basic(username, password)- HTTP Basic authauth_bearer(token)- Bearer token authbypass_csp(bool)- Bypass Content Security Policy
Cache
cache_ttl(int)- Cache TTL in secondscache_refresh(bool)- Force cache refreshcache_available(bool)- Reuse an identical cached render inside the TTL (0 credits). Without it every request renders a fresh screenshot
PDF (when format is "pdf")
pdf_paper_size(str)- Paper size:a4,letter, etc.pdf_width(str)- Custom width (CSS units)pdf_height(str)- Custom heightpdf_landscape(bool)- Landscape orientationpdf_margin(str)- Uniform marginpdf_margin_top/right/bottom/left(str)- Individual marginspdf_scale(float)- Scale factor (0.1-2.0)pdf_print_background(bool)- Include backgroundspdf_page_ranges(str)- Page rangespdf_header(str)- Header HTMLpdf_footer(str)- Footer HTMLpdf_fit_one_page(bool)- Fit to single pagepdf_prefer_css_page_size(bool)- Use CSS page size
Storage (BYOS)
storage_enabled(bool)- Enable custom storagestorage_path(str)- Path templatestorage_acl(str)- ACL:public-read,private
Error Handling
from renderscreenshot import Client, TakeOptions, RenderScreenshotError
client = Client("rs_live_xxxxx")
try:
image = client.take(TakeOptions.url("https://example.com"))
except RenderScreenshotError as e:
print(f"Error: {e.message}")
print(f"Code: {e.code}")
print(f"HTTP Status: {e.http_status}")
print(f"Param: {e.param}") # e.g. "url" for validation errors
print(f"Request ID: {e.request_id}")
if e.retryable:
if e.retry_after:
print(f"Retry after {e.retry_after} seconds")
# Implement retry logic
Requirements
- Python 3.9+
- httpx
License
MIT License - see LICENSE for details.
Links
Metadata
Release files for renderscreenshot 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| renderscreenshot-1.0.2.tar.gz | 39.4 kB | With provenance | Details for renderscreenshot-1.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| renderscreenshot-1.0.2-py3-none-any.whl | Python 3 | none | any | Details for renderscreenshot-1.0.2-py3-none-any.whl |
Total release size: 65.8 kB
Release files / renderscreenshot-1.0.2.tar.gz
| Download URL | renderscreenshot-1.0.2.tar.gz |
|---|---|
| Size | 39.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0ac45912022127ca38b0098d9282868b981841f09cf66306fdc518585a8e01c3
|
|
BLAKE2b-256 checksum How to use checksums |
211ea04e19b026bcbb7767eddefb7b3321741b6efea95d332a406b8c237996df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / renderscreenshot-1.0.2-py3-none-any.whl
| Download URL | renderscreenshot-1.0.2-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5eddbbdf22c425b7524223f7655f017911143297b556c8cc827c4c84def6716c
|
|
BLAKE2b-256 checksum How to use checksums |
a11c5e5b911b1d99c4df0e313cc9ffed6fa0eee904ede20f58633081383d205f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for renderscreenshot 1.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for renderscreenshot-1.0.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.