Developer Resources

Code Examples Gallery

10+ real-world examples to get you building with SnapAPI in minutes. Copy, paste, and ship.

๐Ÿ”—

Link Preview Card Generator

Node.js

Generate rich link preview cards for any URL โ€” perfect for chat apps, social feeds, or CMS platforms. Captures a screenshot and extracts metadata in one call using the Extract API.

const axios = require('axios');
const fs = require('fs');

const API_KEY = process.env.SNAPAPI_KEY;
const BASE = 'https://api.snapapi.pics';

async function generateLinkPreview(url) {
  // Step 1: Capture screenshot thumbnail
  const screenshot = await axios.get(`${BASE}/screenshot`, {
    params: {
      url,
      api_key: API_KEY,
      width: 1200,
      height: 630,
      format: 'webp',
      quality: 80,
      block_cookie_banners: true,
      block_ads: true
    },
    responseType: 'arraybuffer'
  });

  // Step 2: Extract metadata
  const meta = await axios.get(`${BASE}/extract`, {
    params: {
      url,
      api_key: API_KEY,
      extract: 'title,description,og:image,favicon'
    }
  });

  return {
    title: meta.data.title,
    description: meta.data.description,
    favicon: meta.data.favicon,
    thumbnail: Buffer.from(screenshot.data).toString('base64'),
    thumbnailType: 'image/webp'
  };
}

// Usage
generateLinkPreview('https://github.com')
  .then(card => {
    console.log(`Title: ${card.title}`);
    console.log(`Description: ${card.description}`);
    fs.writeFileSync('preview.webp',
      Buffer.from(card.thumbnail, 'base64'));
    console.log('Preview saved!');
  });
๐Ÿ“ธ

Bulk Screenshot Pipeline

Python

Capture screenshots of hundreds of URLs concurrently with async Python. Includes retry logic, rate limiting, and progress tracking. Perfect for archiving, monitoring, or bulk reporting.

import asyncio
import aiohttp
import os
from pathlib import Path

API_KEY = os.environ['SNAPAPI_KEY']
BASE = 'https://api.snapapi.pics/screenshot'
MAX_CONCURRENT = 5  # respect rate limits

async def capture(session, sem, url, output_dir):
    async with sem:
        params = {
            'url': url,
            'api_key': API_KEY,
            'format': 'webp',
            'full_page': 'true',
            'block_cookie_banners': 'true',
            'block_ads': 'true'
        }
        for attempt in range(3):
            try:
                async with session.get(BASE, params=params) as resp:
                    if resp.status == 200:
                        fname = url.replace('https://', '').replace('/', '_')
                        path = output_dir / f"{fname}.webp"
                        path.write_bytes(await resp.read())
                        print(f"โœ… {url}")
                        return True
                    elif resp.status == 429:
                        await asyncio.sleep(2 ** attempt)
                        continue
            except Exception as e:
                print(f"โš ๏ธ  {url}: {e}")
                await asyncio.sleep(1)
        print(f"โŒ {url}: failed after 3 attempts")
        return False

async def bulk_capture(urls, output_dir='./screenshots'):
    output = Path(output_dir)
    output.mkdir(exist_ok=True)
    sem = asyncio.Semaphore(MAX_CONCURRENT)

    async with aiohttp.ClientSession() as session:
        tasks = [capture(session, sem, url, output) for url in urls]
        results = await asyncio.gather(*tasks)
        success = sum(1 for r in results if r)
        print(f"\nDone: {success}/{len(urls)} captured")

# Usage
urls = [
    'https://github.com',
    'https://stackoverflow.com',
    'https://dev.to',
    'https://news.ycombinator.com',
    'https://reddit.com',
]
asyncio.run(bulk_capture(urls))
๐Ÿ”

Visual Diff Tool

Node.js

Detect visual changes on any webpage by comparing screenshots over time. Uses pixelmatch for pixel-level diffing. Great for regression testing, competitor monitoring, or content change detection.

const axios = require('axios');
const { PNG } = require('pngjs');
const pixelmatch = require('pixelmatch');
const fs = require('fs');

const API_KEY = process.env.SNAPAPI_KEY;

