SnapForge API Reference

Generate pixel-perfect screenshots, PDFs, and Open Graph images from any URL or HTML with a simple REST API.

v1 — Current

Authentication

All API requests require an API key. You can pass it in one of two ways:

Option 1: HTTP Header (recommended)

X-API-Key: your_api_key_here

Option 2: Query Parameter

GET /v1/og-image?api_key=your_api_key_here&title=Hello
💡
Demo Key Available: Use sf_demo_public for testing with the free tier (50 requests/day). No signup required.
⚠️
Keep your API key secret. Do not expose it in client-side code or public repositories. Use environment variables or server-side proxies.

Base URL

All API endpoints are accessed under the following base URL:

Base URL
https://api.snapforge.dev/v1

Quick Start

Get your first screenshot in under a minute. Here is a minimal example using the demo API key:

# Take a screenshot and save to file
curl -X POST https://api.snapforge.dev/v1/screenshot \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sf_demo_public" \
  -d '{
    "url": "https://example.com",
    "width": 1280,
    "height": 800
  }' \
  --output screenshot.png
const response = await fetch('https://api.snapforge.dev/v1/screenshot', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'sf_demo_public'
  },
  body: JSON.stringify({
    url: 'https://example.com',
    width: 1280,
    height: 800
  })
});

const blob = await response.blob();
// Save or display the screenshot blob
import requests

response = requests.post(
    'https://api.snapforge.dev/v1/screenshot',
    headers={'X-API-Key': 'sf_demo_public'},
    json={
        'url': 'https://example.com',
        'width': 1280,
        'height': 800
    }
)

with open('screenshot.png', 'wb') as f:
    f.write(response.content)
That's it! The API returns the binary image directly in the response body. No JSON wrapping, no base64 — just the raw file.

Screenshot

Capture any webpage or HTML as a high-quality screenshot image. Supports PNG, JPEG, and WebP formats with fine-grained control over viewport, scaling, and rendering.

POST /v1/screenshot
Capture a webpage or HTML content as an image.

Request Body (JSON)

ParameterTypeRequiredDefaultDescription
url string conditional URL of the page to capture. Required if html is not provided.
html string conditional Raw HTML content to render and capture. Required if url is not provided.
width integer optional 1280 Viewport width in pixels. Range: 320–3840.
height integer optional 800 Viewport height in pixels. Range: 200–2160.
fullPage boolean optional false Capture the full scrollable page, not just the viewport.
format string optional png Image format. One of: png, jpeg, webp.
quality integer optional 80 Image quality (1–100). Only applies to jpeg and webp.
deviceScaleFactor number optional 1 Device pixel ratio (1–3). Use 2 for retina-quality screenshots.
delay integer optional 0 Milliseconds to wait after page load before capture. Max: 10000.
selector string optional CSS selector of a specific element to capture instead of the full page.
darkMode boolean optional false Enable prefers-color-scheme: dark media emulation.
blockAds boolean optional false Block common ad and tracking domains during capture.
userAgent string optional Custom User-Agent header for the browser.
headers object optional {} Extra HTTP headers to send with the page request.
cookies array optional [] Cookies to set before navigation. Each item: { name, value, domain, path }.

Response

200 Binary image data with appropriate Content-Type header (image/png, image/jpeg, or image/webp).
400 JSON error if input is invalid (e.g., missing url/html, selector not found).

Code Examples

# Full-page retina screenshot in WebP
curl -X POST https://api.snapforge.dev/v1/screenshot \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "url": "https://github.com",
    "width": 1440,
    "height": 900,
    "fullPage": true,
    "format": "webp",
    "quality": 90,
    "deviceScaleFactor": 2,
    "darkMode": true,
    "blockAds": true
  }' \
  --output github-dark.webp
const response = await fetch('https://api.snapforge.dev/v1/screenshot', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    url: 'https://github.com',
    width: 1440,
    height: 900,
    fullPage: true,
    format: 'webp',
    quality: 90,
    deviceScaleFactor: 2,
    darkMode: true,
    blockAds: true
  })
});

if (!response.ok) {
  const err = await response.json();
  throw new Error(err.error.message);
}

const buffer = await response.arrayBuffer();
// In Node.js:
const fs = require('fs');
fs.writeFileSync('screenshot.webp', Buffer.from(buffer));
import requests

response = requests.post(
    'https://api.snapforge.dev/v1/screenshot',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={
        'url': 'https://github.com',
        'width': 1440,
        'height': 900,
        'fullPage': True,
        'format': 'webp',
        'quality': 90,
        'deviceScaleFactor': 2,
        'darkMode': True,
        'blockAds': True
    }
)

response.raise_for_status()

with open('screenshot.webp', 'wb') as f:
    f.write(response.content)

print(f'Saved {len(response.content)} bytes')

Capture HTML Directly

