API Reference

Everything you need to integrate SnapAPI into your application

Authentication

Include your API key in every request using either:

Header: x-api-key: YOUR_KEY

Query param: ?api_key=YOUR_KEY

Don't have a key? Sign up free — 100 API calls/month, no credit card.

Analyze

GET /v1/analyze

Structured understanding of any webpage — page type, primary CTA (text + href), navigation, buttons, forms, headings, images, links, word count, load time, OG metadata, and detected technologies. DOM-based, no AI. Optional screenshot=true for a base64 PNG in the same browser session.

ParameterDefaultDescription
urlrequiredThe webpage URL to analyze
screenshotfalseInclude a base64 PNG snapshot alongside the analysis
delay0Wait ms after load (max 10000)
wait_for_selectorCSS selector to wait for before analyzing. Essential for React/SPA apps. Example: #app, .content-loaded
wait_for_network_idlefalseWait for all network requests to complete after load.
interactJSON array of browser actions before analysis. Supports click, type, hover, wait, scroll_to. Example: [{"action":"click","selector":"#tab-pricing"},{"action":"wait","ms":500}]. Max 20 steps. Returns 400 on step failure.
cURL
JavaScript
Python
curl "https://snapapi.tech/v1/analyze?url=stripe.com" \
  -H "x-api-key: YOUR_KEY"

# With interact — click pricing tab before capturing
curl "https://snapapi.tech/v1/analyze?url=stripe.com&interact=%5B%7B%22action%22%3A%22click%22%2C%22selector%22%3A%22%23pricing%22%7D%5D" \
  -H "x-api-key: YOUR_KEY"
const res = await fetch(
  "https://snapapi.tech/v1/analyze?url=stripe.com",
  { headers: { "x-api-key": "YOUR_KEY" } }
);
const data = await res.json();

console.log(data.page_type);          // "landing"
console.log(data.primary_cta.text);   // "Start now"
console.log(data.technologies);        // ["react", "stripe", "google-analytics"]
console.log(data.word_count);          // 1432
console.log(data.load_time_ms);        // 980

// With interact — click a tab, then wait 500ms
const res2 = await fetch(
  "https://snapapi.tech/v1/analyze?" + new URLSearchParams({
    url: "stripe.com",
    interact: JSON.stringify([
      { action: "click", selector: "#pricing" },
      { action: "wait", ms: 500 }
    ])
  }),
  { headers: { "x-api-key": "YOUR_KEY" } }
);
import requests, json

r = requests.get(
    "https://snapapi.tech/v1/analyze",
    params={"url": "stripe.com"},
    headers={"x-api-key": "YOUR_KEY"}
)
data = r.json()

print(data["page_type"])           # landing
print(data["primary_cta"]["text"]) # Start now
print(data["technologies"])         # ["react", "stripe", "google-analytics"]
print(data["word_count"])           # 1432
print(data["load_time_ms"])         # 980

Example response

{
  "url": "https://stripe.com",
  "load_time_ms": 980,
  "title": "Stripe | Financial Infrastructure for the Internet",
  "description": "Stripe powers online and in-person payment processing...",
  "page_type": "landing",
  "primary_cta": { "text": "Start now", "href": "https://stripe.com/register" },
  "nav_items": [
    { "text": "Products", "href": "https://stripe.com/products" },
    { "text": "Pricing", "href": "https://stripe.com/pricing" }
  ],
  "buttons": [ { "text": "Start now", "href": "https://stripe.com/register" } ],
  "forms": [],
  "headings": [ { "level": 1, "text": "Financial infrastructure for the internet" } ],
  "images": [ { "src": "...", "alt": "...", "width": 800, "height": 600 } ],
  "links": [ { "text": "Pricing", "href": "https://stripe.com/pricing", "external": false } ],
  "word_count": 1432,
  "technologies": ["react", "stripe", "google-analytics"],
  "text_summary": "Stripe powers online and in-person payment processing and financial solutions for businesses..."
}

Snapshot

GET /v1/screenshot

Capture a visual snapshot of any webpage as a high-quality image. Returns the image binary directly (or JSON with metadata if meta=true).

