Full-featured API with the same capabilities as the dashboard
The API provides the same capabilities as scanning through the dashboard:
Follow these 3 steps to make your first API call and start scanning websites.
Generate an API key from the API Keys page
Copy and run this code:
# 1. Set your API key
export API_KEY="your_api_key_here"
# 2. Trigger a scan
curl -X POST https://jsvisible.com/api/v1/scan \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
# 3. Check your usage
curl https://jsvisible.com/api/v1/usage \
-H "Authorization: Bearer $API_KEY"Start integrating JSVisible into your application
All API requests require an API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYGenerate your API key from the API Keys page.
Enterprise tier includes 200 API scans per month (shared with dashboard). GET requests to view results are unlimited! Perfect for monitoring hundreds of websites daily. Need more? Contact sales@jsvisible.com for custom limits.
The API returns rate limit information in response headers:
HTTP/1.1 200 OK
X-Scans-Limit: 200
X-Scans-Remaining: 187
X-Scans-Reset: 1735689600
{
"success": true,
...
}Tip: Check X-Scans-Remaining to monitor your usage and avoid hitting the limit.
https://jsvisible.com/api/v1/api/v1/scanTrigger a new SEO scan. Supports single URL crawl mode or multi-URL list mode.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | * | Single URL to crawl (discovers and follows links) |
urls | string[] | * | Array of specific URLs to scan (URL List Mode, max 100) |
max_pages | number | No | Max pages to scan (default: 500 for Enterprise) |
team_id | string | No | Associate scan with a team (UUID) |
* Either url or urls is required (not both)
Provide a single URL. The crawler will discover and follow internal links automatically.
curl -X POST https://jsvisible.com/api/v1/scan \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "max_pages": 50}'Provide an array of specific URLs. Can include different domains. No auto-discovery.
curl -X POST https://jsvisible.com/api/v1/scan \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com",
"https://example.com/about",
"https://example.com/pricing",
"https://competitor.com"
]
}'Associate scans with a team for shared access. Requires appropriate team permissions.
curl -X POST https://jsvisible.com/api/v1/scan \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"team_id": "550e8400-e29b-41d4-a716-446655440000"
}'{
"success": true,
"scan_id": "550e8400-e29b-41d4-a716-446655440000",
"website": "https://example.com",
"status": "completed",
"total_issues": 5,
"total_warnings": 12,
"pages_analyzed": 25,
"seo_score": 78,
"mode": "crawl", // or "url_list"
"urls_scanned": null, // number if url_list mode
"screenshots_enabled": true,
"screenshot_count": 3,
"team_id": null, // or team UUID
"quota": {
"scansUsed": 48,
"scansLimit": 200,
"scansRemaining": 152
}
}Note: Use GET /api/v1/scan/:id to retrieve full scan data including all issues, JS errors, internal links, and screenshots.
/api/v1/scansRetrieve a list of your scans with pagination support.
limit (optional): Number of results (default: 10, max: 100)offset (optional): Pagination offset (default: 0)curl "https://jsvisible.com/api/v1/scans?limit=10&offset=0" \
-H "Authorization: Bearer YOUR_API_KEY"{
"success": true,
"scans": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"website": "https://example.com",
"total_issues": 5,
"total_warnings": 12,
"pages_analyzed": 25,
"seo_score": 78,
"crawled_at": "2026-11-20T10:30:00Z"
}
],
"pagination": {
"count": 1,
"limit": 10,
"offset": 0,
"total": 47
}
}/api/v1/scan/:idFull DataGet complete scan details including all pages, issues, JS errors, internal links, and screenshots.
curl https://jsvisible.com/api/v1/scan/SCAN_ID \
-H "Authorization: Bearer YOUR_API_KEY"{
"success": true,
"scan": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"website": "https://example.com",
"total_issues": 5,
"total_warnings": 12,
"pages_analyzed": 25,
"seo_score": 78,
"crawled_at": "2026-11-20T10:30:00Z",
"team_id": null,
"mode": "crawl",
"screenshots_captured": 3,
// Aggregated JS error counts
"js_error_summary": {
"uncaughtExceptions": 2,
"consoleErrors": 8,
"failedRequests": 1
},
// Internal link analysis
"internal_link_analysis": {
"total_internal_links": 156,
"orphan_pages": 3,
"avg_links_per_page": 6.2,
"orphan_page_urls": [
"https://example.com/old-page",
"https://example.com/hidden-content"
]
},
// Full page-by-page data
"scan_data": [
{
"url": "https://example.com",
"title": "Example Site - Home",
"metaDescription": "Welcome to Example Site...",
"h1Count": 1,
"h1Text": "Welcome to Example",
"wordCount": 450,
"loadTime": "1.24s",
"issues": ["Missing meta description"],
"warnings": ["Title too short (28 chars)"],
// Internal links for this page
"internalLinksCount": 12,
"internalLinksTo": [], // Pages linking TO this page
// Per-page JS errors
"jsErrors": {
"uncaughtExceptions": 1,
"consoleErrors": 3,
"failedRequests": 0
},
// Screenshots (if captured) - Desktop & Mobile
"screenshots": {
"desktop": {
"userView": {
"screenshot": "base64...",
"metrics": { "title": "...", "textLength": 4500 }
},
"googlebotView": {
"screenshot": "base64...",
"metrics": { "title": "...", "textLength": 4200 }
}
},
"mobile": {
"userView": {
"screenshot": "base64...",
"metrics": { "title": "...", "textLength": 4300 }
},
"googlebotView": {
"screenshot": "base64...",
"metrics": { "title": "...", "textLength": 4100 }
}
},
"differences": [
{
"type": "content_difference",
"severity": "warning",
"device": "desktop",
"message": "Googlebot sees 7% less content"
}
],
"renderingHealth": "good",
"summary": "Minor differences detected"
},
"details": {
"titleLength": 28,
"hasCanonical": true,
"hasStructuredData": false
}
}
],
// Issues from database
"issues": [
{
"id": 1,
"page_url": "https://example.com",
"issue_type": "missing_meta_description",
"severity": "error",
"message": "Missing meta description"
}
]
},
"quota": {
"scansUsed": 48,
"scansLimit": 200,
"scansRemaining": 152
}
}uncaughtExceptions - Runtime JS errorsconsoleErrors - console.error() callsfailedRequests - Failed script/API loadsorphan_pages - Pages with 0 internal linksavg_links_per_page - Average link countorphan_page_urls - List of orphan URLsdesktop.userView - Desktop user screenshotdesktop.googlebotView - Desktop Googlebotmobile.userView - Mobile user screenshotmobile.googlebotView - Mobile GooglebotrenderingHealth - excellent/good/fair/poor/api/v1/usageCheck your current API usage and quota limits.
curl https://jsvisible.com/api/v1/usage \
-H "Authorization: Bearer YOUR_API_KEY"{
"success": true,
"current_period": {
"start": "2026-01-01T00:00:00Z",
"end": "2026-02-01T00:00:00Z"
},
"scans": {
"used": 47,
"limit": 200,
"remaining": 153,
"reset_at": "2026-02-01T00:00:00Z"
},
"limits": {
"pages_per_scan": 500,
"total_pages_per_month": 100000,
"max_urls_per_list": 100
},
"note": "API scans share quota with dashboard scans. GET requests are unlimited."
}Invalid or missing API key
{
"success": false,
"error": "unauthorized",
"message": "Invalid API key"
}API access requires Enterprise tier, or insufficient team permissions
{
"success": false,
"error": "permission_denied",
"message": "You do not have permission to run scans in this team."
}Monthly scan limit reached
{
"success": false,
"error": "scan_limit_exceeded",
"message": "Monthly scan limit reached (200 scans). Resets on February 1, 2026.",
"quota": {
"scansUsed": 200,
"scansLimit": 200,
"scansRemaining": 0
}
}Invalid parameters
{
"success": false,
"error": "Invalid URL format: not-a-valid-url"
}urls array instead of crawlingjs_error_summary.uncaughtExceptions for critical JavaScript issues affecting SEOinternal_link_analysis.orphan_pages to find pages with no internal linksscreenshots.renderingHealth to quickly identify Googlebot rendering issues on desktop and mobileteam_id to organize scans by project or client/api/v1/usage before batch operations to ensure sufficient quotaAs an Enterprise customer, you have access to priority support.