Documentation Index
Fetch the complete documentation index at: https://mintlify.com/pinchtab/pinchtab/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Screenshots API captures visual snapshots of browser tabs. Screenshots are returned as:
- Base64-encoded strings (default)
- Raw JPEG binary data
- Saved files on disk
Capture Screenshot
GET /tabs/{id}/screenshot
curl "http://localhost:9867/tabs/tab_abc123/screenshot" | jq .
Query Parameters
JPEG quality (0-100). Higher = better quality, larger file size.
Return raw JPEG binary instead of base64 JSON
Set to file to save screenshot to disk
Disable CSS animations before capturing
Response (200 OK - JSON)
{
"format": "jpeg",
"base64": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
Response (200 OK - Raw)
When raw=true, returns raw JPEG binary with Content-Type: image/jpeg header.
Save to File
Save screenshot directly to disk instead of returning in response:
curl "http://localhost:9867/tabs/tab_abc123/screenshot?output=file"
Response:
{
"path": "/path/to/screenshots/screenshot-20260303-123456.jpg",
"size": 45678,
"format": "jpeg",
"timestamp": "20260303-123456"
}
Quality Levels
| Quality | File Size | Use Case |
|---|
| 60 | Smallest | Quick previews, thumbnails |
| 80 | Medium (default) | General screenshots |
| 90 | Large | High-quality captures |
| 95-100 | Largest | Maximum quality |
Complete Example
import requests
import base64
import time
BASE = "http://localhost:9867"
# Start instance
inst = requests.post(f"{BASE}/instances/start",
json={"mode": "headed"}).json()
# Open tab
tab = requests.post(f"{BASE}/instances/{inst['id']}/tabs/open",
json={"url": "https://example.com"}).json()
tab_id = tab["tabId"]
# Wait for page load
time.sleep(2)
# Capture screenshot (base64)
resp = requests.get(
f"{BASE}/tabs/{tab_id}/screenshot",
params={"quality": 90}
)
screenshot_data = resp.json()
# Save to file
with open("example.jpg", "wb") as f:
f.write(base64.b64decode(screenshot_data["base64"]))
print("Screenshot saved to example.jpg")
# Alternative: Get raw binary directly
resp = requests.get(
f"{BASE}/tabs/{tab_id}/screenshot",
params={"quality": 90, "raw": True}
)
with open("example_raw.jpg", "wb") as f:
f.write(resp.content)
print("Raw screenshot saved to example_raw.jpg")
# Cleanup
requests.post(f"{BASE}/instances/{inst['id']}/stop")
Multiple Screenshots Example
#!/bin/bash
BASE="http://localhost:9867"
TAB="tab_abc123"
SITES=(
"https://example.com"
"https://google.com"
"https://github.com"
)
for site in "${SITES[@]}"; do
# Navigate
curl -s -X POST "$BASE/tabs/$TAB/navigate" \
-d "{\"url\":\"$site\"}"
sleep 2
# Capture screenshot
NAME=$(echo $site | sed 's/https:\/\///' | sed 's/\//_/g')
curl -s "$BASE/tabs/$TAB/screenshot?raw=true&quality=85" \
> "${NAME}.jpg"
echo "Saved ${NAME}.jpg"
done
Disable Animations
Disable CSS animations before capturing for consistent screenshots:
curl "http://localhost:9867/tabs/tab_abc123/screenshot?noAnimations=true&raw=true" \
> screenshot.jpg
This is useful for:
- Automated testing (avoid animation flakiness)
- Consistent visual comparisons
- Cleaner documentation screenshots
Error Handling
Tab Not Found (404)
curl "http://localhost:9867/tabs/nonexistent/screenshot"
Response:
{
"error": "tab not found",
"statusCode": 404
}
Chrome Error (500)
# If page failed to load
curl "http://localhost:9867/tabs/tab_abc123/screenshot"
Response:
{
"error": "screenshot: page not ready",
"statusCode": 500
}
Best Practices
Wait for Page Load
Always wait for the page to fully load before capturing:
# Navigate
requests.post(f"{BASE}/tabs/{tab_id}/navigate",
json={"url": "https://example.com", "waitFor": "networkidle"})
# Now capture
resp = requests.get(f"{BASE}/tabs/{tab_id}/screenshot?raw=true")
Use Appropriate Quality
# Thumbnails: low quality
requests.get(f"{BASE}/tabs/{tab_id}/screenshot?quality=60")
# Documentation: medium quality
requests.get(f"{BASE}/tabs/{tab_id}/screenshot?quality=80")
# Detailed captures: high quality
requests.get(f"{BASE}/tabs/{tab_id}/screenshot?quality=95")
Prefer Raw for Large Files
# ✅ Good: Direct binary (more efficient)
resp = requests.get(f"{BASE}/tabs/{tab_id}/screenshot?raw=true")
with open("screenshot.jpg", "wb") as f:
f.write(resp.content)
# ❌ Bad: Base64 (larger payload, needs decoding)
resp = requests.get(f"{BASE}/tabs/{tab_id}/screenshot")
data = base64.b64decode(resp.json()["base64"])
with open("screenshot.jpg", "wb") as f:
f.write(data)
Disable Animations for Consistency
# For automated testing
requests.get(
f"{BASE}/tabs/{tab_id}/screenshot",
params={"noAnimations": True, "raw": True}
)
Use Cases
Visual Regression Testing
import requests
import hashlib
def capture_and_hash(tab_id):
resp = requests.get(
f"http://localhost:9867/tabs/{tab_id}/screenshot?raw=true&noAnimations=true"
)
return hashlib.md5(resp.content).hexdigest()
# Baseline
baseline_hash = capture_and_hash(tab_id)
# After changes
current_hash = capture_and_hash(tab_id)
if baseline_hash != current_hash:
print("Visual regression detected!")
Automated Documentation
# Capture screenshots for docs
pages = [
("https://example.com", "homepage"),
("https://example.com/features", "features"),
("https://example.com/pricing", "pricing")
]
for url, name in pages:
requests.post(f"{BASE}/tabs/{tab_id}/navigate",
json={"url": url, "waitFor": "networkidle"})
resp = requests.get(
f"{BASE}/tabs/{tab_id}/screenshot?raw=true&quality=90"
)
with open(f"docs/images/{name}.jpg", "wb") as f:
f.write(resp.content)
Monitor Page Changes
import time
while True:
# Capture screenshot
resp = requests.get(
f"{BASE}/tabs/{tab_id}/screenshot",
params={"output": "file", "quality": 80}
)
path = resp.json()["path"]
print(f"Screenshot saved: {path}")
time.sleep(300) # Every 5 minutes
Next Steps
PDF Export
Export pages as PDF documents
Screencast
Live streaming of tab content
Snapshot
Get structured page data
Navigation
Navigate before capturing