async function captureScreenshot(url) {
  const res = await axios.get('https://api.snapapi.pics/screenshot', {
    params: {
      url,
      api_key: API_KEY,
      width: 1280,
      height: 800,
      format: 'png',
      block_cookie_banners: true
    },
    responseType: 'arraybuffer'
  });
  return PNG.sync.read(Buffer.from(res.data));
}

async function visualDiff(url, baselinePath) {
  // Capture current state
  const current = await captureScreenshot(url);

  // Load baseline (or create if first run)
  if (!fs.existsSync(baselinePath)) {
    PNG.sync.write(current).copy(
      fs.createWriteStream(baselinePath)
    );
    console.log('Baseline created. Run again to compare.');
    return null;
  }

  const baseline = PNG.sync.read(fs.readFileSync(baselinePath));
  const { width, height } = baseline;
  const diff = new PNG({ width, height });

  const numDiffPixels = pixelmatch(
    baseline.data, current.data, diff.data,
    width, height, { threshold: 0.1 }
  );

  const diffPercent = (numDiffPixels / (width * height) * 100).toFixed(2);
  fs.writeFileSync('diff.png', PNG.sync.write(diff));

  console.log(`Diff: ${diffPercent}% changed (${numDiffPixels} pixels)`);
  return { diffPercent, numDiffPixels };
}

// Usage
visualDiff('https://news.ycombinator.com', 'baseline.png');
๐Ÿ“„

PDF Invoice Generator

PHP

Convert any HTML invoice page to a pixel-perfect PDF. Supports custom paper sizes, margins, headers/footers, and print media queries. Drop-in replacement for wkhtmltopdf.

<?php
$apiKey = getenv('SNAPAPI_KEY');

function generateInvoicePdf($invoiceUrl, $outputPath) {
    global $apiKey;

    $params = http_build_query([
        'url'        => $invoiceUrl,
        'api_key'    => $apiKey,
        'format'     => 'pdf',
        'pdf_format' => 'A4',
        'pdf_margin' => '20mm',
        'pdf_print_background' => 'true',
        'wait_until'  => 'networkidle',
        'block_ads'   => 'true'
    ]);

    $url = "https://api.snapapi.pics/screenshot?{$params}";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    $pdf = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode === 200) {
        file_put_contents($outputPath, $pdf);
        echo "Invoice saved to {$outputPath}\n";
        return true;
    }

    echo "Error: HTTP {$httpCode}\n";
    return false;
}

// Usage โ€” pass your invoice URL
generateInvoicePdf(
    'https://your-app.com/invoices/INV-2026-001',
    '/tmp/invoice-001.pdf'
);

// Batch generate
$invoices = ['INV-2026-001', 'INV-2026-002', 'INV-2026-003'];
foreach ($invoices as $inv) {
    generateInvoicePdf(
        "https://your-app.com/invoices/{$inv}",
        "/tmp/{$inv}.pdf"
    );
}
?>
๐Ÿ•ท๏ธ

SEO Meta Scraper

cURL + jq

Extract SEO metadata from any URL with a single shell command. Pull title, description, OG tags, canonical URL, and structured data. Pipe to jq for beautiful JSON output.

#!/bin/bash
# SEO Meta Scraper using SnapAPI Extract API
# Requires: curl, jq

API_KEY="${SNAPAPI_KEY}"
BASE="https://api.snapapi.pics/extract"

seo_audit() {
  local url="$1"
  echo "๐Ÿ” Auditing: $url"
  echo "---"

  curl -s "${BASE}?url=${url}&api_key=${API_KEY}&extract=title,description,og:title,og:description,og:image,canonical,h1,favicon" | jq '{
    url: .url,
    title: .title,
    title_length: (.title | length),
    description: .description,
    desc_length: (.description | length),
    og_title: .["og:title"],
    og_description: .["og:description"],
    og_image: .["og:image"],
    canonical: .canonical,
    h1: .h1,
    favicon: .favicon,
    issues: [
      (if (.title | length) > 60 then "Title too long (\(.title | length) chars)" else empty end),
      (if (.title | length) < 30 then "Title too short (\(.title | length) chars)" else empty end),
      (if (.description | length) > 160 then "Description too long" else empty end),
      (if (.description | length) == 0 then "Missing description" else empty end),
      (if .["og:image"] == null then "Missing OG image" else empty end),
      (if .["og:title"] == null then "Missing OG title" else empty end)
    ]
  }'
}

