Everything you need to integrate SnapAPI into your application
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.
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.
| Parameter | Default | Description |
|---|---|---|
| url | required | The webpage URL to analyze |
| screenshot | false | Include a base64 PNG snapshot alongside the analysis |
| delay | 0 | Wait ms after load (max 10000) |
| wait_for_selector | — | CSS selector to wait for before analyzing. Essential for React/SPA apps. Example: #app, .content-loaded |
| wait_for_network_idle | false | Wait for all network requests to complete after load. |
| interact | — | JSON 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 "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..."
}
Capture a visual snapshot of any webpage as a high-quality image. Returns the image binary directly (or JSON with metadata if meta=true).
| Parameter | Default | Description |
|---|---|---|
| url | required | Website URL to capture |
| width | 1280 | Viewport width in pixels |
| height | 800 | Viewport height in pixels |
| format | png | Output format: png, jpeg, webp |
| quality | 80 | Image quality (1-100, jpeg/webp only) |
| full_page | false | Capture full scrollable page |
| delay | 0 | Wait ms after load (max 10000, for SPAs) |
| dark_mode | false | Emulate dark color scheme |
| block_ads | false | Block common ad networks and trackers |
| selector | — | CSS selector to capture a specific element |
| meta | false | Return JSON with title, description, favicon + base64 image |
| device | — | Device preset: iphone14, iphone14pro, iphone15, pixel7, pixel8, galaxys23, ipad, ipadpro, desktop |
| cache | true | Use 30-min response cache |
| wait_for_selector | — | CSS selector to wait for before capture. Essential for SPAs, React apps. Example: #app, .dashboard |
| wait_for_network_idle | false | Wait for all network requests to complete after page load. |
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)
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.
| Parameter | Default | Description |
|---|---|---|
| url | required | The webpage URL to convert |
| format | A4 | Paper size: A4, Letter, Legal, A3, A5, Tabloid |
| landscape | false | Landscape orientation |
| print_background | false | Include background colors and images |
| scale | 1 | Page scale factor (0.1–2) |
| margin_top | 20 | Top margin in pixels |
| margin_right | 20 | Right margin in pixels |
| margin_bottom | 20 | Bottom margin in pixels |
| margin_left | 20 | Left margin in pixels |
| delay | 0 | Wait ms after load before capture (max 10000) |
| wait_for_selector | — | CSS selector to wait for before generating PDF. |
| wait_for_network_idle | false | Wait for all network requests to complete before generating PDF. |
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)
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 "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" }]
}
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)
| Field | Default | Description |
|---|---|---|
| html | required | Full HTML string to render (max 2MB) |
| width | 1200 | Viewport width in pixels |
| height | 630 | Viewport height in pixels |
| format | png | Output format: png, jpeg, webp |
| quality | 90 | Image quality (1-100, jpeg/webp only) |
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)
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)
| Field | Default | Description |
|---|---|---|
| urls | required | Array of URLs to process (strings) |
| endpoint | analyze | Which endpoint to call per URL: analyze, screenshot, or metadata |
| params | {} | Query params forwarded to each endpoint call. E.g. {"screenshot": "true", "format": "webp"} |
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
}
Scheduled snapshots with visual diff and optional structural analysis. Available on Starter plans and above. Each snapshot counts toward monthly usage.
Create a new monitor to capture snapshots on a schedule.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL to monitor |
| name | string | No | Display name (defaults to hostname) |
| interval | integer | No | Minutes between snapshots (default: 60). Minimum: Starter=30, Pro=5, Business=1 |
| webhook_url | string | No | URL to POST when a snapshot is captured |
| params | object | No | Capture params: width, height, format, quality, full_page, dark_mode, selector, delay |
| params.analyze | boolean | No | Enable 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"
}
List all your monitors with status, run counts, and tier limits.
Get a single monitor with its 20 most recent snapshots.
Update a monitor. Pause/resume, change interval, rename, or update webhook.
| Parameter | Type | Description |
|---|---|---|
| status | string | "active" or "paused" |
| interval | integer | New interval in minutes |
| name | string | New display name |
| webhook_url | string | New webhook URL (empty string to remove) |
Delete a monitor and all its stored snapshots.
Paginated snapshot history for a monitor.
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | integer | 1 | Page number |
| limit | integer | 20 | Items per page (max 100) |
Serve the actual screenshot image for a specific snapshot. Returns the image directly (Content-Type: image/png, image/jpeg, or image/webp).
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.
Check your current usage, tier, and monthly limits.
Example response
{
"tier": "starter",
"usage": { "month": "2026-03", "count": 142 },
"limits": { "monthly": 1000, "concurrent": 2 }
}
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": [] }
}
Update your account settings (key name, allowed domains).
| Field | Type | Description |
|---|---|---|
| name | string | Display name for your key (max 50 chars) |
| allowed_domains | string[] | 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"]}'
Create a free account and get your API key. If the email already exists, returns a masked key.
| Field | Type | Description |
|---|---|---|
| string | Your email address (required) |
New account
{ "key": "snap_abc123...", "tier": "free", "limit": 100 }
Existing account
{ "exists": true, "masked_key": "snap_abc1...3xyz" }
Send a 6-digit recovery code to your email.
| Field | Type | Description |
|---|---|---|
| string | The email you signed up with |
Verify the recovery code and retrieve your full API key.
| Field | Type | Description |
|---|---|---|
| string | The email you signed up with | |
| code | string | 6-digit code from your email |
Health check. No authentication required.
Response
{ "status": "ok", "activeJobs": 0, "uptime": 3600 }
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 }
}