Lighthouse Performance Audits for Any Website
GET /audit?url=https://example.com
Returns all categories: Performance, Accessibility, Best Practices, SEO
GET /audit?url=https://example.com&quick=true
Faster! Only runs performance audit (~15-20s instead of 30-40s)
GET /audit?url=https://example.com&strategy=mobile
GET /audit?url=https://example.com&strategy=desktop
Test mobile or desktop experience (default: desktop). Desktop uses Lighthouse's own desktop throttling (desktopDense4G, no CPU slowdown), so desktop scores line up with PageSpeed Insights and Chrome DevTools. Mobile uses Lighthouse's mobile calibration.
GET /audit?url=https://example.com&categories=performance,seo
performance - Core Web Vitals & speed metricsaccessibility - A11y compliancebest-practices - Web best practicesseo - SEO optimizationGET /audit?url=https://example.com&runs=3
Runs the performance audit three times and reports the MEDIAN score and
that run's metrics, plus a variance object
({ runs, performanceScores, spread }) - steadier numbers on
noisy sites. Allowed values: 1 (default) or 3. Heads up: runs=3 takes
about 3x as long and counts as 3 requests against your rate limit.
Whenever performance is audited, the response includes an
opportunities array - Lighthouse's top 3 fixes by estimated
savings (omitted when there are none):
"opportunities": [
{
"id": "render-blocking-resources",
"title": "Eliminate render-blocking resources",
"savings": "1.2 s",
"savingsMs": 1230
}
]
GET /audit?url=https://example.com&fields=scores
Return only what you need. Comma-separated from scores,
coreWebVitals, opportunities,
variance. The response always keeps url,
timestamp, strategy, cached (and
age when cached). fields=scores is the compact
badge/CI shape.
{
"url": "https://example.com",
"timestamp": "2025-10-17T12:00:00.000Z",
"strategy": "desktop",
"scores": {
"performance": 95,
"accessibility": 88,
"bestPractices": 92,
"seo": 90
},
"coreWebVitals": {
"largestContentfulPaint": {
"value": "1.2 s",
"score": 100,
"rating": "good"
},
...
},
"cached": false
}
Cached responses also include an age field: seconds since
the result was generated.
X-Cache - HIT or MISSX-RateLimit-Remaining - audits left in the current windowX-RateLimit-Reset - Unix time (seconds) when the window resetsAll errors share one shape with a stable machine-readable code:
{
"error": "Rate limit exceeded",
"code": "rate_limited",
"hint": "Try again in 42 minutes (limit 50/hour)."
}
Codes: rate_limited, queue_full,
timeout, unreachable, invalid_url,
invalid_categories, invalid_runs,
invalid_fields, internal.
quick=true for faster auditsBuilt with ❤️ using Lighthouse, Hono, and Bun