SnapAPI/sdk/node/README.md
Hoid 8a36826e35
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
feat: add POST /v1/screenshots/batch endpoint
- Batch screenshot endpoint: take 1-10 screenshots in a single request
- Concurrent processing with Promise.allSettled (partial success support)
- Upfront quota check for all URLs before processing
- Per-URL SSRF validation via existing takeScreenshot()
- Added incrementUsage() to usage middleware for granular tracking
- 10 new tests covering all edge cases
- Updated OpenAPI docs (JSDoc on route)
- Updated Node.js and Python SDK READMEs with batch method docs
2026-03-06 09:09:27 +01:00

6.7 KiB
Raw Blame History

SnapAPI Node.js SDK

Official Node.js client for SnapAPI — the EU-hosted screenshot API.

Installation

npm install snapapi

Quick Start

import { SnapAPI } from 'snapapi';
import fs from 'fs';

const snap = new SnapAPI('your-api-key');

// Simple screenshot
const png = await snap.capture('https://example.com');
fs.writeFileSync('screenshot.png', png);

Usage

Basic Screenshot

const screenshot = await snap.capture('https://example.com');

With Options

const screenshot = await snap.capture('https://example.com', {
  format: 'jpeg',
  width: 1920,
  height: 1080,
  quality: 90,
});

Full-Page Capture

const screenshot = await snap.capture({
  url: 'https://example.com/blog',
  fullPage: true,
  format: 'png',
  deviceScale: 2, // Retina
});

Mobile Viewport

const screenshot = await snap.capture({
  url: 'https://example.com',
  width: 375,
  height: 812,
  deviceScale: 2,
});

Wait for Dynamic Content

const screenshot = await snap.capture({
  url: 'https://example.com/dashboard',
  waitForSelector: '#chart-loaded',
  waitUntil: 'networkidle2',
});

Dark Mode Capture

// Capture in dark mode (prefers-color-scheme: dark)
const darkScreenshot = await snap.capture({
  url: 'https://example.com',
  darkMode: true,
  format: 'png',
});

Custom User Agent

// Set a custom User-Agent string for the request
const screenshot = await snap.capture({
  url: 'https://example.com',
  userAgent: 'Mozilla/5.0 (compatible; SnapAPI/1.0)',
  format: 'png',
});

Hide Elements Before Capture

// Hide cookie banners, popups, ads
const cleanScreenshot = await snap.capture({
  url: 'https://example.com',
  hideSelectors: [
    '.cookie-banner',
    '.popup-overlay', 
    '#advertisement',
    '.tracking-notice'
  ],
});

// Hide single element
const singleHide = await snap.capture('https://example.com', {
  hideSelectors: '.newsletter-popup',
});

Custom CSS Injection

// Inject custom CSS before capture
const styled = await snap.capture({
  url: 'https://example.com',
  css: 'body { background: #1a1a2e !important; color: #eee !important; font-family: "Comic Sans MS" }',
});

// Combine with other options
const combined = await snap.capture({
  url: 'https://example.com',
  css: '.hero { padding: 80px 0 } h1 { font-size: 48px }',
  darkMode: true,
  hideSelectors: ['.cookie-banner'],
});

JavaScript Injection

// Execute custom JavaScript before capture
const interactiveScreenshot = await snap.capture({
  url: 'https://example.com',
  js: `
    // Dismiss modal popup
    document.querySelector('.modal-overlay')?.remove();
    
    // Scroll to specific content
    window.scrollTo(0, 500);
    
    // Click button to reveal content
    document.querySelector('#show-more-btn')?.click();
    
    // Wait for animation to complete
    await new Promise(resolve => setTimeout(resolve, 1000));
  `,
});

// Combine with other options for complex scenarios
const complexCapture = await snap.capture({
  url: 'https://example.com/app',
  js: 'document.querySelector(".sidebar").style.display = "none";',
  css: 'body { zoom: 0.8 }',
  waitForSelector: '#content-loaded',
  hideSelectors: ['.ad-banner', '.cookie-notice'],
});

Crop Specific Areas (Clip)

// Crop a specific rectangular area from the screenshot
const croppedScreenshot = await snap.capture({
  url: 'https://example.com',
  clip: {
    x: 100,      // X coordinate (pixels from left)
    y: 50,       // Y coordinate (pixels from top)
    width: 800,  // Width of the crop area
    height: 600, // Height of the crop area
  },
});

// Useful for capturing specific UI elements or sections
const headerScreenshot = await snap.capture({
  url: 'https://example.com',
  clip: { x: 0, y: 0, width: 1280, height: 120 }, // Top banner only
  format: 'png',
});

API Reference

new SnapAPI(apiKey, config?)

Parameter Type Description
apiKey string Your SnapAPI API key (required)
config.baseUrl string API base URL (default: https://snapapi.eu)
config.timeout number Request timeout in ms (default: 30000)

snap.capture(url, options?) / snap.capture(options)

Returns a Promise<Buffer> containing the screenshot image.

Option Type Default Description
url string URL to capture (required)
format 'png' | 'jpeg' | 'webp' 'png' Output format
width number 1280 Viewport width (3203840)
height number 800 Viewport height (2002160)
fullPage boolean false Capture full scrollable page
quality number 80 JPEG/WebP quality (1100)
waitForSelector string CSS selector to wait for
deviceScale number 1 Device pixel ratio (13)
delay number 0 Extra delay in ms (05000)
waitUntil string 'domcontentloaded' Load event to wait for
darkMode boolean false Emulate prefers-color-scheme: dark
hideSelectors string | string[] CSS selectors to hide before capture
css string Custom CSS to inject before capture (max 5000 chars)
clip object Crop rectangle: {x, y, width, height} (mutually exclusive with fullPage/selector)

snap.batch(urls, options?)

Take multiple screenshots in a single request. Each URL counts as one screenshot toward usage limits.

const results = await snap.batch(
  ['https://example.com', 'https://example.org'],
  { format: 'jpeg', width: 1920, height: 1080 }
);

for (const result of results) {
  if (result.status === 'success') {
    fs.writeFileSync(`${result.url}.jpg`, Buffer.from(result.image, 'base64'));
  } else {
    console.error(`Failed: ${result.url}${result.error}`);
  }
}
  • Max 10 URLs per batch
  • All options (format, width, height, etc.) are shared across all URLs
  • Returns partial results — some may succeed while others fail
  • Response is always JSON with { results: [...] }

snap.health()

Returns API health status.

Error Handling

import { SnapAPI, SnapAPIError } from 'snapapi';

try {
  const screenshot = await snap.capture('https://example.com');
} catch (err) {
  if (err instanceof SnapAPIError) {
    console.error(`API error ${err.status}: ${err.detail}`);
  }
}

EU-Hosted & GDPR Compliant

SnapAPI runs entirely on EU infrastructure (Germany). Your data never leaves the EU. Learn more.

License

MIT — Cloonar Technologies GmbH