Site Audit
The Site Audit endpoint loads any URL in a real Chromium browser and extracts:
- Color palette — grouped by background, text, primary, and accent (up to 20 unique colors)
- Fonts — every font family with weights and usage context (body, heading, code)
- Headings — all h1–h6 with font size, weight, color, and text content
- Tech stack — framework detection with confidence scores (Tailwind, Bootstrap, Next.js, React, Vue, WordPress, and more)
- Page metadata — title, description, OG image, favicon, language
Site Audit requires a Starter+ plan. Try it free at snapsharp.dev/tools/site-audit — 3 requests/day, no sign-up.
Endpoint
POST /v1/site-auditParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string | required | Target URL to audit |
format | json | png | pdf | json | Output format |
include_screenshot | boolean | true | Include base64 screenshot in the JSON response |
width | integer | 1280 | Viewport width in pixels (320–3840) |
sections | string[] | all | Sections to include: colors, fonts, headings, stack, accessibility |
dark_mode | boolean | false | Audit in dark color scheme (prefers-color-scheme: dark) |
device | string | — | Device preset (e.g. iPhone 14). Sets viewport, DPR, and User-Agent |
delay | integer | 0 | Wait N ms after page load before extracting tokens. Useful for JS-rendered content |
wait_for | string | — | CSS selector to wait for before auditing (waits up to 10s) |
block_cookie_banners | boolean | false | Hide GDPR/cookie banners before capture and extraction |
block_chats | boolean | false | Hide live chat widgets before capture and extraction |
proxy | string | — | Route through a proxy: http://user:pass@host:port |
country | enum | — | Geo-route via residential proxy: US, GB, DE, FR, NL, JP, AU, CA, BR, IN |
Response — JSON
curl -X POST https://api.snapsharp.dev/v1/site-audit \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://linear.app", "format": "json"}'{
"url": "https://linear.app",
"screenshot_url": "data:image/png;base64,...",
"extracted_at": "2026-03-27T12:00:00Z",
"colors": {
"primary": ["#5E6AD2", "#4B50C8"],
"background": ["#000000", "#111111"],
"text": ["#FFFFFF", "#B4B4B4"],
"accent": ["#EB5757"],
"all_unique": ["#000000", "#5E6AD2", "#FFFFFF", "..."]
},
"fonts": {
"families": [
{ "name": "Inter", "usage": "body", "count": 147, "weights": [400, 500, 600, 700] },
{ "name": "JetBrains Mono", "usage": "code", "count": 23, "weights": [400] }
],
"total_unique": 2
},
"headings": [
{
"tag": "h1",
"text": "Linear is a better way to build products",
"font_size": "56px",
"font_weight": "700",
"color": "#FFFFFF",
"font_family": "Inter"
}
],
"typography": {
"body_font_size": "16px",
"body_line_height": "1.6",
"heading_scale": [56, 40, 24, 20]
},
"stack": {
"css_framework": "Tailwind CSS",
"js_framework": "Next.js",
"ui_library": null,
"detection_confidence": 0.95,
"signals": [
{ "tech": "Next.js", "signal": "__NEXT_DATA__ script tag found", "confidence": 0.95 },
{ "tech": "Tailwind CSS", "signal": "Utility class patterns detected", "confidence": 0.9 },
{ "tech": "Vercel", "signal": "x-vercel-id header detected", "confidence": 0.85 }
]
},
"meta": {
"title": "Linear – A better way to build products",
"description": "Linear streamlines issues, sprints, and product roadmaps...",
"favicon_url": "https://linear.app/favicon.ico",
"og_image": "https://linear.app/og-image.png",
"language": "en",
"viewport": "width=device-width, initial-scale=1"
}
}Response — PNG (Site-Book)
Returns a pixel-perfect visual card (1200px wide) with all design tokens rendered beautifully.
curl -X POST https://api.snapsharp.dev/v1/site-audit \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://linear.app", "format": "png"}' \
--output site-book.pngThe PNG includes:
- A screenshot of the page (top fold)
- Color swatches with hex codes
- Font families with weights
- Heading hierarchy with sizes
- Technology stack badges
- SnapSharp watermark at the bottom
Response — PDF
Same content as PNG but rendered as A4 landscape PDF — perfect for client reports.
curl -X POST https://api.snapsharp.dev/v1/site-audit \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://linear.app", "format": "pdf"}' \
--output site-audit-linear.app.pdfAccessibility
When sections includes accessibility (or is omitted — all sections are included by default), the response includes a basic accessibility overview:
{
"accessibility": {
"images_without_alt": 3,
"total_images": 24,
"links_without_text": 1,
"headings_order_valid": true,
"lang_attribute": "en",
"has_skip_link": false,
"color_contrast_issues": 2,
"aria_landmarks": ["banner", "main", "contentinfo"],
"total_interactive_elements": 18,
"interactive_without_label": 0
}
}| Field | Description |
|---|---|
images_without_alt | Number of <img> elements missing alt attributes |
total_images | Total images on the page |
links_without_text | <a> elements without visible text or aria-label |
headings_order_valid | Whether heading levels are in correct order (h1 → h2 → h3) |
lang_attribute | Value of <html lang> attribute |
has_skip_link | Whether a "skip to content" link exists |
color_contrast_issues | Number of text/background pairs that fail WCAG AA contrast ratio |
aria_landmarks | ARIA landmark roles found on the page |
interactive_without_label | Buttons, inputs, selects without accessible labels |
Audit history
Every audit you run is saved and accessible from the dashboard. You can:
- Browse previous audits sorted by date
- Re-view full results (JSON, PNG, PDF) for any past audit
- Compare audits of the same URL over time to track design changes
- Delete audits you no longer need
Audit history is available on all paid plans with no retention limit.
SDK Examples
// Node.js
import { SnapSharp } from '@snapsharp/sdk';
const snap = new SnapSharp('sk_live_...');
const audit = await snap.siteAudit('https://linear.app', {
format: 'json',
sections: ['colors', 'fonts', 'stack', 'accessibility'],
});
console.log(audit.stack.js_framework); // "Next.js"
console.log(audit.colors.primary); // ["#5E6AD2", ...]
console.log(audit.accessibility.images_without_alt); // 3# Python
from snapsharp import SnapSharp
snap = SnapSharp("sk_live_...")
audit = snap.site_audit(
"https://linear.app",
format="json",
sections=["colors", "fonts", "stack", "accessibility"],
)
print(audit["stack"]["css_framework"]) # "Tailwind CSS"
print(audit["accessibility"]["headings_order_valid"]) # True// Go
package main
import (
"fmt"
snapsharp "github.com/bogdanov-igor/snapsharp/sdk-go"
)
func main() {
client := snapsharp.New("sk_live_...")
audit, _ := client.SiteAudit("https://linear.app",
&snapsharp.SiteAuditParams{Format: "json"})
fmt.Println(audit.Stack.JSFramework) // "Next.js"
}<?php
// PHP
use SnapSharp\SnapSharp;
$snap = new SnapSharp('sk_live_...');
$audit = $snap->siteAudit('https://linear.app', [
'format' => 'json',
]);
echo $audit['stack']['css_framework']; // "Tailwind CSS"# Ruby
require "snapsharp"
snap = SnapSharp.new("sk_live_...")
audit = snap.site_audit("https://linear.app", format: "json")
puts audit["stack"]["js_framework"] # "Next.js"Stack Detection
The following technologies are detected automatically:
| Technology | Signal |
|---|---|
| Tailwind CSS | Utility class patterns (flex, px-, bg-) |
| Bootstrap | Class patterns (container, col-, btn-) |
| Material UI | Mui* class prefixes |
| Chakra UI | chakra- class prefixes |
| Next.js | __NEXT_DATA__ script tag |
| Nuxt | __NUXT__ global variable |
| React | data-reactroot, #__next, #root |
| Vue.js | data-v-* scoped attributes |
| Angular | app-root, ng-version attribute |
| WordPress | meta[generator], wp-content paths |
| Webflow | Generator meta tag |
| Framer | Generator meta tag, framer-* classes |
| Vercel | x-vercel-id response header |
| Netlify | x-powered-by: netlify header |
Limitations
| Limitation | Details |
|---|---|
| Cross-origin iframes | Fonts and styles inside cross-origin iframes (e.g. embedded widgets, third-party forms) cannot be extracted due to browser security policies. Only same-origin iframes are scanned. |
| Server-side rendered fonts | If a site loads fonts exclusively via server-side rendering (e.g. @font-face injected at build time with no client-side <link> or @import), the font family name may appear as a generic fallback until networkidle is reached. We wait up to 10 seconds for async font loading. |
| Dynamic font loading | Fonts loaded via JavaScript after user interaction (scroll, click) won't be detected. Only fonts present after initial page load + networkidle are captured. |
| Shadow DOM | Elements inside closed Shadow DOM roots are not scanned. Open Shadow DOM roots are partially supported. |
| Very large pages | Pages with more than ~50,000 DOM elements may time out or return partial results. Screenshots are capped at 8000px height. |
| Authentication-protected pages | Sites behind login walls, CAPTCHA, or Cloudflare challenges may return incomplete or blocked results. |
To improve font detection accuracy, the audit waits for networkidle (up to 10s) after initial page load, giving async web fonts time to load. Same-origin iframes are also scanned for additional font families.
Errors
| Code | Error | Description |
|---|---|---|
| 400 | invalid_url | Invalid URL or parameters (private, blocked, or SSRF-protected) |
| 401 | unauthorized | Missing or invalid API key |
| 403 | plan_required | Starter+ plan required |
| 429 | rate_limited | Rate limit exceeded |
| 500 | — | Internal server error |
| 502 | audit_failed | Page unreachable or browser error |
| 503 | service_unavailable | No browser instances available. Retry shortly. |
| 504 | timeout | Audit timed out after 30 seconds |
Pricing
| Plan | Site Audit |
|---|---|
| Free | ❌ |
| Starter | ✅ JSON + PNG + PDF |
| Growth | ✅ |
| Business | ✅ |
| Enterprise | ✅ |