# Single URL
seo_audit "https://github.com"

# Batch audit from file
# while IFS= read -r url; do
#   seo_audit "$url"
#   sleep 0.5
# done < urls.txt
๐ŸŽจ

Social Media Card Generator

Python

Generate beautiful OG images for blog posts, product pages, or tweets. Renders custom HTML templates as images โ€” no Puppeteer infrastructure needed. Supports custom fonts and CSS.

import requests
import os
from urllib.parse import quote

API_KEY = os.environ['SNAPAPI_KEY']

def generate_social_card(title, subtitle, author, bg_color='#6366f1'):
    """Generate a social media card from an HTML template."""
    html = f"""
    <html>
    <body style="margin:0; width:1200px; height:630px;
      background: linear-gradient(135deg, {bg_color}, #ec4899);
      display:flex; align-items:center; justify-content:center;
      font-family: system-ui, sans-serif;">
      <div style="text-align:center; color:white; padding:60px;">
        <h1 style="font-size:52px; margin:0 0 16px; line-height:1.2;">
          {title}
        </h1>
        <p style="font-size:24px; opacity:0.9; margin:0 0 32px;">
          {subtitle}
        </p>
        <p style="font-size:18px; opacity:0.7;">
          By {author} ยท snapapi.pics
        </p>
      </div>
    </body>
    </html>
    """

    resp = requests.get('https://api.snapapi.pics/screenshot', params={
        'api_key': API_KEY,
        'html': html,
        'width': 1200,
        'height': 630,
        'format': 'png'
    })

    if resp.status_code == 200:
        filename = f"card-{title[:20].replace(' ', '-').lower()}.png"
        with open(filename, 'wb') as f:
            f.write(resp.content)
        print(f"โœ… Card saved: {filename}")
        return filename
    else:
        print(f"โŒ Error: {resp.status_code}")
        return None

# Generate cards for blog posts
posts = [
    ("How We Built SnapAPI", "From idea to 10K users", "Alex"),
    ("Screenshot API Guide", "Everything you need to know", "Team"),
    ("Web Scraping in 2026", "The ethical approach", "Alex"),
]

for title, subtitle, author in posts:
    generate_social_card(title, subtitle, author)
๐Ÿ’ฐ

Price Monitoring Bot

Node.js

Track product prices on any e-commerce site. Captures screenshots for visual proof and extracts price data using the Extract API. Set up alerts when prices drop below your threshold.

const axios = require('axios');
const fs = require('fs');

const API_KEY = process.env.SNAPAPI_KEY;
const BASE = 'https://api.snapapi.pics';

const PRODUCTS = [
  {
    name: 'MacBook Pro M4',
    url: 'https://store.example.com/macbook-pro',
    selector: '.product-price',
    threshold: 1999
  },
  {
    name: 'Sony WH-1000XM5',
    url: 'https://store.example.com/sony-xm5',
    selector: '.price-value',
    threshold: 298
  }
];

async function checkPrice(product) {
  // Extract price text
  const extract = await axios.get(`${BASE}/extract`, {
    params: {
      url: product.url,
      api_key: API_KEY,
      extract: 'text',
      selector: product.selector
    }
  });

  const priceText = extract.data.text || '';
  const price = parseFloat(priceText.replace(/[^0-9.]/g, ''));

  // Capture visual proof
  const screenshot = await axios.get(`${BASE}/screenshot`, {
    params: {
      url: product.url,
      api_key: API_KEY,
      format: 'webp',
      quality: 70,
      block_cookie_banners: true
    },
    responseType: 'arraybuffer'
  });

  const timestamp = new Date().toISOString().slice(0, 10);
  fs.writeFileSync(
    `price-${product.name.replace(/\s/g, '-')}-${timestamp}.webp`,
    screenshot.data
  );

  console.log(`${product.name}: $${price}`);

  if (price <= product.threshold) {
    console.log(`๐Ÿšจ PRICE DROP! ${product.name} is now $${price}`);
    // Send alert via email, Slack, etc.
  }

  return { product: product.name, price, timestamp };
}

