snapshot-api
v1.0.0
Published
Official TypeScript/JavaScript SDK for Snapshot API — screenshot-as-a-service
Downloads
9
Maintainers
Readme
snapshot-api
Official Node.js / TypeScript SDK for Snapshot API — screenshot-as-a-service.
npm install snapshot-apiQuick Start
import { SnapshotClient } from 'snapshot-api';
const client = new SnapshotClient({
apiKey: process.env.SNAPSHOT_API_KEY!,
});
// Capture and wait in one call
const result = await client.capture('https://stripe.com');
console.log(result.screenshots[0].url);Authentication
Register for an API key at api.snapshot.dev or via the API:
const { apiKey } = await client.auth.register({
email: '[email protected]',
password: 'yourPassword123!',
name: 'Your Name',
});
// Save apiKey — shown once onlyWeb Screenshots
Basic capture
const result = await client.screenshots.webAndWait({
url: 'https://stripe.com',
format: 'png',
dimensions: { width: 1440, height: 900 },
});AI-targeted section
const result = await client.screenshots.webAndWait({
url: 'https://stripe.com/pricing',
description: 'the pricing comparison table',
});
console.log(result.metadata?.aiSelectorUsed); // true
console.log(result.metadata?.aiConfidence); // 0.92CSS selector
const result = await client.screenshots.webAndWait({
url: 'https://stripe.com/pricing',
element: '.pricing-table',
});Full-page PDF
const result = await client.screenshots.webAndWait({
url: 'https://example.com/report',
format: 'pdf',
paperSize: 'A4',
fullPage: true,
});Video recording (Growth+)
const result = await client.screenshots.webAndWait({
url: 'https://example.com',
video: { duration: 10, fps: 30 },
});
// result.screenshots[0] is an .mp4 URLAdvanced options
const result = await client.screenshots.webAndWait({
url: 'https://example.com',
stealth: true, // Business+: bypass bot detection
blockAds: true, // Starter+: block ad networks
acceptCookies: true, // Starter+: dismiss cookie banners
proxyLocation: 'eu-west', // Business+: route via EU proxy
dimensions: { width: 1920, height: 1080 },
format: 'jpeg',
});Custom S3 storage (Business+)
const result = await client.screenshots.webAndWait({
url: 'https://example.com',
storage: {
bucket: 'my-screenshots',
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});Mobile Screenshots
// By app name
const result = await client.screenshots.mobileAndWait({
appName: 'Instagram',
platform: 'both',
});
// By bundle ID (more accurate)
const result = await client.screenshots.mobileAndWait({
bundleId: 'com.instagram.android',
platform: 'android',
});
// With device emulation
const result = await client.screenshots.mobileAndWait({
appName: 'Instagram',
platform: 'ios',
deviceEmulation: 'iPhone 12',
});
// Real Android UI (Growth+)
const result = await client.screenshots.mobileAndWait({
bundleId: 'com.instagram.android',
platform: 'android-real',
});HTML Rendering
const result = await client.screenshots.htmlAndWait({
html: '<h1 style="color: red">Hello World</h1>',
dimensions: { width: 800, height: 600 },
format: 'png',
});Async Job Pattern
All webAndWait / mobileAndWait methods poll automatically. For manual control:
// 1. Enqueue
const { jobId } = await client.screenshots.web({ url: 'https://example.com' });
// 2. Poll manually
const status = await client.jobs.getStatus(jobId);
console.log(status.status); // 'queued' | 'processing' | 'completed' | 'failed'
// 3. Get result
if (status.status === 'completed') {
const result = await client.jobs.getResult(jobId);
}With progress callback:
const result = await client.screenshots.wait(jobId, {
pollIntervalMs: 1000,
timeoutMs: 60_000,
onProgress: (status) => {
console.log(`Progress: ${status.progress}%`);
},
});Billing
// Get JWT for billing operations
const { token } = await client.auth.getToken('[email protected]', 'yourPassword');
// Current plan + usage
const plan = await client.billing.getCurrentPlan(token);
console.log(`${plan.screenshotsRemaining} screenshots remaining`);
// Usage history
const history = await client.billing.getUsageHistory(token);
// Upgrade plan — returns Flutterwave checkout link
const upgrade = await client.billing.upgradePlan(token, 'GROWTH');
// Redirect user to: upgrade.paymentLink
// Verify payment after redirect
const verification = await client.billing.verifyPayment(token, txRef);
console.log(verification.activatedByWebhook); // true when webhook already processed
// Cancel
await client.billing.cancel(token);Team Workspaces
const { token } = await client.auth.getToken(email, password);
// Create workspace
const workspace = await client.workspaces.create(token, 'Acme Dev Team');
// Invite member
await client.workspaces.invite(token, workspace.workspaceId, '[email protected]', 'MEMBER');
// List members
const ws = await client.workspaces.get(token, workspace.workspaceId);
console.log(ws.members);App Monitoring (Business+)
const { token } = await client.auth.getToken(email, password);
// Create monitor
const monitor = await client.monitors.create(token, {
appId: 'com.instagram.android',
platform: 'android',
schedule: '0 */6 * * *', // every 6 hours
webhookUrl: 'https://your-app.com/alerts',
diffThreshold: 0.02, // alert if 2%+ of pixels change
});
// Get run history
const history = await client.monitors.getHistory(token, monitor.monitorId);Error Handling
import {
SnapshotClient,
AuthenticationError,
RateLimitError,
QuotaExceededError,
ValidationError,
JobFailedError,
JobTimeoutError,
} from 'snapshot-api';
try {
const result = await client.capture('https://example.com');
} catch (err) {
if (err instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (err instanceof RateLimitError) {
console.error(`Rate limited. Retry in ${err.retryAfter}s`);
} else if (err instanceof QuotaExceededError) {
console.error('Monthly quota exceeded — upgrade your plan');
} else if (err instanceof ValidationError) {
console.error('Bad request:', err.message, err.details);
} else if (err instanceof JobFailedError) {
console.error(`Job ${err.jobId} failed: ${err.reason}`);
} else if (err instanceof JobTimeoutError) {
console.error(`Job ${err.jobId} timed out after ${err.timeoutMs}ms`);
}
}Configuration
const client = new SnapshotClient({
apiKey: 'snp_...', // Required
baseUrl: 'http://localhost:3000', // Default: https://api.snapshot.dev
timeout: 30_000, // Request timeout (ms). Default: 30000
maxRetries: 3, // Auto-retry on 429 / 5xx. Default: 3
retryDelay: 1000, // Initial retry delay (ms, doubles each retry). Default: 1000
});TypeScript
Fully typed — all request options and response shapes have TypeScript definitions.
import type {
WebScreenshotOptions,
JobResult,
ScreenshotItem,
ProxyLocation,
} from 'snapshot-api';Requirements
- Node.js ≥ 18 (uses native
fetchandAbortController) - No runtime dependencies — zero
node_modulesbloat
License
MIT