# Render custom HTML as screenshot
curl -X POST https://api.snapforge.dev/v1/screenshot \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "html": "<html><body style=\"background:#1a1a2e;color:#fff;display:flex;align-items:center;justify-content:center;height:100vh;font-family:sans-serif\"><h1>Hello, SnapForge!</h1></body></html>",
    "width": 800,
    "height": 600
  }' \
  --output hello.png
const html = `
<html>
<body style="background:#1a1a2e;color:#fff;display:flex;
  align-items:center;justify-content:center;height:100vh;
  font-family:sans-serif">
  <h1>Hello, SnapForge!</h1>
</body>
</html>`;

const response = await fetch('https://api.snapforge.dev/v1/screenshot', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({ html, width: 800, height: 600 })
});
import requests

html = """
<html>
<body style="background:#1a1a2e;color:#fff;display:flex;
  align-items:center;justify-content:center;height:100vh;
  font-family:sans-serif">
  <h1>Hello, SnapForge!</h1>
</body>
</html>
"""

response = requests.post(
    'https://api.snapforge.dev/v1/screenshot',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={'html': html, 'width': 800, 'height': 600}
)

PDF Generation

Convert any webpage or HTML content into a high-quality PDF document. Supports standard page sizes, custom margins, headers, footers, and background printing.

POST /v1/pdf
Generate a PDF from a URL or HTML content.

Request Body (JSON)

ParameterTypeRequiredDefaultDescription
url string conditional URL of the page to convert. Required if html is not provided.
html string conditional Raw HTML content to convert. Required if url is not provided.
format string optional A4 Page size. One of: A3, A4, A5, Letter, Legal.
landscape boolean optional false Render the PDF in landscape orientation.
printBackground boolean optional true Include background colors and images in the PDF.
margin object optional Page margins in CSS units. Object with top, right, bottom, left properties (e.g., "20mm").
scale number optional 1 Scale of the webpage rendering. Range: 0.1–2.
displayHeaderFooter boolean optional false Enable custom header and footer rendering.
headerTemplate string optional HTML template for the page header. Supports Chromium template classes: date, title, url, pageNumber, totalPages.
footerTemplate string optional HTML template for the page footer. Same template classes as header.
width integer optional 1280 Viewport width for rendering the page before PDF conversion.
height integer optional 800 Viewport height for rendering the page before PDF conversion.

Response

200 Binary PDF data with Content-Type: application/pdf and Content-Disposition: attachment; filename="document.pdf".
400 JSON error if url and html are both missing.

Code Examples

# Convert a webpage to PDF with custom margins
curl -X POST https://api.snapforge.dev/v1/pdf \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "url": "https://example.com",
    "format": "A4",
    "landscape": false,
    "printBackground": true,
    "margin": {
      "top": "20mm",
      "right": "15mm",
      "bottom": "20mm",
      "left": "15mm"
    },
    "displayHeaderFooter": true,
    "footerTemplate": "<div style=\"font-size:10px;text-align:center;width:100%\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
  }' \
  --output document.pdf
const response = await fetch('https://api.snapforge.dev/v1/pdf', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    url: 'https://example.com',
    format: 'A4',
    printBackground: true,
    margin: {
      top: '20mm',
      right: '15mm',
      bottom: '20mm',
      left: '15mm'
    }
  })
});

const buffer = await response.arrayBuffer();
// Save as PDF file (Node.js)
const fs = require('fs');
fs.writeFileSync('document.pdf', Buffer.from(buffer));
import requests

response = requests.post(
    'https://api.snapforge.dev/v1/pdf',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={
        'url': 'https://example.com',
        'format': 'A4',
        'printBackground': True,
        'margin': {
            'top': '20mm',
            'right': '15mm',
            'bottom': '20mm',
            'left': '15mm'
        }
    }
)

response.raise_for_status()

with open('document.pdf', 'wb') as f:
    f.write(response.content)

print(f'PDF saved: {len(response.content) // 1024} KB')

OG Image Generator

Create beautiful Open Graph images for social media previews with built-in templates or fully custom HTML. Images are rendered at 2x device pixel ratio for retina quality.

POST /v1/og-image
Generate an Open Graph image using a template or custom HTML.

Request Body (JSON)