// Check all products
async function monitorPrices() {
  const results = [];
  for (const product of PRODUCTS) {
    results.push(await checkPrice(product));
    await new Promise(r => setTimeout(r, 1000)); // rate limit
  }
  // Append to price history
  const historyPath = 'price-history.json';
  const history = fs.existsSync(historyPath)
    ? JSON.parse(fs.readFileSync(historyPath)) : [];
  history.push(...results);
  fs.writeFileSync(historyPath, JSON.stringify(history, null, 2));
}

monitorPrices();
๐Ÿงช

Automated Testing Integration

Jest / Playwright

Add visual regression testing to your CI/CD pipeline. Compare screenshots against baselines in Jest tests. No need to run your own headless browser infrastructure.

// visual-regression.test.js
const axios = require('axios');
const fs = require('fs');
const { PNG } = require('pngjs');
const pixelmatch = require('pixelmatch');

const API_KEY = process.env.SNAPAPI_KEY;
const BASELINE_DIR = './test/baselines';
const DIFF_THRESHOLD = 0.5; // 0.5% diff allowed

async function snapPage(url, name) {
  const res = await axios.get('https://api.snapapi.pics/screenshot', {
    params: {
      url,
      api_key: API_KEY,
      width: 1280,
      height: 800,
      format: 'png',
      block_cookie_banners: true,
      wait_until: 'networkidle'
    },
    responseType: 'arraybuffer'
  });
  return Buffer.from(res.data);
}

describe('Visual Regression Tests', () => {
  const pages = [
    { name: 'homepage', url: 'https://your-app.com' },
    { name: 'pricing', url: 'https://your-app.com/pricing' },
    { name: 'docs', url: 'https://your-app.com/docs' },
  ];

  pages.forEach(({ name, url }) => {
    test(`${name} matches baseline`, async () => {
      const current = await snapPage(url, name);
      const baselinePath = `${BASELINE_DIR}/${name}.png`;

      if (!fs.existsSync(baselinePath)) {
        fs.mkdirSync(BASELINE_DIR, { recursive: true });
        fs.writeFileSync(baselinePath, current);
        console.log(`Created baseline for ${name}`);
        return; // first run, skip comparison
      }

      const baselineImg = PNG.sync.read(fs.readFileSync(baselinePath));
      const currentImg = PNG.sync.read(current);
      const { width, height } = baselineImg;
      const diff = new PNG({ width, height });

      const diffPixels = pixelmatch(
        baselineImg.data, currentImg.data,
        diff.data, width, height, { threshold: 0.1 }
      );

      const diffPercent = (diffPixels / (width * height)) * 100;
      expect(diffPercent).toBeLessThan(DIFF_THRESHOLD);
    }, 30000);
  });
});
๐Ÿ“ง

Content Digest Emailer

Python

Build a visual content digest email. Capture thumbnails of articles, extract titles and descriptions, then compile into a beautiful HTML email. Perfect for newsletters and content curation.

import requests
import base64
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

API_KEY = os.environ['SNAPAPI_KEY']
BASE = 'https://api.snapapi.pics'

