Documentation
Everything you need to render web pages with OtterSnap. Plain REST, JSON in, image bytes out.
Quick start
- Grab an API key (Free plan includes 100 renders/month).
- Send a POST request with the target URL.
- Save the response body — it's your image or PDF.
Authentication
All requests need your secret key in the Authorization header. Keep it server-side — never ship it in frontend code.
Authorization: Bearer otter_live_YOUR_KEYTake a screenshot
POSThttps://api.ottersnap.com/v1/screenshot
Returns raw image bytes on success (image/png or image/jpeg) and a JSON error otherwise.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| url | string · required | The page to render. Must start with http:// or https://. |
| format | string · default: png | Output format: png or jpeg. |
| fullPage | boolean · default: false | Capture the entire scrollable page instead of the viewport. |
| width | integer · default: 1280 | Viewport width in pixels (320–3840). |
| height | integer · default: 800 | Viewport height in pixels (240–2160). Ignored when fullPage is true. |
| scale | integer · default: 1 | Device scale factor. Set 2 for retina-quality captures. |
| darkMode | boolean · default: false | Render the page in dark color scheme. |
| delay | integer · default: 0 | Extra wait in milliseconds (0–10000) after the page loads — useful for animations. |
| cookieBlock | boolean · default: false | Hide common cookie/consent banners before capturing. |
| selector | string | CSS selector to capture a single element instead of the whole page. |
Examples
curl -X POST https://api.ottersnap.com/v1/screenshot \
-H "Authorization: Bearer otter_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://github.com",
"format": "png",
"fullPage": true,
"width": 1280,
"scale": 2
}' --output shot.pngconst res = await fetch("https://api.ottersnap.com/v1/screenshot", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OTTERSNAP_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://github.com",
format: "png",
fullPage: true,
}),
});
const imageBuffer = Buffer.from(await res.arrayBuffer());
fs.writeFileSync("shot.png", imageBuffer);import os, requests
res = requests.post(
"https://api.ottersnap.com/v1/screenshot",
headers={"Authorization": f"Bearer {os.environ['OTTERSNAP_KEY']}"},
json={"url": "https://github.com", "format": "png"},
)
open("shot.png", "wb").write(res.content)Generate a PDF
POSThttps://api.ottersnap.com/v1/pdf
| Parameter | Type | Description |
|---|---|---|
| url | string · required | The page to convert to PDF. |
| paper | string · default: A4 | Paper size: A4, A3, Letter, Legal or Tabloid. |
curl -X POST https://api.ottersnap.com/v1/pdf \
-H "Authorization: Bearer otter_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://ottersnap.com/invoice/1042",
"paper": "A4"
}' --output invoice.pdfGenerate an OG image
POSThttps://api.ottersnap.com/v1/og
Returns a branded 1200×630 social card. No HTML needed — pass your copy and pick a theme.
| Parameter | Type | Description |
|---|---|---|
| title | string · required | Main headline. Keep it under ~60 characters for the largest font size. |
| subtitle | string | Supporting line shown under the headline. |
| siteName | string · default: ottersnap.com | Brand name shown in the bottom-left corner. |
| theme | string · default: emerald | Color theme: emerald, sky, violet or slate. |
curl -X POST https://api.ottersnap.com/v1/og \
-H "Authorization: Bearer otter_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Introducing OtterSnap",
"subtitle": "One fast API for developers and AI agents",
"theme": "emerald"
}' --output og.pngUsing the SDKs
Official clients wrap the raw REST calls above with typed errors and sane timeouts.
import { OtterSnap } from "ottersnap";
const otter = new OtterSnap(process.env.OTTERSNAP_KEY);
const png = await otter.screenshot("https://example.com", {
fullPage: true,
darkMode: true,
delay: 1500,
});
fs.writeFileSync("shot.png", png);
const og = await otter.og({ title: "Hello", theme: "emerald" });import os
from ottersnap import OtterSnap
otter = OtterSnap(os.environ["OTTERSNAP_KEY"])
png = otter.screenshot("https://example.com", full_page=True)
open("shot.png", "wb").write(png)Errors & limits
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_url | The url field is missing, malformed, or points at a private network. |
| 401 | invalid_api_key | The Authorization header is missing or the key is wrong. |
| 422 | render_failed | The target page failed to load or timed out (30s). Check the URL. |
| 429 | quota_exceeded | Monthly quota used up. Upgrade or wait for the reset. |
Renders time out after 30 seconds. Every response includes an X-OtterSnap-Credits-Used header so you can reconcile usage.
Stuck on something?
Email us your request and response — we answer within 24 hours.
support@ottersnap.com