ParameterTypeRequiredDefaultDescription
title string conditional Main text for the OG image. Required if customHtml is not provided.
customHtml string conditional Full custom HTML template. Required if title is not provided.
subtitle string optional Secondary text displayed below the title.
template string optional basic Template name. One of: basic, gradient, dark, minimal, blog.
logo string optional URL to a logo image to include on the OG image.
bgColor string optional #667eea Background color (CSS color value).
bgGradient string optional CSS gradient for background (e.g., linear-gradient(135deg, #667eea 0%, #764ba2 100%)).
textColor string optional #ffffff Text color (CSS color value).
fontSize integer optional 48 Font size for the title text in pixels.
width integer optional 1200 Image width in pixels. Range: 200–2400.
height integer optional 630 Image height in pixels. Range: 200–1260.
format string optional png Image format. One of: png, jpeg, webp.
quality integer optional 90 Image quality (1–100). Only applies to jpeg and webp.

Response

200 Binary image data with appropriate Content-Type header.
400 JSON error if title and customHtml are both missing.

Code Examples

# Generate an OG image with the gradient template
curl -X POST https://api.snapforge.dev/v1/og-image \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "title": "My Amazing Blog Post",
    "subtitle": "A deep dive into modern web development",
    "template": "gradient",
    "bgGradient": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
    "fontSize": 52,
    "width": 1200,
    "height": 630
  }' \
  --output og-image.png
const response = await fetch('https://api.snapforge.dev/v1/og-image', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    title: 'My Amazing Blog Post',
    subtitle: 'A deep dive into modern web development',
    template: 'gradient',
    bgGradient: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
    fontSize: 52
  })
});

const blob = await response.blob();
// Use as <meta property="og:image"> source
import requests

response = requests.post(
    'https://api.snapforge.dev/v1/og-image',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={
        'title': 'My Amazing Blog Post',
        'subtitle': 'A deep dive into modern web development',
        'template': 'gradient',
        'bgGradient': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
        'fontSize': 52
    }
)

with open('og-image.png', 'wb') as f:
    f.write(response.content)
GET /v1/og-image
Generate an OG image via URL query parameters. Ideal for use directly in <meta> tags.

All the same parameters as the POST endpoint, but passed as URL query parameters. This is especially useful for embedding directly in HTML og:image meta tags.

Example Usage in HTML

<!-- Use directly in your meta tags -->
<meta property="og:image"
  content="https://api.snapforge.dev/v1/og-image?api_key=YOUR_API_KEY&title=My%20Blog%20Post&template=gradient&subtitle=Read%20More" />
💡
The GET endpoint accepts the same parameters as the POST endpoint, but as query string parameters. Remember to URL-encode special characters in values.

Rate Limits

Rate limits are enforced per API key based on your subscription tier. When you exceed the limit, the API returns a 429 status code.

TierRequest LimitRatePrice
Free 50 requests / day 5 req/min $0/mo
Basic 5,000 requests / month 30 req/min $9/mo
Pro 25,000 requests / month 100 req/min $29/mo
⚠️
Daily limits reset at midnight UTC. If you need higher limits, contact us at api@snapforge.dev.

Error Codes

The API uses standard HTTP status codes. Error responses include a JSON body with an error object containing a human-readable message and a machine-readable code.

Error Response Format

{
  "error": {
    "message": "Either \"url\" or \"html\" is required.",
    "code": "INVALID_INPUT"
  }
}

Error Reference

HTTP StatusError CodeDescription
400 INVALID_INPUT Missing required parameters. Ensure either url or html is provided.
400 SELECTOR_NOT_FOUND The CSS selector provided did not match any element on the page. (Screenshot endpoint only.)
401 AUTH_REQUIRED No API key was provided. Pass it via X-API-Key header or api_key query parameter.
401 INVALID_KEY The provided API key is not valid. Check for typos or request a new key.
429 DAILY_LIMIT_REACHED You have exceeded your daily/monthly request quota. Upgrade your plan or wait for the limit to reset.
500 INTERNAL_ERROR An unexpected server error occurred. If the issue persists, contact support.

Response Headers

Successful responses include these useful headers:

HeaderEndpointDescription
Content-Type All MIME type of the returned content (e.g., image/png, application/pdf).
Content-Length All Size of the response body in bytes.
X-Image-Width Screenshot The actual viewport width used for the capture.
X-Image-Height Screenshot The actual viewport height used for the capture.
Content-Disposition PDF Set to attachment; filename="document.pdf" for PDF downloads.

Pricing

Start for free with the demo key. Upgrade when you need more.

Free

$0
forever
  • 50 requests per day
  • All 3 endpoints
  • 5 req/min rate limit
  • Community support
  • Demo key: sf_demo_public

Basic

$9
per month
  • 5,000 requests per month
  • All 3 endpoints
  • 30 req/min rate limit
  • Priority email support
  • Dedicated API key

Pro

$29
per month
  • 25,000 requests per month
  • All 3 endpoints
  • 100 req/min rate limit
  • Dedicated support
  • Custom integrations
💡
To get an API key or upgrade your plan, email api@snapforge.dev or reach out via our Telegram Bot.

Telegram Bot

SnapForge is also available as a Telegram bot for quick, interactive use. Send a URL and instantly get a screenshot, PDF, or OG image right in the chat.

🤖

@SnapForgeBot

Open in Telegram and start capturing instantly.

Open @SnapForgeBot