ParameterDefaultDescription
urlrequiredWebsite URL to capture
width1280Viewport width in pixels
height800Viewport height in pixels
formatpngOutput format: png, jpeg, webp
quality80Image quality (1-100, jpeg/webp only)
full_pagefalseCapture full scrollable page
delay0Wait ms after load (max 10000, for SPAs)
dark_modefalseEmulate dark color scheme
block_adsfalseBlock common ad networks and trackers
selectorCSS selector to capture a specific element
metafalseReturn JSON with title, description, favicon + base64 image
deviceDevice preset: iphone14, iphone14pro, iphone15, pixel7, pixel8, galaxys23, ipad, ipadpro, desktop
cachetrueUse 30-min response cache
wait_for_selectorCSS selector to wait for before capture. Essential for SPAs, React apps. Example: #app, .dashboard
wait_for_network_idlefalseWait for all network requests to complete after page load.
cURL
JavaScript
Node.js
Python
curl "https://snapapi.tech/v1/screenshot?url=github.com&format=webp" \
  -H "x-api-key: YOUR_KEY" -o screenshot.webp
const res = await fetch(
  "https://snapapi.tech/v1/screenshot?url=github.com&width=1440&dark_mode=true",
  { headers: { "x-api-key": "YOUR_KEY" } }
);
const blob = await res.blob();
const https = require("https");
const fs = require("fs");

const url = "https://snapapi.tech/v1/screenshot?url=github.com&format=png";
const opts = { headers: { "x-api-key": "YOUR_KEY" } };

https.get(url, opts, (res) => {
  res.pipe(fs.createWriteStream("screenshot.png"));
});
import requests

response = requests.get("https://snapapi.tech/v1/screenshot",
    params={"url": "github.com", "format": "webp"},
    headers={"x-api-key": "YOUR_KEY"})

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

PDF

GET /v1/pdf

Convert any webpage to a downloadable PDF. Renders in a real browser — supports A4, Letter, Legal, A3, A5, landscape, custom margins, and background colors. Returns application/pdf binary.

ParameterDefaultDescription
urlrequiredThe webpage URL to convert
formatA4Paper size: A4, Letter, Legal, A3, A5, Tabloid
landscapefalseLandscape orientation
print_backgroundfalseInclude background colors and images
scale1Page scale factor (0.1–2)
margin_top20Top margin in pixels
margin_right20Right margin in pixels
margin_bottom20Bottom margin in pixels
margin_left20Left margin in pixels
delay0Wait ms after load before capture (max 10000)
wait_for_selectorCSS selector to wait for before generating PDF.
wait_for_network_idlefalseWait for all network requests to complete before generating PDF.
cURL
JavaScript
Python
curl "https://snapapi.tech/v1/pdf?url=https://stripe.com&format=A4" \
  -H "x-api-key: YOUR_KEY" \
  -o stripe.pdf
const res = await fetch(
  "https://snapapi.tech/v1/pdf?" + new URLSearchParams({
    url: "https://stripe.com",
    api_key: "YOUR_KEY",
    format: "A4",
    print_background: "true"
  })
);
require("fs").writeFileSync("stripe.pdf", Buffer.from(await res.arrayBuffer()));
import requests

r = requests.get("https://snapapi.tech/v1/pdf", params={
    "url": "https://stripe.com",
    "api_key": "YOUR_KEY",
    "format": "A4",
    "print_background": "true"
})
with open("stripe.pdf", "wb") as f:
    f.write(r.content)

Metadata

GET /v1/metadata

Extract title, description, Open Graph tags, favicon, headings, and links from any webpage without rendering it visually. Faster and cheaper than a screenshot. Great for link previews, AI agents, and SEO tools.

cURL
JavaScript
Python
curl "https://snapapi.tech/v1/metadata?url=https://github.com" \
  -H "x-api-key: YOUR_KEY"
const res = await fetch(
  "https://snapapi.tech/v1/metadata?url=https://github.com",
  { headers: { "x-api-key": "YOUR_KEY" } }
);
const data = await res.json();
console.log(data.title, data.og_image, data.favicon);
import requests

resp = requests.get(
    "https://snapapi.tech/v1/metadata",
    params={"url": "https://github.com"},
    headers={"x-api-key": "YOUR_KEY"}
)
data = resp.json()
print(data["title"])
print(data["og_image"])
print(data["favicon"])

Example response

{
  "title": "GitHub · Build and ship software on a single, collaborative platform",
  "description": "GitHub is where...",
  "og_title": "GitHub",
  "og_image": "https://github.githubassets.com/images/modules/site/social-cards/homepage.png",
  "og_type": "website",
  "favicon": "https://github.com/favicon.ico",
  "canonical": "https://github.com/",
  "language": "en",
  "headings": [{ "level": 1, "text": "Build and ship software on a single, collaborative platform" }],
  "links": [{ "text": "Sign up", "href": "https://github.com/signup" }]
}

