Public beta notice — the rendering API is rolling out to accounts progressively. If a request fails, email support@ottersnap.com and we'll enable your key right away.

Documentation

Everything you need to render web pages with OtterSnap. Plain REST, JSON in, image bytes out.

Quick start

  1. Grab an API key (Free plan includes 100 renders/month).
  2. Send a POST request with the target URL.
  3. 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.

header
Authorization: Bearer otter_live_YOUR_KEY

Take 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

ParameterTypeDescription
urlstring · requiredThe page to render. Must start with http:// or https://.
formatstring · default: pngOutput format: png or jpeg.
fullPageboolean · default: falseCapture the entire scrollable page instead of the viewport.
widthinteger · default: 1280Viewport width in pixels (320–3840).
heightinteger · default: 800Viewport height in pixels (240–2160). Ignored when fullPage is true.
scaleinteger · default: 1Device scale factor. Set 2 for retina-quality captures.
darkModeboolean · default: falseRender the page in dark color scheme.
delayinteger · default: 0Extra wait in milliseconds (0–10000) after the page loads — useful for animations.
cookieBlockboolean · default: falseHide common cookie/consent banners before capturing.
selectorstringCSS selector to capture a single element instead of the whole page.

Examples

cURL
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.png
JavaScript (fetch)
const 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);
Python (requests)
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

ParameterTypeDescription
urlstring · requiredThe page to convert to PDF.
paperstring · default: A4Paper size: A4, A3, Letter, Legal or Tabloid.
cURL
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.pdf

Generate 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.

ParameterTypeDescription
titlestring · requiredMain headline. Keep it under ~60 characters for the largest font size.
subtitlestringSupporting line shown under the headline.
siteNamestring · default: ottersnap.comBrand name shown in the bottom-left corner.
themestring · default: emeraldColor theme: emerald, sky, violet or slate.
cURL
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.png

Using the SDKs

Official clients wrap the raw REST calls above with typed errors and sane timeouts.

JavaScript — npm install ottersnap
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" });
Python — from ottersnap import OtterSnap
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

HTTPCodeMeaning
400invalid_urlThe url field is missing, malformed, or points at a private network.
401invalid_api_keyThe Authorization header is missing or the key is wrong.
422render_failedThe target page failed to load or timed out (30s). Check the URL.
429quota_exceededMonthly 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