def build_digest(urls):
    """Build HTML digest with thumbnails and metadata."""
    items = []

    for url in urls:
        # Get metadata
        meta = requests.get(f'{BASE}/extract', params={
            'url': url,
            'api_key': API_KEY,
            'extract': 'title,description,og:image'
        }).json()

        # Get thumbnail
        img = requests.get(f'{BASE}/screenshot', params={
            'url': url,
            'api_key': API_KEY,
            'width': 600,
            'height': 400,
            'format': 'jpeg',
            'quality': 70,
            'block_cookie_banners': 'true'
        })
        thumb_b64 = base64.b64encode(img.content).decode()

        items.append({
            'url': url,
            'title': meta.get('title', url),
            'description': meta.get('description', '')[:150],
            'thumbnail': thumb_b64
        })

    # Build HTML email
    cards = ''
    for item in items:
        cards += f"""
        <div style="margin-bottom:24px; border:1px solid #eee;
                    border-radius:8px; overflow:hidden;">
          <img src="data:image/jpeg;base64,{item['thumbnail']}"
               style="width:100%; height:200px; object-fit:cover;">
          <div style="padding:16px;">
            <h3 style="margin:0 0 8px;">
              <a href="{item['url']}">{item['title']}</a>
            </h3>
            <p style="color:#666; margin:0;">{item['description']}</p>
          </div>
        </div>"""

    return f"""
    <html><body style="font-family:system-ui; max-width:600px;
      margin:0 auto; padding:20px;">
      <h1>๐Ÿ“ฐ Your Weekly Digest</h1>
      <p style="color:#666;">Here's what's worth reading this week:</p>
      {cards}
      <p style="color:#999; font-size:12px; margin-top:32px;">
        Powered by SnapAPI
      </p>
    </body></html>"""

# Usage
urls = [
    'https://news.ycombinator.com',
    'https://dev.to',
    'https://github.blog',
]
html = build_digest(urls)

# Save or send
with open('digest.html', 'w') as f:
    f.write(html)
print("Digest generated! Open digest.html")
๐Ÿ’ฌ

Slack Bot with Previews

Node.js

Build a Slack bot that auto-generates rich website previews when someone shares a URL. Captures a screenshot and uploads it as a reply thread. Uses Slack's Bolt framework.

const { App } = require('@slack/bolt');
const axios = require('axios');

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  socketMode: true,
  appToken: process.env.SLACK_APP_TOKEN,
});

const API_KEY = process.env.SNAPAPI_KEY;

// Listen for messages with URLs
app.message(/https?:\/\/[^\s]+/g, async ({ message, say, client }) => {
  const urls = message.text.match(/https?:\/\/[^\s]+/g);
  if (!urls) return;

  for (const url of urls.slice(0, 3)) { // max 3 per message
    try {
      // Capture screenshot
      const screenshot = await axios.get(
        'https://api.snapapi.pics/screenshot',
        {
          params: {
            url,
            api_key: API_KEY,
            width: 1200,
            height: 630,
            format: 'png',
            block_cookie_banners: true,
            block_ads: true
          },
          responseType: 'arraybuffer'
        }
      );

      // Extract metadata
      const meta = await axios.get(
        'https://api.snapapi.pics/extract',
        {
          params: {
            url,
            api_key: API_KEY,
            extract: 'title,description'
          }
        }
      );

      // Upload to Slack
      await client.files.uploadV2({
        channel_id: message.channel,
        thread_ts: message.ts,
        file: Buffer.from(screenshot.data),
        filename: 'preview.png',
        title: meta.data.title || url,
        initial_comment: meta.data.description
          ? `*${meta.data.title}*\n${meta.data.description}`
          : `Preview of ${url}`
      });
    } catch (err) {
      console.error(`Failed to preview ${url}:`, err.message);
    }
  }
});

// Slash command: /snap 
app.command('/snap', async ({ command, ack, respond }) => {
  await ack();
  const url = command.text.trim();
  if (!url) {
    await respond('Usage: `/snap https://example.com`');
    return;
  }

  await respond(`๐Ÿ“ธ Capturing ${url}...`);

  const screenshot = await axios.get(
    'https://api.snapapi.pics/screenshot',
    {
      params: {
        url,
        api_key: API_KEY,
        format: 'png',
        full_page: true,
        block_cookie_banners: true
      },
      responseType: 'arraybuffer'
    }
  );

  // Return as ephemeral image (use files.upload for persistent)
  await respond({
    text: `Screenshot of ${url}`,
    blocks: [{
      type: 'image',
      image_url: `data:image/png;base64,${Buffer.from(screenshot.data).toString('base64')}`,
      alt_text: url
    }]
  });
});

(async () => {
  await app.start();
  console.log('โšก๏ธ Snap Bot is running!');
})();

Ready to Build?

Get your free API key and start capturing in minutes.

Get Free API Key โ†’