HTML → Image

POST /v1/render

Send raw HTML, receive a pixel-perfect PNG, JPEG, or WebP image. Perfect for OG cards, email previews, report thumbnails, and dynamic social images. Requires Starter plan or above.

Request body (JSON)

FieldDefaultDescription
htmlrequiredFull HTML string to render (max 2MB)
width1200Viewport width in pixels
height630Viewport height in pixels
formatpngOutput format: png, jpeg, webp
quality90Image quality (1-100, jpeg/webp only)
cURL
JavaScript
Python
curl -X POST "https://snapapi.tech/v1/render" \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html":"

My OG Card

","width":1200,"height":630}' \ -o og.png
const html = `

My Article Title

`; const res = await fetch("https://snapapi.tech/v1/render", { method: "POST", headers: { "x-api-key": "YOUR_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ html, width: 1200, height: 630, format: "png" }) }); require("fs").writeFileSync("og.png", Buffer.from(await res.arrayBuffer()));
import requests

html = """

My OG Image

""" resp = requests.post("https://snapapi.tech/v1/render", headers={"x-api-key": "YOUR_KEY"}, json={"html": html, "width": 1200, "height": 630, "format": "png"}) with open("og.png", "wb") as f: f.write(resp.content)

Batch

POST /v1/batch

Process up to 50 URLs in a single request. Runs concurrently up to your tier's parallel limit. Each URL counts as 1 API call. Batch limits: Starter 10 URLs, Pro 25, Business 50.

Request body (JSON)

FieldDefaultDescription
urlsrequiredArray of URLs to process (strings)
endpointanalyzeWhich endpoint to call per URL: analyze, screenshot, or metadata
params{}Query params forwarded to each endpoint call. E.g. {"screenshot": "true", "format": "webp"}
cURL
JavaScript
Python
curl -X POST "https://snapapi.tech/v1/batch" \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://stripe.com", "https://github.com", "https://vercel.com"],
    "endpoint": "analyze",
    "params": { "screenshot": "false" }
  }'
const res = await fetch("https://snapapi.tech/v1/batch", {
  method: "POST",
  headers: { "x-api-key": "YOUR_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    urls: ["https://stripe.com", "https://github.com", "https://vercel.com"],
    endpoint: "analyze"
  })
});
const { results, succeeded, failed, duration_ms } = await res.json();

for (const r of results) {
  if (r.status === "ok") {
    console.log(r.url, r.data.page_type, r.data.technologies);
  } else {
    console.error(r.url, r.error);
  }
}
import requests

resp = requests.post(
    "https://snapapi.tech/v1/batch",
    headers={"x-api-key": "YOUR_KEY"},
    json={
        "urls": ["https://stripe.com", "https://github.com", "https://vercel.com"],
        "endpoint": "analyze"
    }
)
data = resp.json()

for r in data["results"]:
    if r["status"] == "ok":
        print(r["url"], r["data"]["page_type"], r["data"]["technologies"])
    else:
        print(r["url"], "ERROR:", r["error"])

Example response

{
  "results": [
    {
      "url": "https://stripe.com",
      "status": "ok",
      "data": { "page_type": "landing", "primary_cta": { "text": "Start now", "href": "..." }, "technologies": ["react", "stripe"], "word_count": 1432 }
    },
    {
      "url": "https://bad-url-example.invalid",
      "status": "error",
      "error": "net::ERR_NAME_NOT_RESOLVED"
    }
  ],
  "total": 2,
  "succeeded": 1,
  "failed": 1,
  "duration_ms": 4210
}

Monitors

Scheduled snapshots with visual diff and optional structural analysis. Available on Starter plans and above. Each snapshot counts toward monthly usage.

POST /v1/monitors

Create a new monitor to capture snapshots on a schedule.

ParameterTypeRequiredDescription
urlstringYesURL to monitor
namestringNoDisplay name (defaults to hostname)
intervalintegerNoMinutes between snapshots (default: 60). Minimum: Starter=30, Pro=5, Business=1
webhook_urlstringNoURL to POST when a snapshot is captured
paramsobjectNoCapture params: width, height, format, quality, full_page, dark_mode, selector, delay
params.analyzebooleanNoEnable structural analysis per snapshot — detects CTA changes, technology changes, H1 rewrites, word count shifts. No extra page load.

Response

{
  "id": "mon_a1b2c3d4e5f6g7h8",
  "name": "example.com",
  "url": "https://example.com",
  "interval": 30,
  "status": "active",
  "next_run": "2026-03-10T12:30:00.000Z"
}
GET /v1/monitors

List all your monitors with status, run counts, and tier limits.

GET /v1/monitors/:id

Get a single monitor with its 20 most recent snapshots.

PATCH /v1/monitors/:id

Update a monitor. Pause/resume, change interval, rename, or update webhook.

ParameterTypeDescription
statusstring"active" or "paused"
intervalintegerNew interval in minutes
namestringNew display name
webhook_urlstringNew webhook URL (empty string to remove)
DELETE /v1/monitors/:id

Delete a monitor and all its stored snapshots.

GET /v1/monitors/:id/snapshots

Paginated snapshot history for a monitor.

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items per page (max 100)
GET /v1/monitors/:id/snapshots/:sid

Serve the actual screenshot image for a specific snapshot. Returns the image directly (Content-Type: image/png, image/jpeg, or image/webp).

WEBHOOK POST → your webhook_url

When a monitor captures a snapshot, SnapAPI sends a POST to your webhook URL (if configured).

Standard payload (visual diff only)

{
  "event": "snapshot.captured",
  "monitor_id": "mon_a1b2c3d4e5f6g7h8",
  "monitor_name": "My Site",
  "snapshot_id": "snap_x9y8z7w6v5u4",
  "url": "https://example.com",
  "taken_at": "2026-03-10T12:30:00.000Z",
  "changed": true,
  "diff_percent": 4.2,
  "meta": { "title": "Example Domain", "description": "" }
}

With params.analyze: true — structural diff included

{
  "event": "snapshot.captured",
  "changed": true,
  "diff_percent": 2.1,
  "structural_changes": {
    "primary_cta": { "before": "Start free trial", "after": "Get started" },
    "technologies": { "added": ["intercom"], "removed": [] },
    "word_count": { "before": 1240, "after": 980 }
  },
  "analysis": {
    "page_type": "landing",
    "primary_cta": { "text": "Get started", "href": "https://example.com/signup" },
    "technologies": ["react", "stripe", "intercom", "google-analytics"],
    "word_count": 980
  }
}

structural_changes only appears when analyze: true and something changed — keys are only present when that specific field changed.

Usage & Account

GET /v1/usage

Check your current usage, tier, and monthly limits.

Example response

{
  "tier": "starter",
  "usage": { "month": "2026-03", "count": 142 },
  "limits": { "monthly": 1000, "concurrent": 2 }
}
GET /v1/account

Get account details including email, tier, settings, and subscription management link.

Example response

{
  "email": "you@example.com",
  "tier": "pro",
  "masked_key": "snap_d9e0...4ed",
  "manage_subscription": "https://portal.lemonsqueezy.com/...",
  "settings": { "name": "My App", "allowed_domains": [] }
}
POST /v1/account/settings

Update your account settings (key name, allowed domains).

FieldTypeDescription
namestringDisplay name for your key (max 50 chars)
allowed_domainsstring[]Restrict key to specific domains (empty = any)

Example request

curl -X POST "https://snapapi.tech/v1/account/settings" \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My App", "allowed_domains": ["myapp.com"]}'

Signup & Recovery

POST /v1/signup

Create a free account and get your API key. If the email already exists, returns a masked key.

FieldTypeDescription
emailstringYour email address (required)

New account

{ "key": "snap_abc123...", "tier": "free", "limit": 100 }

Existing account

{ "exists": true, "masked_key": "snap_abc1...3xyz" }
POST /v1/account/recover

Send a 6-digit recovery code to your email.

FieldTypeDescription
emailstringThe email you signed up with
POST /v1/account/verify

Verify the recovery code and retrieve your full API key.

FieldTypeDescription
emailstringThe email you signed up with
codestring6-digit code from your email

System

GET /health

Health check. No authentication required.

Response

{ "status": "ok", "activeJobs": 0, "uptime": 3600 }
GET /v1/status

Detailed system metrics. No authentication required.

Response

{
  "status": "operational",
  "uptime_seconds": 3600,
  "total_requests": 500,
  "total_screenshots": 480,
  "total_errors": 2,
  "active_jobs": 1,
  "error_rate": 0.4,
  "latency": { "avg_ms": 2100, "p95_ms": 4500, "samples": 480 }
}
OpenAPI Spec (YAML)