getsnap
v1.14.0
Published
Official Node.js SDK + CLI for getSnap.dev — Screenshot & PDF API
Downloads
2,184
Maintainers
Readme
getsnap
Official Node.js SDK and CLI for getSnap.dev — Screenshot, PDF, and video API.
Installation
npm install getsnapCommand-line (npx getsnap)
Every install ships a getsnap executable. No code required for one-off captures:
# Set your key once
export GETSNAP_KEY=sk_live_YOUR_KEY
# Capture a PNG and print the CDN URL
npx getsnap screenshot https://news.ycombinator.com
# Save a binary directly to disk
npx getsnap screenshot https://news.ycombinator.com --out hn.png
npx getsnap pdf https://news.ycombinator.com --out hn.pdf --full-page
npx getsnap og https://blog.example.com/post --out og.png
# Video (MP4, 10 seconds, 15 fps by default)
npx getsnap video https://getsnap.dev --out demo.mp4 --duration 5
# Account info
npx getsnap usage
npx getsnap referrals
# Everything else
npx getsnap --helpFull flag reference: npx getsnap --help. Every capture flag maps 1:1 to the SDK
option, so anything you can do with the JS SDK you can do from the CLI.
Quick Start (SDK)
import GetSnap from "getsnap";
const snap = new GetSnap("sk_live_YOUR_KEY");
// Take a screenshot
const { url } = await snap.screenshot({
url: "https://github.com",
format: "png",
full_page: true,
remove_popups: true,
});
console.log(url); // CDN URL to your screenshotFeatures
- Full TypeScript types for all options and responses
- Screenshot capture (URL or HTML)
- Binary response (raw image bytes)
- Batch capture (up to 100 URLs)
- Usage tracking
- Async status polling
- All API parameters supported:
lazy_load,wait_for_selector,hide_selectors,remove_selectors,extract_text,extract_html,click_selector,scroll_to_selector, and more
API
new GetSnap(apiKey, options?)
Create a client instance.
apiKey— Your getSnap.dev key (starts withsk_live_orsk_test_)options.baseUrl— Custom base URL (default:https://api.getsnap.dev)
snap.screenshot(options)
Take a screenshot. Returns { url, cached, request_id, extracted_text?, extracted_html? }.
const result = await snap.screenshot({
url: "https://example.com",
format: "png",
viewport_width: 1280,
viewport_height: 720,
full_page: true,
remove_popups: true,
block_ads: true,
lazy_load: true,
extract_text: true,
});snap.screenshotBinary(options)
Get raw image/PDF bytes as an ArrayBuffer.
import { writeFile } from "fs/promises";
const buffer = await snap.screenshotBinary({
url: "https://example.com",
format: "webp",
quality: 90,
});
await writeFile("screenshot.webp", Buffer.from(buffer));snap.ogImage(options)
Generate a 1200×630 Open Graph / Twitter Card image from any URL.
Applies social-share-optimized defaults on the server side (PNG,
hi-DPI, wait for network idle, block popups + ads). Same billing
as screenshot(): 1 credit per fresh capture, 0 credits for cache
hits.
const { url } = await snap.ogImage({
url: "https://blog.example.com/why-rust",
});
// Drop `url` directly into <meta property="og:image">All defaults are overrideable (viewport_width, viewport_height,
format, device_scale_factor, wait_for_selector, extra_delay_ms,
block_ads, remove_popups, dark_mode, css). Pass
response_type: "binary" to get raw bytes with
Cache-Control: public, max-age=604800, immutable instead of a JSON
URL.
snap.batch(options)
Capture multiple URLs in one request.
const batch = await snap.batch({
urls: ["https://github.com", "https://stripe.com", "https://vercel.com"],
format: "png",
remove_popups: true,
});
console.log(`${batch.succeeded}/${batch.count} captured`);
batch.results.forEach(r => console.log(r.source_url, "->", r.url));snap.usage()
Check current usage and quota.
const { used, limit, plan } = await snap.usage();
console.log(`${used}/${limit} (${plan})`);snap.referrals()
Get your referral code, ready-to-share URL, reward tier, and aggregated stats. Every getSnap.dev account has a unique code auto-generated at signup — no opt-in required. When someone signs up through your referral URL and pays their first invoice, your Stripe balance is credited by the configured amount (default $5.00).
const r = await snap.referrals();
console.log(r.referral_url);
// https://getsnap.dev/?ref=USERABC1
console.log(`${r.stats.paid} paid, ${r.stats.pending} pending`);
console.log(`Lifetime earned: $${(r.stats.total_earned_cents / 100).toFixed(2)}`);snap.diff(options)
Visual regression diff between two URLs. Captures both at identical dimensions, compares pixel-by-pixel with pixelmatch, returns before/after/diff URLs plus a similarity score (0-100).
Billed at 2 credits per fresh diff (1 per captured page). Cache hits on either side reduce the charge.
const r = await snap.diff({
before: { url: "https://staging.example.com/pricing" },
after: { url: "https://example.com/pricing" },
});
console.log(`Similarity: ${r.similarity.toFixed(2)}%`);
if (r.similarity < 99) {
console.log(`${r.changed_pixels} pixels changed - review:`, r.diff_url);
}Per-side overrides for slower-loading pages:
await snap.diff({
before: {
url: "https://staging.example.com",
wait_for_selector: "#pricing-table", // wait for lazy content
extra_delay_ms: 500,
},
after: {
url: "https://example.com",
css: "body { animation: none !important; }", // freeze animations
},
viewport_width: 1440,
threshold: 0.05, // more sensitive than default 0.1
});snap.audit(options)
Run an accessibility audit against a URL. Uses axe-core to evaluate WCAG 2.0 / 2.1 / 2.2 A/AA/AAA + Section 508 + best-practices rules and returns categorised violations, incomplete rules, pass counts, and (optionally) a screenshot.
Billed at 1 credit per audit + 1 more if include_screenshot: true.
const a = await snap.audit({ url: "https://example.com" });
console.log(a.summary);
// { total_violations: 2, critical: 0, serious: 0, moderate: 2, minor: 0 }
for (const v of a.violations.filter(v => v.impact === "critical")) {
console.error(v.id, v.help, v.help_url);
}snap.teams.* — team management
Share one plan, quota, and rate limit across multiple api_keys.
// Create a team - hoists your current plan onto the team
const team = await snap.teams.create({ name: "Acme Marketing" });
// Invite a member (owner/admin only)
const invite = await snap.teams.invite(team.id, { email: "[email protected]" });
console.log(`Accept URL: ${invite.accept_url}`);
// jane clicks the link, calls this from her own account:
const joined = await snap.teams.accept({ token: "<from-email>" });
// List members
const { members } = await snap.teams.members(team.id);
for (const m of members) {
console.log(`${m.role}: ${m.email}`);
}
// List teams you're in
const { teams } = await snap.teams.list();
// Leave a team (owners cannot use this)
await snap.teams.leave(team.id);Roles are owner / admin / member. Every team has exactly one
owner. Only owners and admins can invite. Owners cannot leave via
.leave() — they must transfer ownership or dissolve the
team first.
snap.status(requestId)
Check status of an async (webhook) request.
const status = await snap.status("req_abc123");Error Handling
import { GetSnap, GetSnapError } from "getsnap";
try {
await snap.screenshot({ url: "https://example.com", format: "png" });
} catch (err) {
if (err instanceof GetSnapError) {
console.error(err.status, err.error, err.message);
// 402, "quota_exceeded", "Monthly limit reached..."
}
}Migration from SnapAPI (v1.0.0)
The class was renamed from SnapAPI to GetSnap starting in v1.1.0.
Both names still work — SnapAPI and SnapAPIError remain as
aliases, so v1.0.0 code continues to compile without changes:
// still works
import { SnapAPI, SnapAPIError } from "getsnap";
const snap = new SnapAPI("sk_live_YOUR_KEY");New code should prefer GetSnap and GetSnapError.
License
MIT
