{"openapi":"3.1.0","info":{"title":"ScanMalware API","description":"URL Security Scanner API","version":"1.0.0"},"paths":{"/api/v1/":{"get":{"summary":"Root","description":"API root endpoint","operationId":"root_api_v1__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/recent":{"get":{"summary":"Get Recent Scans","description":"Get recent public scans with pagination - only public scans are returned via API","operationId":"get_recent_scans_api_v1_recent_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/rss":{"get":{"summary":"Get Rss Feed","description":"RSS feed of latest public scans (cached for 60 seconds)","operationId":"get_rss_feed_api_v1_rss_get","responses":{"200":{"description":"Successful Response"}}}},"/sitemap.xml":{"get":{"summary":"Get Sitemap","description":"Serve the pre-generated XML sitemap.","operationId":"get_sitemap_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/sitemap.xml.gz":{"get":{"summary":"Get Sitemap Gz","description":"Serve the gzip-compressed sitemap as a gzip file.","operationId":"get_sitemap_gz_sitemap_xml_gz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/robots.txt":{"get":{"summary":"Get Robots Txt","description":"Serve robots.txt.","operationId":"get_robots_txt_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/og/{scan_id}":{"get":{"summary":"Get Og Metadata","description":"Get Open Graph metadata for a scan (lightweight endpoint for link previews)","operationId":"get_og_metadata_api_v1_og__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/result/{scan_id}/progress":{"get":{"summary":"Get Scan Progress Endpoint","description":"Get current scan progress for frontend progress bar","operationId":"get_scan_progress_endpoint_api_v1_result__scan_id__progress_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"tags":["statistics"],"summary":"Get Stats","description":"Get system statistics","operationId":"get_stats_api_v1_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/stats/capabilities/latest":{"get":{"tags":["statistics"],"summary":"Get Latest Capabilities","description":"Get latest detection capabilities report from JSONL file","operationId":"get_latest_capabilities_api_v1_stats_capabilities_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/stats/capabilities/by-date":{"get":{"tags":["statistics"],"summary":"Get Capabilities By Date","description":"Get detection capabilities for a specific date, or nearest date if no exact match","operationId":"get_capabilities_by_date_api_v1_stats_capabilities_by_date_get","parameters":[{"name":"scan_date","in":"query","required":true,"schema":{"type":"string","description":"Scan date in YYYY-MM-DD format","title":"Scan Date"},"description":"Scan date in YYYY-MM-DD format"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/site-stats":{"get":{"tags":["statistics"],"summary":"Get Site Stats","description":"Public statistics for the chosen time window: scan volume, malicious sites by IP, network,\nparent domain, hosting platform, TLD, country and city, threat types, and the countries URLs\nare submitted from (the scanner's own automated submissions excluded).","operationId":"get_site_stats_api_v1_site_stats_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","description":"Time window: 12h, 24h, 7d or 30d","default":"24h","title":"Window"},"description":"Time window: 12h, 24h, 7d or 30d"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/site-stats/scripts":{"get":{"tags":["statistics"],"summary":"Get Site Script Stats","description":"JavaScript statistics for the chosen time window: the most loaded third-party script hosts and\nscript URLs, the most common first-party script paths, and the most popular JavaScript\nlibraries and frameworks, counted as distinct websites.","operationId":"get_site_script_stats_api_v1_site_stats_scripts_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","description":"Time window: 12h, 24h, 7d or 30d","default":"24h","title":"Window"},"description":"Time window: 12h, 24h, 7d or 30d"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/site-stats/tls":{"get":{"tags":["statistics"],"summary":"Get Site Tls Stats","description":"TLS server fingerprint statistics for the chosen time window: the most common JARM and JA4S\nfingerprints across scanned websites, and the ones seen on the most malicious websites.","operationId":"get_site_tls_stats_api_v1_site_stats_tls_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","description":"Time window: 12h, 24h, 7d or 30d","default":"24h","title":"Window"},"description":"Time window: 12h, 24h, 7d or 30d"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/site-stats/traffic":{"get":{"tags":["statistics"],"summary":"Get Site Traffic Stats","description":"Site traffic for the chosen time window: the most viewed public scans and the countries\nvisitors come from (both as rankings), and the domains and API endpoints most requested\nthrough the API.","operationId":"get_site_traffic_stats_api_v1_site_stats_traffic_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","description":"Time window: 12h, 24h, 7d or 30d","default":"24h","title":"Window"},"description":"Time window: 12h, 24h, 7d or 30d"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scan-statistics":{"get":{"tags":["scan-statistics"],"summary":"Get Scan Statistics","description":"Get pre-computed scan statistics.\n\nReturns comprehensive scan statistics including:\n- Total scans and breakdown by status\n- Scans by type (public/private/api)\n- Time-based counts (24h, 7d, 30d)\n- Last updated timestamp","operationId":"get_scan_statistics_api_v1_scan_statistics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/scan-statistics/quick":{"get":{"tags":["scan-statistics"],"summary":"Get Quick Stats","description":"Get ultra-fast overview statistics.\n\nPerformance: Sub-millisecond response time\nReturns only the most essential counts for dashboard overview.","operationId":"get_quick_stats_api_v1_scan_statistics_quick_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/scan-statistics/by-status":{"get":{"tags":["scan-statistics"],"summary":"Get Stats By Status","description":"Get scan counts grouped by status.\n\nReturns breakdown of scans by their current status\n(completed, pending, processing, failed).","operationId":"get_stats_by_status_api_v1_scan_statistics_by_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/scan-statistics/by-type":{"get":{"tags":["scan-statistics"],"summary":"Get Stats By Type","description":"Get scan counts grouped by type.\n\nReturns breakdown of scans by type\n(public, private, api).","operationId":"get_stats_by_type_api_v1_scan_statistics_by_type_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/scan-statistics/time-periods":{"get":{"tags":["scan-statistics"],"summary":"Get Stats By Time","description":"Get scan counts by time period.\n\nReturns counts for different time windows\n(24 hours, 7 days, 30 days) and total.","operationId":"get_stats_by_time_api_v1_scan_statistics_time_periods_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/scan-statistics/dashboard":{"get":{"tags":["scan-statistics"],"summary":"Get Dashboard Stats","description":"Get comprehensive statistics optimized for dashboard display.\n\nReturns all statistics in a dashboard-friendly format with\ncomputed percentages, rates, and time-based breakdowns.","operationId":"get_dashboard_stats_api_v1_scan_statistics_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/favicon/search/{mmh3_hash}":{"get":{"tags":["favicon"],"summary":"Search By Favicon Mmh3","description":"Search for websites with the same favicon MMH3 hash with pagination","operationId":"search_by_favicon_mmh3_api_v1_favicon_search__mmh3_hash__get","parameters":[{"name":"mmh3_hash","in":"path","required":true,"schema":{"type":"integer","title":"Mmh3 Hash"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/favicon/stats":{"get":{"tags":["favicon"],"summary":"Get Favicon Stats","description":"Get statistics about favicon hashes in the database","operationId":"get_favicon_stats_api_v1_favicon_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/favicon/{scan_id}":{"get":{"tags":["favicon"],"summary":"Get Favicon Endpoint","description":"Get favicon for a specific scan from object storage or base64 data","operationId":"get_favicon_endpoint_api_v1_favicon__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/favicon/{hash_value}":{"get":{"tags":["search","favicon"],"summary":"Search By Favicon Hash","description":"Search for scans by favicon hash (MMH3 or MD5) with pagination\nReturns scan IDs that match the given favicon hash\nOnly returns public scans","operationId":"search_by_favicon_hash_api_v1_search_favicon__hash_value__get","parameters":[{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","maxLength":64,"pattern":"^[a-fA-F0-9-]+$","description":"Hash value to search","title":"Hash Value"},"description":"Hash value to search"},{"name":"hash_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(mmh3|md5)$","description":"Type of hash to search","default":"mmh3","title":"Hash Type"},"description":"Type of hash to search"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/clipboard/stats":{"get":{"tags":["clipboard","pastejacking"],"summary":"Get Clipboard Statistics","description":"Get clipboard monitoring statistics","operationId":"get_clipboard_statistics_api_v1_clipboard_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/clipboard/{scan_id}":{"get":{"tags":["clipboard","pastejacking"],"summary":"Get Clipboard Events","description":"Get clipboard events captured during a scan","operationId":"get_clipboard_events_api_v1_clipboard__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pastejacking/{scan_id}":{"get":{"tags":["clipboard","pastejacking"],"summary":"Get Pastejacking Detections","description":"Get pastejacking detections for a scan","operationId":"get_pastejacking_detections_api_v1_pastejacking__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/clipboard/suspicious":{"get":{"tags":["clipboard","pastejacking"],"summary":"Search Suspicious Clipboard","description":"Search for suspicious clipboard activity patterns","operationId":"search_suspicious_clipboard_api_v1_search_clipboard_suspicious_get","parameters":[{"name":"pattern","in":"query","required":false,"schema":{"type":"string","description":"Pattern to search in suspicious clipboard events","title":"Pattern"},"description":"Pattern to search in suspicious clipboard events"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/ocr":{"get":{"tags":["ocr"],"summary":"Search Ocr Text","description":"Search through OCR-extracted text from screenshots","operationId":"search_ocr_text_api_v1_search_ocr_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":3,"description":"Search query for OCR text","title":"Q"},"description":"Search query for OCR text"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/ocr/pattern":{"get":{"tags":["ocr"],"summary":"Search Ocr Pattern","description":"Search for specific patterns in OCR text (e.g., 'Windows+R', 'Ctrl+V')","operationId":"search_ocr_pattern_api_v1_search_ocr_pattern_get","parameters":[{"name":"pattern","in":"query","required":true,"schema":{"type":"string","description":"Pattern to search for in OCR text","title":"Pattern"},"description":"Pattern to search for in OCR text"},{"name":"case_sensitive","in":"query","required":false,"schema":{"type":"boolean","description":"Case sensitive search","default":false,"title":"Case Sensitive"},"description":"Case sensitive search"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ocr/stats":{"get":{"tags":["ocr"],"summary":"Get Ocr Statistics","description":"Get OCR processing statistics","operationId":"get_ocr_statistics_api_v1_ocr_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/ocr/{scan_id}":{"get":{"tags":["ocr"],"summary":"Get Ocr Text","description":"Get OCR text extracted from a scan's screenshot","operationId":"get_ocr_text_api_v1_ocr__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/technologies/search":{"get":{"tags":["Technologies"],"summary":"Search technologies","description":"Search for technologies by name or category with full-text search support. Results are paginated and sorted by occurrence count.","operationId":"search_technologies_api_v1_technologies_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search term for technology name (supports partial matching and full-text search)","title":"Q"},"description":"Search term for technology name (supports partial matching and full-text search)","example":"wordpress"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by technology category","title":"Category"},"description":"Filter by technology category","example":"CMS"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number","example":1},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page","example":50}],"responses":{"200":{"description":"Paginated list of technologies matching the search criteria","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/technologies/popular":{"get":{"tags":["Technologies"],"summary":"Get Popular Technologies","description":"Get most popular technologies from recent scans with pagination","operationId":"get_popular_technologies_api_v1_technologies_popular_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/technologies/combinations/{tech_name}":{"get":{"tags":["Technologies"],"summary":"Get Technology Combinations","description":"Find technologies commonly used together with a specific technology with pagination","operationId":"get_technology_combinations_api_v1_technologies_combinations__tech_name__get","parameters":[{"name":"tech_name","in":"path","required":true,"schema":{"type":"string","maxLength":100,"pattern":"^[a-zA-Z0-9 ._/-]+$","description":"Technology name to find combinations for","title":"Tech Name"},"description":"Technology name to find combinations for"},{"name":"min_occurrences","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Minimum occurrences to include","default":2,"title":"Min Occurrences"},"description":"Minimum occurrences to include"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/technologies/stats":{"get":{"tags":["Technologies"],"summary":"Get Technology Stats","description":"Get aggregated technology statistics","operationId":"get_technology_stats_api_v1_technologies_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/technologies/by-scan/{scan_id}":{"get":{"tags":["Technologies"],"summary":"Get Scan Technologies","description":"Get all technologies detected in a specific scan","operationId":"get_scan_technologies_api_v1_technologies_by_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/technologies/bot-protection/{scan_id}":{"get":{"tags":["Technologies"],"summary":"Get Bot Protection","description":"Get bot protection technologies detected in a specific scan","operationId":"get_bot_protection_api_v1_technologies_bot_protection__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/domain/stats/{domain}":{"get":{"tags":["domain"],"summary":"Get Domain Scan Statistics","description":"Get scan statistics for a specific domain","operationId":"get_domain_scan_statistics_api_v1_domain_stats__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/domain/history/{domain}":{"get":{"tags":["domain"],"summary":"Get Domain Scan History","description":"Get scan history for a specific domain with pagination","operationId":"get_domain_scan_history_api_v1_domain_history__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":5,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/domains/{domain}/scans":{"get":{"tags":["domain"],"summary":"Get Domain Scans","description":"Public scans of a domain and its subdomains, matched on the scanned HOST.\n\nA scan matches when the domain is the entry host, the final host after redirects, or a\nsubdomain of either. `matched_on` says which of the two it was, so a caller can tell a scan\nthat STARTED here from one that merely REDIRECTED here — a distinction a flat list loses:\n\n- `[\"url\"]`         the scan was submitted for this domain\n- `[\"final_url\"]`   it landed here from somewhere else (`final_url` shows where it started)\n- both              entry and destination are both this domain\n\nThe domain must appear as a whole label. A host that merely CONTAINS the string does not\nmatch, and neither does the domain appearing anywhere in a path or query string.","operationId":"get_domain_scans_api_v1_domains__domain__scans_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(queued|processing|completed|failed)$"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/hosts/{domain}":{"get":{"tags":["domain"],"summary":"Get Domain Hosts","description":"Every host seen for a domain, grouped by how we learned about it.\n\nSources, strongest evidence first:\n\n- `observed`   the browser resolved and requested it\n- `scripts`    a script the browser actually loaded\n- `declared`   named in the page's Content-Security-Policy - intent, NOT contact\n- `static`     called from a URL sink in script source - roughly a third are corroborated\n               by runtime, the rest being conditional or dead code\n- `referenced` appears only in a string literal or comment - a reference, not an endpoint\n- `stream`     a third party asked us about this host and DNS confirms it exists - existence only\n\nDefaults to `observed,scripts,stream`. The first two are hosts the browser really\ncontacted; `stream` is a different kind of evidence and answers a different question -\nwhat EXISTS under the domain, rather than what its pages touched. We have never fetched a\n`stream` host, so it carries nothing about content or intent. Ask for\n`sources=observed,scripts` to get the runtime-observed answer alone.\n\nOpt into the weaker sources explicitly; every host is always returned under its own key so\na caller cannot mistake intent, or mere existence, for evidence of contact.\n\n`subdomains_only=true` drops the domain itself and anything not strictly below it.","operationId":"get_domain_hosts_api_v1_hosts__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."},{"name":"sources","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated: observed, scripts, declared, static, referenced, stream. Defaults to the two runtime-observed sources plus stream. Use sources=observed,scripts for runtime-observed hosts only.","default":"observed,scripts,stream","title":"Sources"},"description":"Comma-separated: observed, scripts, declared, static, referenced, stream. Defaults to the two runtime-observed sources plus stream. Use sources=observed,scripts for runtime-observed hosts only."},{"name":"subdomains_only","in":"query","required":false,"schema":{"type":"boolean","description":"Return only hosts strictly below the domain","default":false,"title":"Subdomains Only"},"description":"Return only hosts strictly below the domain"},{"name":"max_scans","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Newest scans of this domain to aggregate over","default":200,"title":"Max Scans"},"description":"Newest scans of this domain to aggregate over"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"description":"Maximum hosts per source","default":2000,"title":"Limit"},"description":"Maximum hosts per source"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pcap/{scan_id}":{"get":{"tags":["pcap"],"summary":"Get Pcap File","description":"Download decrypted packet capture file for a scan.\nReturns compressed decrypted PCAP file with HTTP/HTTPS traffic in plaintext.","operationId":"get_pcap_file_api_v1_pcap__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pcap/{scan_id}/metadata":{"get":{"tags":["pcap"],"summary":"Get Pcap Metadata","description":"Get metadata about packet capture without downloading the file","operationId":"get_pcap_metadata_api_v1_pcap__scan_id__metadata_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/{domain}":{"get":{"tags":["certificates"],"summary":"Get Ct Certificates","description":"Get Certificate Transparency certificates for a domain\n\nReturns certificates with hash, timestamp, and CT log source","operationId":"get_ct_certificates_api_v1_ct__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/similar/{domain}":{"get":{"tags":["certificates"],"summary":"Find Similar Ct Domains","description":"Find similar domains in Certificate Transparency logs\n\nSearches for:\n- Wildcard subdomains\n- Domains containing the base domain\n- Fuzzy matches for potential typosquatting","operationId":"find_similar_ct_domains_api_v1_ct_similar__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/dns/{domain}":{"get":{"tags":["certificates"],"summary":"Get Ct Dns Records","description":"DNS observations for a domain and, by default, its subdomains.\n\nReturns `domain`, `dns_records[]` (domain / ip / record_type / timestamp / ttl /\nroot_domain), `ip_addresses`, `total_records`, plus `subdomains[]`,\n`subdomain_count`, `subdomains_unresolved[]`, `subdomains_unresolved_count` and\n`subdomains_truncated`.\n\n`subdomains` holds every hostname below the domain, `www` included, except those that were\nNXDOMAIN every time they were resolved. Those are in `subdomains_unresolved`: mostly retired\nor internal names, kept apart so `subdomains` lists names that existed in public DNS.\n\n`ip_addresses` covers the apex and www only; each subdomain's own IPs are in its\nrecord's `ip` field.\n\n⚠️ **A record's `ip` is frequently empty and that is meaningful, not missing data.** It\nmeans the hostname was published in a certificate but did not resolve when observed;\n`resolution_error` on the same record says why (e.g. `nxdomain`). For hkr.se that is 54\nof 100 records. Do not assume `ip` is populated — but do not discard those records\neither: a certificate hostname that no longer resolves is exactly the shape of dangling\nDNS.\n\n`dns_records` is capped at the 100 most recent observations. `subdomains` is capped at\n`subdomain_limit` (default 2000, max 5000) and `subdomains_truncated` tells you when the\ncap was reached, so a partial list is never mistaken for a complete one. Pass\n`include_subdomains=false` for apex-only results, which are much faster.\n\n## An empty `subdomains` has three meanings — `degraded` is how you tell them apart\n\n**CHECK `degraded` BEFORE YOU BELIEVE A ZERO.** Under load this endpoint sheds requests to\nprotect the upstream store, and a shed answers in milliseconds with every counter at zero.\nThat is not the domain having no subdomains; it is us not having looked.\n\n- `degraded: false`, `total_records: 0` — we looked and hold nothing for this domain. A\n  true zero. Roughly half of all real domains, because the CT corpus is a rolling ~91-day\n  window and a long-lived or wildcard certificate enumerates no individual hostname.\n- `degraded: false`, `total_records` > 0, `subdomain_count: 0` — also a true zero, and not\n  a bug: `subdomains` excludes the apex itself, and names that never resolved are in\n  `subdomains_unresolved`, so a domain with records only for those answers exactly this.\n- `degraded: true` — **we could not answer.** `degraded_reason` says why and `error`\n  says it in prose. Retry; do not record the zeros. `back_pressure` in particular means\n  the store was never even queried, and a retry moments later usually succeeds.\n\n## `stale: true` — a real answer, measured earlier\n\nWhen a re-look is shed, a previously-measured answer is served rather than nothing.\n`degraded` stays `false`, because the hostnames are genuine and the counters really were\nmeasured; `stale_age_seconds` says how long ago, and `stale_reason` why we could not\nre-look. Treat the list as valid but possibly short — it cannot contain anything first\nobserved since it was measured. Most callers should simply use it.\n\n`subdomains_truncated` does NOT cover this: it reports only whether `subdomain_limit` was\nreached, and it is `false` on a degraded response because no cap was involved.","operationId":"get_ct_dns_records_api_v1_ct_dns__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."},{"name":"include_subdomains","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Subdomains"}},{"name":"subdomain_limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Maximum distinct subdomains to return (1-5000).","default":2000,"title":"Subdomain Limit"},"description":"Maximum distinct subdomains to return (1-5000)."}],"responses":{"200":{"description":"DNS observations for the domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CtDnsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/ip/{ip}":{"get":{"tags":["certificates"],"summary":"Find Ct Domains On Ip","description":"Find all domains observed resolving to the same IP address.\n\nReturns `ip`, `domains[{domain, record_count}]` and `total`, ordered by how many\nDNS records back each domain.","operationId":"find_ct_domains_on_ip_api_v1_ct_ip__ip__get","parameters":[{"name":"ip","in":"path","required":true,"schema":{"type":"string","title":"Ip"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/ip/{ip}/domains":{"get":{"tags":["certificates"],"summary":"Find Ct Root Domains On Ip","description":"Registrable domains that resolved to an IP address when their TLS certificates were\nissued, grouped by registrable domain, alphabetical, cursor-paginated.\n\nEach row carries the hostnames seen under that domain, the number of resolution records,\nand when they were first and last observed. A domain that moved to this IP after its\ncertificate was issued is not listed.","operationId":"find_ct_root_domains_on_ip_api_v1_ct_ip__ip__domains_get","parameters":[{"name":"ip","in":"path","required":true,"schema":{"type":"string","title":"Ip"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":120,"minimum":1,"description":"Only observations from the last N days.","default":90,"title":"Days"},"description":"Only observations from the last N days."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Registrable domains per page.","default":100,"title":"Limit"},"description":"Registrable domains per page."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"description":"`next_cursor` from the previous page.","title":"Cursor"},"description":"`next_cursor` from the previous page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ct/timeline/{domain}":{"get":{"tags":["certificates"],"summary":"Get Ct Certificate Timeline","description":"Get certificate issuance timeline for a domain\n\nShows when certificates were issued over time","operationId":"get_ct_certificate_timeline_api_v1_ct_timeline__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","description":"Domain name (e.g. example.com), or an IP address.","title":"Domain"},"description":"Domain name (e.g. example.com), or an IP address."},{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":3650,"minimum":1},{"type":"null"}],"description":"Limit timeline to certificates seen in the last N days. Omit to return full history.","title":"Days"},"description":"Limit timeline to certificates seen in the last N days. Omit to return full history."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/report":{"post":{"tags":["reports"],"summary":"Submit Scan Report","description":"Submit a report about a scanned URL\n\nRate Limits:\n- Maximum {REPORT_RATE_LIMIT_PER_IP} reports per IP per hour\n- Maximum {REPORT_RATE_LIMIT_PER_SCAN} reports per scan\n\nReport types:\n- positive_feedback: Positive feedback (helpful/accurate scan)\n- phishing: Phishing website\n- spam: Spam or unwanted content\n- counterfeit: Selling counterfeit goods\n- scam: Scam website\n- broken_scan: Scan failed or incomplete\n- malware: Contains malware\n- illegal_content: Illegal content\n- copyright: Copyright violation\n- technical_issue: Technical issue with scan\n- other: Other issue (provide details)","operationId":"submit_scan_report_api_v1_report_post","parameters":[{"name":"User-Agent","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User-Agent"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Real-IP","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Real-Ip"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanReport"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/reports/{scan_id}":{"get":{"tags":["reports"],"summary":"Get Scan Reports","description":"Get reports for a specific scan (admin use)","operationId":"get_scan_reports_api_v1_reports__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"report_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by report type","title":"Report Type"},"description":"Filter by report type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/reports/{scan_id}/counts":{"get":{"tags":["reports"],"summary":"Get Scan Report Counts","description":"Get vote counts for a specific scan (public endpoint, cached for 60 seconds)","operationId":"get_scan_report_counts_api_v1_reports__scan_id__counts_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/stats":{"get":{"tags":["js-fingerprinter2"],"summary":"Get Js Fingerprinter2 Stats","description":"Get aggregate statistics for obfuscation detection across all scans.\n\nReturns:\n    Summary statistics including total scans analyzed, risk distribution, common patterns","operationId":"get_js_fingerprinter2_stats_api_v1_js_fingerprinter2_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/js-fingerprinter2/search/js-obfuscation":{"get":{"tags":["js-fingerprinter2"],"summary":"Search Js Obfuscation","description":"Search for scans with JavaScript obfuscation patterns.\n\nNOTE: This endpoint has been moved to /api/v1/search/js-obfuscation for consistency.\nPlease use the new endpoint instead.","operationId":"search_js_obfuscation_api_v1_js_fingerprinter2_search_js_obfuscation_get","deprecated":true,"parameters":[{"name":"risk_level","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by risk level: low, medium, high, critical","title":"Risk Level"},"description":"Filter by risk level: low, medium, high, critical"},{"name":"min_risk_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":0},{"type":"null"}],"description":"Minimum risk score","title":"Min Risk Score"},"description":"Minimum risk score"},{"name":"has_eval","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter scans with eval() calls","title":"Has Eval"},"description":"Filter scans with eval() calls"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/{scan_id}/scripts":{"get":{"tags":["js-fingerprinter2"],"summary":"Get Js Fingerprinter2 Per Script","description":"Get per-script behavioral fingerprint data from js_fingerprinter2.\n\nAggregates detailed_events by script URL to provide per-script summaries\nof eval calls, Function constructor usage, risk scores, and obfuscation patterns.\n\nReturns:\n    Dictionary keyed by script URL (or \"(inline)\") with behavioral summary per script.","operationId":"get_js_fingerprinter2_per_script_api_v1_js_fingerprinter2__scan_id__scripts_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/{scan_id}":{"get":{"tags":["js-fingerprinter2"],"summary":"Get Js Fingerprinter2 Results","description":"Get JavaScript obfuscation detection results for a specific scan.\n\nReturns:\n    Obfuscation analysis results including risk level, eval calls, and high-risk events\n\nNote: By default, detailed_events is excluded as it can be 10MB+ in size.\n      Use ?include_detailed_events=true to include it.","operationId":"get_js_fingerprinter2_results_api_v1_js_fingerprinter2__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"include_detailed_events","in":"query","required":false,"schema":{"type":"boolean","description":"Include detailed_events field (can be very large, 10MB+)","default":false,"title":"Include Detailed Events"},"description":"Include detailed_events field (can be very large, 10MB+)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search":{"get":{"tags":["search"],"summary":"Search Scans","description":"Search scans by URL, domain, title, or all fields using optimized queries with pagination. Only returns public scans.","operationId":"search_scans_api_v1_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":3,"description":"Search query (minimum 3 characters)","title":"Q"},"description":"Search query (minimum 3 characters)"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(url|domain|title|technology|yara|all)$"},{"type":"null"}],"description":"Search type","default":"all","title":"Type"},"description":"Search type"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/screenshot/search":{"post":{"tags":["search"],"summary":"Search Similar Screenshots","description":"Search for visually similar screenshots using perceptual hashing.\n\nReturns scans whose screenshot hash is within `max_distance` bits of the one given,\nclosest first. `hash_type` is one of phash, ahash, dhash, whash.\n\n⚠️ THIS RETURNED [] FOR EVERY INPUT until 2026-08-29, and the cause is worth keeping\nwritten down. It read the BARE `screenshot_hashes->>'<type>' key and did\n`int(stored, 16)`. That key holds a 64-character BIT STRING on 91.6% of rows (see\nutils/screenshot_hash.py), and 64 binary digits parsed as hex is a 256-BIT number, so\nthe XOR against a 64-bit input always exceeded max_distance. The 8.4% of rows that do\nstore hex were only reachable inside the newest 10,000 scans, which the old query\ncapped itself to. Reported by the MISP maintainers.\n\nThe comparison now runs in SQL over the whole public corpus (~1.4s), reading the hash\nthrough the canonical accessor rather than the ambiguous bare key.","operationId":"search_similar_screenshots_api_v1_screenshot_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageSearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ImageSimilarityResponse"},"type":"array","title":"Response Search Similar Screenshots Api V1 Screenshot Search Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/screenshot/{hash_type}/{hash_value}":{"get":{"tags":["search"],"summary":"Search By Screenshot Hash","description":"Search for scans by screenshot hash with pagination\nSupports exact match and similarity search for perceptual hashes\nReturns scan IDs that match the given screenshot hash\nOnly returns public scans","operationId":"search_by_screenshot_hash_api_v1_search_screenshot__hash_type___hash_value__get","parameters":[{"name":"hash_type","in":"path","required":true,"schema":{"type":"string","pattern":"^(ahash|phash|dhash|whash|color_hash|crop_resistant)$","title":"Hash Type"}},{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","maxLength":512,"pattern":"^[#a-fA-F0-9,]+$","description":"Hash value to search. # allowed for color hashes; commas allowed for multi-segment hashes (crop_resistant produces 3-12 comma-joined 16-char chunks)","title":"Hash Value"},"description":"Hash value to search. # allowed for color hashes; commas allowed for multi-segment hashes (crop_resistant produces 3-12 comma-joined 16-char chunks)"},{"name":"similarity_threshold","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":64,"minimum":0},{"type":"null"}],"description":"Hamming distance threshold for similarity search (perceptual hashes only)","title":"Similarity Threshold"},"description":"Hamming distance threshold for similarity search (perceptual hashes only)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/fuzzy/{hash_type}":{"get":{"tags":["search"],"summary":"Search By Fuzzy Hash","description":"Search for scans by fuzzy hash (TLSH, ssdeep, or sdhash). Only returns public scans.","operationId":"search_by_fuzzy_hash_api_v1_search_fuzzy__hash_type__get","parameters":[{"name":"hash_type","in":"path","required":true,"schema":{"type":"string","pattern":"^(tlsh|ssdeep|sdhash)$","description":"Hash type to search","title":"Hash Type"},"description":"Hash type to search"},{"name":"hash_value","in":"query","required":true,"schema":{"type":"string","minLength":10,"description":"Hash value to search","title":"Hash Value"},"description":"Hash value to search"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/ip/{ip_address}":{"get":{"tags":["search"],"summary":"Search By Ip","description":"Search for scans containing a specific IP address. Only returns public scans.","operationId":"search_by_ip_api_v1_search_ip__ip_address__get","parameters":[{"name":"ip_address","in":"path","required":true,"schema":{"type":"string","description":"IP address to search for","title":"Ip Address"},"description":"IP address to search for"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/ip/{ip_address}/stats":{"get":{"tags":["search"],"summary":"Get Ip Stats","description":"Get detailed statistics and enrichment data for an IP address","operationId":"get_ip_stats_api_v1_search_ip__ip_address__stats_get","parameters":[{"name":"ip_address","in":"path","required":true,"schema":{"type":"string","description":"IP address to get statistics for","title":"Ip Address"},"description":"IP address to get statistics for"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/asn/{asn_number}":{"get":{"tags":["search"],"summary":"Search By Asn","description":"Search for scans by AS number - uses indexed ASN columns for fast lookup with pagination","operationId":"search_by_asn_api_v1_search_asn__asn_number__get","parameters":[{"name":"asn_number","in":"path","required":true,"schema":{"type":"integer","description":"AS number to search for","title":"Asn Number"},"description":"AS number to search for"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/similar":{"get":{"tags":["search"],"summary":"Search Similar Scans","description":"Find scans similar to a given scan using multiple hash methods with pagination.\nCombines results from screenshot, favicon, and fuzzy hash matching.\nOnly returns public scans.","operationId":"search_similar_scans_api_v1_search_similar_get","parameters":[{"name":"scan_id","in":"query","required":true,"schema":{"type":"string","description":"Base scan ID to find similar scans for","title":"Scan Id"},"description":"Base scan ID to find similar scans for"},{"name":"methods","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Methods to use for similarity: screenshot, favicon, fuzzy","default":["screenshot"],"title":"Methods"},"description":"Methods to use for similarity: screenshot, favicon, fuzzy"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analyzers/search/high-risk":{"get":{"tags":["search"],"summary":"Search Analyzer High Risk Scans","description":"Search for scans with high risk scores from security analyzer.\n\n`min_risk_score` is on the rule engine's **0-100** scale. The AI equivalent,\n`/api/v1/ai/search/high-risk`, uses a **0-10** scale.","operationId":"search_analyzer_high_risk_scans_api_v1_analyzers_search_high_risk_get","parameters":[{"name":"min_risk_score","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum rule-engine risk score, on a 0-100 scale (security_verdict.overall_score). NOTE: /api/v1/ai/search/high-risk takes a min_risk_score on a 0-10 scale instead -- the two engines score on different scales and the parameter is not interchangeable.","default":50,"title":"Min Risk Score"},"description":"Minimum rule-engine risk score, on a 0-100 scale (security_verdict.overall_score). NOTE: /api/v1/ai/search/high-risk takes a min_risk_score on a 0-10 scale instead -- the two engines score on different scales and the parameter is not interchangeable."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/search/classification":{"get":{"tags":["search"],"summary":"Search By Classification","description":"Search scans by AI classification.","operationId":"search_by_classification_api_v1_ai_search_classification_get","parameters":[{"name":"classification","in":"query","required":true,"schema":{"type":"string","pattern":"^(LEGITIMATE|LOW_RISK|MODERATE_RISK|HIGH_RISK|CONFIRMED_SCAM)$","title":"Classification"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/search/high-risk":{"get":{"tags":["search"],"summary":"Search Ai High Risk Scans","description":"Search for high-risk scans with configurable thresholds.\n\nScale caveat: `min_risk_score` here is on the AI engine's **0-10** scale,\nwhile the rule-engine endpoint `/api/v1/analyzers/search/high-risk` takes\n**0-100**. `min_confidence` is a **0-100** percentage on this endpoint.","operationId":"search_ai_high_risk_scans_api_v1_ai_search_high_risk_get","parameters":[{"name":"min_risk_score","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":0,"description":"Minimum AI risk score, on a 0-10 scale (analysis.risk_score). NOTE: /api/v1/analyzers/search/high-risk takes a min_risk_score on a 0-100 scale instead -- the two engines score on different scales and the parameter is not interchangeable.","default":7,"title":"Min Risk Score"},"description":"Minimum AI risk score, on a 0-10 scale (analysis.risk_score). NOTE: /api/v1/analyzers/search/high-risk takes a min_risk_score on a 0-100 scale instead -- the two engines score on different scales and the parameter is not interchangeable."},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum AI confidence, as a 0-100 percentage (analysis.confidence_percentage). Unlike min_risk_score this one really is a percentage, so 70 means 70%.","default":70,"title":"Min Confidence"},"description":"Minimum AI confidence, as a 0-100 percentage (analysis.confidence_percentage). Unlike min_risk_score this one really is a percentage, so 70 means 70%."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum results","default":100,"title":"Limit"},"description":"Maximum results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/semantic":{"get":{"tags":["search"],"summary":"Semantic Search","description":"Search for websites using natural language descriptions, matched against screenshots.\nExamples: \"login page\", \"e-commerce checkout\", \"news website\", \"social media feed\"","operationId":"semantic_search_api_v1_search_semantic_get","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","description":"Natural language query to search for visually similar websites","title":"Query"},"description":"Natural language query to search for visually similar websites"},{"name":"threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":-1.0,"description":"Similarity threshold (-1 to 1, higher = more similar). Similarity is 1 - L2 distance between the text and image embeddings; text-to-image scores typically fall between -0.4 and 0.1, so useful thresholds are around -0.3 to 0.","default":-0.2,"title":"Threshold"},"description":"Similarity threshold (-1 to 1, higher = more similar). Similarity is 1 - L2 distance between the text and image embeddings; text-to-image scores typically fall between -0.4 and 0.1, so useful thresholds are around -0.3 to 0."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":20,"title":"Limit"},"description":"Results per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/similar/visual/{scan_id}":{"get":{"tags":["search"],"summary":"Visual Similar Scans","description":"Find public scans whose screenshot looks like this scan's.\n\n404 when the scan does not exist, is not public, or has no image embedding yet.\nThe base scan is never returned as its own neighbour.","operationId":"visual_similar_scans_api_v1_similar_visual__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":-1.0,"description":"Similarity threshold (-1 to 1). Similarity is 1 - L2 distance between the two screenshots' image embeddings: identical renders score 1.0 and unrelated pages about 0.0.","default":-0.2,"title":"Threshold"},"description":"Similarity threshold (-1 to 1). Similarity is 1 - L2 distance between the two screenshots' image embeddings: identical renders score 1.0 and unrelated pages about 0.0."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum similar scans to return","default":20,"title":"Limit"},"description":"Maximum similar scans to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ids/alerts/{scan_id}":{"get":{"tags":["ids"],"summary":"Get Ids Alerts","description":"Get network intrusion detection alerts for a specific scan","operationId":"get_ids_alerts_api_v1_ids_alerts__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Ids Alerts Api V1 Ids Alerts  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analyzers/{scan_id}":{"get":{"tags":["analyzers"],"summary":"Get Analyzer Results","description":"Get analyzer results for a specific scan","operationId":"get_analyzer_results_api_v1_analyzers__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Analyzer Results Api V1 Analyzers  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analyzers/stats/overview":{"get":{"tags":["analyzers"],"summary":"Get Analyzer Statistics","description":"Get overall analyzer statistics","operationId":"get_analyzer_statistics_api_v1_analyzers_stats_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Analyzer Statistics Api V1 Analyzers Stats Overview Get"}}}}}}},"/api/v1/cpe/stats":{"get":{"tags":["cpe"],"summary":"Get Cpe Stats","description":"Get statistics about CPE detections from public scans only.","operationId":"get_cpe_stats_api_v1_cpe_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Cpe Stats Api V1 Cpe Stats Get"}}}}}}},"/api/v1/cpe/{scan_id}":{"get":{"tags":["cpe"],"summary":"Get Scan Cpes","description":"Get CPE identifiers extracted from a specific scan.","operationId":"get_scan_cpes_api_v1_cpe__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Get Scan Cpes Api V1 Cpe  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cpe/search/{cpe_pattern}":{"get":{"tags":["cpe"],"summary":"Search Cpe","description":"Search for scans containing specific CPE patterns or technology names with pagination.\n\nMatches both full CPE strings and plain technology names (e.g. 'nginx', 'cowboy').","operationId":"search_cpe_api_v1_cpe_search__cpe_pattern__get","parameters":[{"name":"cpe_pattern","in":"path","required":true,"schema":{"type":"string","title":"Cpe Pattern"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search Cpe Api V1 Cpe Search  Cpe Pattern  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/safe-browsing/stats":{"get":{"tags":["safe-browsing"],"summary":"Get Safe Browsing Stats","description":"Get statistics about Google Safe Browsing detections.","operationId":"get_safe_browsing_stats_api_v1_safe_browsing_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Safe Browsing Stats Api V1 Safe Browsing Stats Get"}}}}}}},"/api/v1/safe-browsing/{scan_id}":{"get":{"tags":["safe-browsing"],"summary":"Get Safe Browsing Threats","description":"Get Google Safe Browsing threats for a specific scan.","operationId":"get_safe_browsing_threats_api_v1_safe_browsing__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Safe Browsing Threats Api V1 Safe Browsing  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/stats":{"get":{"tags":["ai"],"summary":"Get Ai Stats","description":"Get statistics about AI analysis results.","operationId":"get_ai_stats_api_v1_ai_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Ai Stats Api V1 Ai Stats Get"}}}}}}},"/api/v1/ai/{scan_id}":{"get":{"tags":["ai"],"summary":"Get Ai Analysis","description":"Get AI-powered scam analysis results for a specific scan.","operationId":"get_ai_analysis_api_v1_ai__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Ai Analysis Api V1 Ai  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/search/scam-type":{"get":{"tags":["ai"],"summary":"Search By Scam Type","description":"Search scans by detected scam type.","operationId":"search_by_scam_type_api_v1_ai_search_scam_type_get","parameters":[{"name":"scam_type","in":"query","required":true,"schema":{"type":"string","description":"Scam type to search for","title":"Scam Type"},"description":"Scam type to search for"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search By Scam Type Api V1 Ai Search Scam Type Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scan/{scan_id}/summary":{"get":{"tags":["scan-summary"],"summary":"Get Scan Summary","description":"Get condensed scan summary for integrations","operationId":"get_scan_summary_api_v1_scan__scan_id__summary_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Scan Summary Api V1 Scan  Scan Id  Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/screenshot/duplicates":{"get":{"tags":["screenshot"],"summary":"Find Duplicate Screenshots","description":"Find groups of similar screenshots (potential duplicates) with pagination.\n\nFor performance reasons, only exact matches (max_distance=0) are supported\nvia efficient SQL GROUP BY. This avoids O(n²) comparisons across 100K+ screenshots.\n\nUse /api/v1/search/screenshot/phash/{hash} for fuzzy matching of a specific hash.","operationId":"find_duplicate_screenshots_api_v1_screenshot_duplicates_get","parameters":[{"name":"hash_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(phash|ahash|dhash|whash|crop_resistant)$","default":"phash","title":"Hash Type"}},{"name":"max_distance","in":"query","required":false,"schema":{"type":"integer","maximum":0,"minimum":0,"description":"Exact matches only — 0 is the only accepted value. Grouping the whole corpus by approximate hash is an O(n^2) comparison across 500K+ screenshots and is not implemented. To find screenshots SIMILAR to one specific hash, use GET /api/v1/search/screenshot/{hash_type}/{hash} with its `similarity_threshold` parameter (0-64 bits), which is a linear scan and takes ~1.4s. The bound used to advertise 0-5 while the handler rejected everything above 0, so a spec-generated client emitted requests that could never succeed.","default":0,"title":"Max Distance"},"description":"Exact matches only — 0 is the only accepted value. Grouping the whole corpus by approximate hash is an O(n^2) comparison across 500K+ screenshots and is not implemented. To find screenshots SIMILAR to one specific hash, use GET /api/v1/search/screenshot/{hash_type}/{hash} with its `similarity_threshold` parameter (0-64 bits), which is a linear scan and takes ~1.4s. The bound used to advertise 0-5 while the handler rejected everything above 0, so a spec-generated client emitted requests that could never succeed."},{"name":"min_group_size","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":2,"default":2,"title":"Min Group Size"}},{"name":"max_group_members","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum scans returned per duplicate group. Groups of exact screenshot matches are routinely in the thousands (the largest on record holds ~9,000 identical hosting placeholder pages), so this is capped independently of `limit`, which counts GROUPS. Each member carries the group's true size in `group_size`.","default":10,"title":"Max Group Members"},"description":"Maximum scans returned per duplicate group. Groups of exact screenshot matches are routinely in the thousands (the largest on record holds ~9,000 identical hosting placeholder pages), so this is capped independently of `limit`, which counts GROUPS. Each member carries the group's true size in `group_size`."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of GROUPS per page","default":20,"title":"Limit"},"description":"Number of GROUPS per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/screenshot/stats":{"get":{"tags":["screenshot"],"summary":"Get Screenshot Stats","description":"Get statistics about screenshot hashes in the database","operationId":"get_screenshot_stats_api_v1_screenshot_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/screenshot/{scan_id}":{"get":{"tags":["screenshot"],"summary":"Get Screenshot","description":"Get scan screenshot with optional resizing and format conversion","operationId":"get_screenshot_api_v1_screenshot__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2000,"minimum":50},{"type":"null"}],"description":"Resize width (maintains aspect ratio)","title":"Width"},"description":"Resize width (maintains aspect ratio)"},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2000,"minimum":50},{"type":"null"}],"description":"Resize height (maintains aspect ratio)","title":"Height"},"description":"Resize height (maintains aspect ratio)"},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(png|webp)$","description":"Output format: png or webp","default":"png","title":"Format"},"description":"Output format: png or webp"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["screenshot"],"summary":"Get Screenshot","description":"Get scan screenshot with optional resizing and format conversion","operationId":"get_screenshot_api_v1_screenshot__scan_id__head","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2000,"minimum":50},{"type":"null"}],"description":"Resize width (maintains aspect ratio)","title":"Width"},"description":"Resize width (maintains aspect ratio)"},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2000,"minimum":50},{"type":"null"}],"description":"Resize height (maintains aspect ratio)","title":"Height"},"description":"Resize height (maintains aspect ratio)"},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(png|webp)$","description":"Output format: png or webp","default":"png","title":"Format"},"description":"Output format: png or webp"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/rdap/{scan_id}":{"get":{"summary":"Get Rdap Info","description":"Get RDAP/WHOIS domain registration information for a scan\n\nReturns domain age, registration date, and other RDAP data\nwith proper security validation.\n\nArgs:\n    scan_id: UUID of the scan\n\nReturns:\n    RDAPResponse: Domain registration information\n\nRaises:\n    HTTPException: If scan_id is invalid or scan not found","operationId":"get_rdap_info_api_v1_rdap__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RDAPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ns/{nameserver}":{"get":{"summary":"Search By Nameserver","description":"Search for all registered domains using a specific nameserver.\n\nCombines a primary domain dataset (covering the TLDs listed in `tld_coverage`)\nwith a supplementary dataset of domains ScanMalware has scanned. If the primary\nsource returns fewer than 10 domains, the supplementary source is queried and\nunique domains are merged in.\n\nArgs:\n    nameserver: Nameserver to search for (e.g., \"ns1.example.com\")\n    limit: Maximum results to return (default: 20, max: 1000)\n    offset: Pagination offset (default: 0)\n\nReturns:\n    JSON with domains, metadata, and query stats. When supplementary data\n    is merged, extra fields indicate how many domains were added.\n\nRaises:\n    HTTPException: If both data sources fail","operationId":"search_by_nameserver_api_v1_ns__nameserver__get","parameters":[{"name":"nameserver","in":"path","required":true,"schema":{"type":"string","title":"Nameserver"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"tld","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":63},{"type":"null"}],"description":"Only domains under this TLD, e.g. `se`. Must be one of `tld_coverage`.","title":"Tld"},"description":"Only domains under this TLD, e.g. `se`. Must be one of `tld_coverage`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ioc/{scan_id}":{"get":{"summary":"Get Ioc Matches","description":"Get IoC (Indicators of Compromise) threat intelligence matches for a scan\n\nReturns all matched malicious indicators (IPs and domains) that were found\nin the threat intelligence database.\n\nArgs:\n    scan_id: UUID of the scan\n\nReturns:\n    JSON with IoC matches, summary, and metadata\n\nRaises:\n    HTTPException: If scan_id is invalid or scan not found","operationId":"get_ioc_matches_api_v1_ioc__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scan":{"post":{"summary":"Submit Scan","description":"Submit a URL for scanning with URL validation and optional CSRF protection.\n\nSupports flexible URL input formats:\n- Full URLs: https://example.com, http://example.com\n- Domain only: example.com (will try https://, https://www., http://, http://www.)\n- With path: example.com/page (will prepend protocol)","operationId":"submit_scan_api_v1_scan_post","security":[{"OptionalHTTPBearer":[]}],"parameters":[{"name":"x-csrf-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Csrf-Token"}},{"name":"User-Agent","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User-Agent"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/load-time-distribution":{"get":{"summary":"Get Load Time Distribution Stats","description":"Public corpus distribution of page-load times (the basis for the result-page\n\"Very Fast/Fast/Medium/Slow\" badge).","operationId":"get_load_time_distribution_stats_api_v1_stats_load_time_distribution_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/result/{scan_id}":{"get":{"summary":"Get Scan Result","description":"Get scan result by ID","operationId":"get_scan_result_api_v1_result__scan_id__get","security":[{"OptionalHTTPBearer":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jarm/scan/{scan_id}":{"get":{"tags":["jarm"],"summary":"Get Jarm Signatures","description":"Get all JARM signatures and analysis attempts for a specific scan.\n\nReturns:\n- JARM TLS fingerprints for successful analyses\n- Failure information for hosts where JARM could not be generated","operationId":"get_jarm_signatures_api_v1_jarm_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Jarm Signatures Api V1 Jarm Scan  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jarm/stats":{"get":{"tags":["jarm"],"summary":"Get Jarm Stats","description":"Get statistics about JARM signatures in the database.\n\nReturns counts of unique signatures, scans, hosts, and the most common signatures.","operationId":"get_jarm_stats_api_v1_jarm_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Jarm Stats Api V1 Jarm Stats Get"}}}}}}},"/api/v1/search/jarm/{jarm_signature}":{"get":{"tags":["jarm"],"summary":"Search By Jarm","description":"Search for scans by JARM TLS fingerprint with pagination.\n\nJARM fingerprints are 62-character hashes that identify TLS server configurations.\nThis can help identify servers running the same software or configuration.","operationId":"search_by_jarm_api_v1_search_jarm__jarm_signature__get","parameters":[{"name":"jarm_signature","in":"path","required":true,"schema":{"type":"string","description":"JARM TLS fingerprint (62-character hex string)","title":"Jarm Signature"},"description":"JARM TLS fingerprint (62-character hex string)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search By Jarm Api V1 Search Jarm  Jarm Signature  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/rpki/{scan_id}":{"get":{"tags":["rpki"],"summary":"Get Rpki Validation","description":"Get RPKI validation results for a scan.\n\nReturns validation status (valid/invalid/not-found) for each\nserver IP address, with ASN, covering prefix, and risk contribution.","operationId":"get_rpki_validation_api_v1_rpki__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Rpki Validation Api V1 Rpki  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/malware/threats/recent":{"get":{"tags":["malware"],"summary":"Get Recent Threats","description":"Get recently detected threats across all scans.\n\nReturns recent malware detections sorted by time, useful for\nthreat monitoring and security intelligence.","operationId":"get_recent_threats_api_v1_malware_threats_recent_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"description":"Hours to look back","default":24,"title":"Hours"},"description":"Hours to look back"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum results","default":100,"title":"Limit"},"description":"Maximum results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Recent Threats Api V1 Malware Threats Recent Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/malware/stats":{"get":{"tags":["malware"],"summary":"Get Malware Statistics","description":"Get overall malware scanning statistics.\n\nReturns aggregated statistics about antivirus scans including\ntotal resources scanned, threats detected, and trends.","operationId":"get_malware_statistics_api_v1_malware_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Malware Statistics Api V1 Malware Stats Get"}}}}}}},"/api/v1/malware/{scan_id}":{"get":{"tags":["malware"],"summary":"Get Malware Scan Results","description":"Get malware scan results for a specific scan.\n\nReturns all antivirus malware detections including threat names,\ncontent types, and file hashes.","operationId":"get_malware_scan_results_api_v1_malware__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Malware Scan Results Api V1 Malware  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/yara/stats":{"get":{"tags":["yara"],"summary":"Get Yara Stats","description":"Get overall YARA malware detection statistics.\n\nReturns aggregated statistics about YARA rule matches, including:\n- Total detections and unique patterns\n- Severity distribution\n- Most common threat categories\n- Detection trends over time","operationId":"get_yara_stats_api_v1_yara_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Yara Stats Api V1 Yara Stats Get"}}}}}}},"/api/v1/yara/threats/recent":{"get":{"tags":["yara"],"summary":"Get Recent Yara Threats","description":"Get recently detected YARA threats across all scans.\n\nReturns recent malware pattern matches sorted by detection time,\nuseful for threat monitoring and security intelligence.","operationId":"get_recent_yara_threats_api_v1_yara_threats_recent_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"description":"Hours to look back","default":24,"title":"Hours"},"description":"Hours to look back"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum results","default":100,"title":"Limit"},"description":"Maximum results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Recent Yara Threats Api V1 Yara Threats Recent Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/yara/scan/{scan_id}":{"get":{"tags":["yara"],"summary":"Get Yara Matches By Scan","description":"Get YARA malware pattern matches for a specific scan.\n\nReturns all community YARA rules that matched during JavaScript analysis,\nincluding rule metadata, severity, matched strings, and threat intelligence.","operationId":"get_yara_matches_by_scan_api_v1_yara_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Yara Matches By Scan Api V1 Yara Scan  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/yara/{scan_id}":{"get":{"tags":["yara"],"summary":"Get Yara Matches","description":"Get YARA malware pattern matches for a specific scan (legacy endpoint).\n\nThis is an alias for /scan/{scan_id} for backward compatibility.","operationId":"get_yara_matches_api_v1_yara__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Yara Matches Api V1 Yara  Scan Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tracking-keys/stats/top":{"get":{"tags":["tracking"],"summary":"Get Top Trackers","description":"Get top tracking keys by usage","operationId":"get_top_trackers_api_v1_tracking_keys_stats_top_get","parameters":[{"name":"tracker_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tracker type","title":"Tracker Type"},"description":"Filter by tracker type"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of results","default":20,"title":"Limit"},"description":"Number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tracking-keys/by-scan/{scan_id}":{"get":{"tags":["tracking"],"summary":"Get Scan Tracking Keys","description":"Get all tracking keys for a specific scan with usage statistics","operationId":"get_scan_tracking_keys_api_v1_tracking_keys_by_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tracking-keys/{tracker_type}/{key}":{"get":{"tags":["tracking"],"summary":"Search By Tracking Key","description":"Find all scans using a specific tracking key","operationId":"search_by_tracking_key_api_v1_tracking_keys__tracker_type___key__get","parameters":[{"name":"tracker_type","in":"path","required":true,"schema":{"type":"string","description":"Tracker type (google_analytics, facebook_pixel, etc.)","title":"Tracker Type"},"description":"Tracker type (google_analytics, facebook_pixel, etc.)"},{"name":"key","in":"path","required":true,"schema":{"type":"string","description":"Tracking key/ID","title":"Key"},"description":"Tracking key/ID"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":20,"title":"Limit"},"description":"Results per page"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(latest|oldest)$","description":"Sort order","default":"latest","title":"Sort"},"description":"Sort order"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registrar/search/{registrar_name}":{"get":{"tags":["registrar"],"summary":"Search By Registrar","description":"Search for scans by registrar name with fuzzy ILIKE matching.","operationId":"search_by_registrar_api_v1_registrar_search__registrar_name__get","parameters":[{"name":"registrar_name","in":"path","required":true,"schema":{"type":"string","title":"Registrar Name"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrarSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/segments/by-scan/{scan_id}/security":{"get":{"tags":["segments"],"summary":"Get Scan Segments Security","description":"Security analysis for every segment of one scan, in a single request.\n\nPrefer this over calling /segments/{id}/security once per segment: it returns the same\ninformation for the whole scan and is dramatically cheaper on both sides.","operationId":"get_scan_segments_security_api_v1_segments_by_scan__scan_id__security_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/segments/{segment_id}/security":{"get":{"tags":["segments"],"summary":"Get Segment Security","description":"Get security analysis for a specific JavaScript segment.\n\nReturns malware pattern matches, risk assessment, and threat intelligence\nfor the given segment ID.\n\n⚠️ For every segment of a scan, use /api/v1/segments/by-scan/{scan_id}/security\ninstead — one request rather than one per segment, and far cheaper to serve.\n\nArgs:\n    segment_id: The unique segment identifier\n\nReturns:\n    Security analysis including:\n    - Malware pattern matches (YARA, custom patterns)\n    - Risk score and severity\n    - Pattern descriptions and recommendations\n    - Threat categories","operationId":"get_segment_security_api_v1_segments__segment_id__security_get","parameters":[{"name":"segment_id","in":"path","required":true,"schema":{"type":"integer","description":"JavaScript segment ID","title":"Segment Id"},"description":"JavaScript segment ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/segments/{segment_id}":{"get":{"tags":["segments"],"summary":"Get Segment","description":"Get basic information about a JavaScript segment.\n\nArgs:\n    segment_id: The unique segment identifier\n\nReturns:\n    Segment metadata including script URL, function name, code length, etc.","operationId":"get_segment_api_v1_segments__segment_id__get","parameters":[{"name":"segment_id","in":"path","required":true,"schema":{"type":"integer","description":"JavaScript segment ID","title":"Segment Id"},"description":"JavaScript segment ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/smql":{"get":{"tags":["smql"],"summary":"Smql Search","description":"Search scans using the ScanMalware Query Language (SMQL).\n\nSyntax examples:\n- Simple text: `paypal login`\n- Filters: `domain:paypal.com`, `country:RU`, `technology:WordPress`\n- Boolean: `technology:WordPress AND country:RU`\n- Negation: `-domain:google.com` or `NOT domain:google.com`\n- Grouping: `(technology:WordPress OR technology:Joomla) AND country:CN`\n- Several values of one field: `domain:(paypal.com OR paypal.me)`, `ip:(1.1.1.1 8.8.8.8)`\n  (values without an operator are ORed), `technology:(WordPress AND WooCommerce)`\n- Defanged indicators are accepted: `domain:paypal[.]com`, `hxxps://evil[.]com/login`;\n  `notes` in the response shows how each was read\n- Ranges: `js_risk_score:60..100`, `submitted:last7d`\n- Existence: `has:malware`, `has:pastejacking`\n- CT-backed: `ct_domain:example.com`, `ct_hash:<sha1>`,\n  `ct_domain:example.com AND ct_issued:>2024-01-01` — resolved against Certificate\n  Transparency data into a domain set (capped at 1000; cannot be negated).\n  `ct_issued` must be combined with `ct_domain`, `ct_san` or `ct_hash`. Wildcard\n  CT domains such as `ct_domain:*.paypal.com` are slower and can return 503 while\n  the CT service is busy.","operationId":"smql_search_api_v1_search_smql_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2000,"description":"SMQL query string","title":"Q"},"description":"SMQL query string"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":20,"title":"Limit"},"description":"Results per page"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Sort order: newest, oldest, url, load_time, ip_count","default":"newest","title":"Sort"},"description":"Sort order: newest, oldest, url, load_time, ip_count"},{"name":"count_only","in":"query","required":false,"schema":{"type":"boolean","description":"Return only the number of matching scans, without results. Faster when only the count is needed.","default":false,"title":"Count Only"},"description":"Return only the number of matching scans, without results. Faster when only the count is needed."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/smql/facets":{"get":{"tags":["smql"],"summary":"Smql Facets","description":"What the scans matching an SMQL query have in common: the most frequent hosting networks,\ncountries, domains, registrars, certificate issuers, technologies, favicons, JARM\nfingerprints, tracking IDs and AI verdicts.\n\nCounts are taken over the newest `sample` matching scans, not every match; `sample` in the\nresponse gives the number aggregated and their date span. Each value carries `query`, the\nSMQL filter that finds those scans, ready to AND onto the original query. A filter can match\nmore scans than its count (`registrar:` also matches third-party domains a page loaded).","operationId":"smql_facets_api_v1_search_smql_facets_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2000,"description":"SMQL query string","title":"Q"},"description":"SMQL query string"},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"description":"Comma-separated facet names (see `available` in any response); a default set when omitted","title":"Fields"},"description":"Comma-separated facet names (see `available` in any response); a default set when omitted"},{"name":"size","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"description":"Values per facet","default":10,"title":"Size"},"description":"Values per facet"},{"name":"sample","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":100,"description":"How many of the newest matching scans to aggregate","default":1000,"title":"Sample"},"description":"How many of the newest matching scans to aggregate"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/smql/domains":{"get":{"tags":["smql"],"summary":"Smql Domain Search","description":"Search DOMAINS rather than scans: lists every matching domain, including domains\nScanMalware has never scanned, each annotated with its newest public scan if one exists.\n\nFilters (see `filters` in any response):\n- `ct_ip:158.94.209.214` or `ct_ip:158.94.209.0/24`: domains seen on the address when their\n  certificates were issued. Not re-checked, so domains that moved there later are missing.\n- `nameserver:ns1.example.com`: registered domains delegated to a nameserver (`coverage` lists\n  the TLDs covered). Exact name only. Add `AND tld:se` for one TLD.\n- `ct_domain:*ledger-live*`, `ct_san:...`, optionally `AND ct_issued:last7d`: hostnames in\n  certificate logs (wildcards search the last 30 days, exact names the last 90).","operationId":"smql_domain_search_api_v1_search_smql_domains_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2000,"description":"SMQL query using domain filters","title":"Q"},"description":"SMQL query using domain filters"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Domains per page","default":100,"title":"Limit"},"description":"Domains per page"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"description":"`next_cursor` from the previous page","title":"Cursor"},"description":"`next_cursor` from the previous page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/smql/stats":{"get":{"tags":["smql"],"summary":"Smql Stats","description":"Return estimated total public scan count (from pg_class, essentially free).","operationId":"smql_stats_api_v1_search_smql_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/search/smql/filters":{"get":{"tags":["smql"],"summary":"Smql Filters","description":"Return all available SMQL filters grouped by category.","operationId":"smql_filters_api_v1_search_smql_filters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/account/overview":{"get":{"tags":["account"],"summary":"Account Overview","description":"Headline stats for the account dashboard.","operationId":"account_overview_api_v1_account_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/scans":{"get":{"tags":["account"],"summary":"Account Scans","description":"The authenticated user's submitted scans, newest first.","operationId":"account_scans_api_v1_account_scans_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/logins":{"get":{"tags":["account"],"summary":"Account Logins","description":"Recent sign-in events for the authenticated user.","operationId":"account_logins_api_v1_account_logins_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/security":{"get":{"tags":["account"],"summary":"Account Security","description":"Sign-in methods on the account: password, passkeys and two-factor authentication,\neach with the action that sets it up or changes it and whether it can be removed.","operationId":"account_security_api_v1_account_security_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/sessions":{"get":{"tags":["account"],"summary":"Account Sessions","description":"Where the account is signed in: one entry per session, the current one flagged.","operationId":"account_sessions_api_v1_account_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/sessions/others":{"delete":{"tags":["account"],"summary":"Sign Out Other Sessions","description":"Sign out every session of the account except the one making this request.","operationId":"sign_out_other_sessions_api_v1_account_sessions_others_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/sessions/{session_id}":{"delete":{"tags":["account"],"summary":"Sign Out Session","description":"Sign out one session of the account.","operationId":"sign_out_session_api_v1_account_sessions__session_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/api-keys":{"get":{"tags":["account"],"summary":"List Api Keys","description":"List the authenticated user's non-revoked API keys (expired ones are\nflagged so users can review and clean them up).","operationId":"list_api_keys_api_v1_account_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["account"],"summary":"Create Api Key","description":"Create a new personal access token. The full token is returned ONCE in\nthis response; only the SHA-256 hash of its secret part is stored.","operationId":"create_api_key_api_v1_account_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/api-keys/revoke-all":{"post":{"tags":["account"],"summary":"Revoke All Api Keys","description":"Emergency revocation of ALL of the authenticated user's API keys.","operationId":"revoke_all_api_keys_api_v1_account_api_keys_revoke_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/api-keys/audit":{"get":{"tags":["account"],"summary":"Api Key Audit Trail","description":"The authenticated user's API key audit trail (newest first).","operationId":"api_key_audit_trail_api_v1_account_api_keys_audit_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/api-keys/{key_id}":{"delete":{"tags":["account"],"summary":"Revoke Api Key","description":"Revoke (soft-delete) one of the authenticated user's API keys.","operationId":"revoke_api_key_api_v1_account_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scans/{scan_id}/web-features":{"get":{"tags":["web-features"],"summary":"Get Scan Web Features","description":"Browser features and web APIs the page used while it loaded, as counted by the browser.\n\n`recorded: false` means no features were recorded for this scan (scans from before this\nexisted), so an empty list is unknown rather than \"none\". `interstitial` is set when the\nbrowser was shown something other than the site (`provider_warning`, `challenge`, `block`,\n`error_page`, `placeholder`): the features then belong to that page. Each feature's `name` is\nthe value for an SMQL `js_feature:` search.","operationId":"get_scan_web_features_api_v1_scans__scan_id__web_features_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scans/{scan_id}/pivot-values":{"get":{"tags":["scans"],"summary":"Get Scan Pivot Values","description":"Values of a scan that can be searched but are not part of the main result.\n\n- `resources`: SHA-256 of each response body the page loaded (HTML, scripts, stylesheets,\n  fonts and similar), with its file name, content type, and whether it is the page's own\n  HTML document. Search with `resource_sha256:`.\n- `yara_rules`: YARA rules that matched the page or one of its scripts. Search with\n  `yara_rule:`. Some rules are broad and match many ordinary sites.\n- `websocket_hosts`: hosts of WebSockets the page opened. Search with `websocket_host:`.\n- `wasm_modules`: SHA-256 of WebAssembly modules the page loaded or carried. Search with\n  `wasm_sha256:`.\n- `brands`: brands this scan is listed under on the brand pages (`/brands/{slug}`).\n\nWebSocket and WebAssembly values are recorded since October 2026.","operationId":"get_scan_pivot_values_api_v1_scans__scan_id__pivot_values_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scans/{scan_id}/wasm":{"get":{"tags":["webassembly"],"summary":"Get Scan Wasm","description":"WebAssembly modules the scanned page used: carried in its scripts, downloaded, or built at run time.\n\nEach module has its size, how it reached the page (`how`), the hosts of the files and scripts\ninvolved, plain-language `labels` (leads, never verdicts), known library or service `names`,\ntoolchain and counts, how many other public scans used it, and what it did at run time.\n`recorded: false` means modules were not recorded for this scan (scans from before\nOctober 2026), so an empty list is unknown rather than \"none\". Search any module with\n`wasm_sha256:`.","operationId":"get_scan_wasm_api_v1_scans__scan_id__wasm_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/wasm/{sha256}":{"get":{"tags":["webassembly"],"summary":"Get Wasm Module","description":"One WebAssembly module: its structure (sections, imports, exports, data segments and their\nentropy), what the analysis found (`labels`, `names`, hosts it names, threat-feed matches, messaging-bot\nchannels with their tokens masked, `passed_text`: fixed text it hands to the page's JavaScript through its\nimports, addresses as hosts; `loaded_by`: scripts on public scans that carry or load it, with their host and\nobfuscation level), what it did at run time, and the public scans it appeared on\n(newest first, paged). Modules seen only on private scans are not shown.\nDownload the module with `/api/v1/wasm/{sha256}/download`.","operationId":"get_wasm_module_api_v1_wasm__sha256__get","parameters":[{"name":"sha256","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 of the module (64 hex characters)","title":"Sha256"},"description":"SHA-256 of the module (64 hex characters)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/wasm/{sha256}/download":{"get":{"tags":["webassembly"],"summary":"Download Wasm Module","description":"The module's bytes, as the page had them (`application/octet-stream`, saved as `<sha256>.wasm`).\nWebAssembly does nothing on its own: it runs only when a script instantiates it. Modules seen only\non private scans are not available.","operationId":"download_wasm_module_api_v1_wasm__sha256__download_get","parameters":[{"name":"sha256","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 of the module (64 hex characters)","title":"Sha256"},"description":"SHA-256 of the module (64 hex characters)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/health":{"get":{"summary":"Health Check","description":"Liveness check: returns ok while the API is serving requests.","operationId":"health_check_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/health/deps":{"get":{"summary":"Health Dependencies","description":"Dependency health: HTTP 503 when a service the API depends on is unavailable.\n\nAnswer from the status code; the body names each dependency as connected or\ndisconnected.","operationId":"health_dependencies_api_v1_health_deps_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/modules/ping":{"get":{"tags":["Module Monitoring"],"summary":"Health Check","description":"Basic health check endpoint - No authentication required\n\nReturns simple status for uptime monitoring","operationId":"health_check_api_v1_modules_ping_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Unauthorized - Invalid credentials"},"403":{"description":"Forbidden - Access denied"}}}},"/api/v1/scans/{scan_id}/jsfingerprints":{"get":{"tags":["jsfingerprints"],"summary":"List Fingerprints For Scan","description":"Get all JavaScript fingerprints for a specific scan.\n\nReturns comprehensive fingerprint data including hashes, metrics, library detection,\nbundle analysis, and more.","operationId":"list_fingerprints_for_scan_api_v1_scans__scan_id__jsfingerprints_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"include_functions","in":"query","required":false,"schema":{"type":"boolean","description":"Include full function list","default":false,"title":"Include Functions"},"description":"Include full function list"},{"name":"include_http_headers","in":"query","required":false,"schema":{"type":"boolean","description":"Include HTTP header data","default":true,"title":"Include Http Headers"},"description":"Include HTTP header data"},{"name":"include_vectors_info","in":"query","required":false,"schema":{"type":"boolean","description":"Include ML vector availability","default":true,"title":"Include Vectors Info"},"description":"Include ML vector availability"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/{fingerprint_id}":{"get":{"tags":["jsfingerprints"],"summary":"Get Single Fingerprint","description":"Get detailed information about a single JavaScript fingerprint.","operationId":"get_single_fingerprint_api_v1_jsfingerprints__fingerprint_id__get","parameters":[{"name":"fingerprint_id","in":"path","required":true,"schema":{"type":"integer","description":"Fingerprint ID","title":"Fingerprint Id"},"description":"Fingerprint ID"},{"name":"include_functions","in":"query","required":false,"schema":{"type":"boolean","description":"Include full function list","default":false,"title":"Include Functions"},"description":"Include full function list"},{"name":"include_http_headers","in":"query","required":false,"schema":{"type":"boolean","description":"Include HTTP header data","default":true,"title":"Include Http Headers"},"description":"Include HTTP header data"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/{fingerprint_id}/similar":{"get":{"tags":["jsfingerprints"],"summary":"Find Similar Javascript","description":"Find JavaScript files similar to the given fingerprint using ML vector similarity.\nUses cosine similarity on the 192-dimensional composite vector (AST + handcrafted features).\nSupports pagination via limit and offset parameters.","operationId":"find_similar_javascript_api_v1_jsfingerprints__fingerprint_id__similar_get","parameters":[{"name":"fingerprint_id","in":"path","required":true,"schema":{"type":"integer","description":"Fingerprint ID","title":"Fingerprint Id"},"description":"Fingerprint ID"},{"name":"threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum similarity score","default":0.7,"title":"Threshold"},"description":"Minimum similarity score"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum results","default":10,"title":"Limit"},"description":"Maximum results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset for pagination","default":0,"title":"Offset"},"description":"Results offset for pagination"},{"name":"exclude_same_scan","in":"query","required":false,"schema":{"type":"boolean","description":"Exclude results from same scan","default":false,"title":"Exclude Same Scan"},"description":"Exclude results from same scan"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/sha256/{hash_value}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Sha256","description":"Search JavaScript fingerprints by exact SHA-256 hash.\nOnly searches public scans.","operationId":"search_by_sha256_api_v1_jsfingerprints_search_sha256__hash_value__get","parameters":[{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","title":"Hash Value"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/normalized/{hash_value}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Normalized","description":"Search JavaScript fingerprints by normalized SHA-256 hash.\nNormalized hash ignores whitespace and formatting differences.\nOnly searches public scans.","operationId":"search_by_normalized_api_v1_jsfingerprints_search_normalized__hash_value__get","parameters":[{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","title":"Hash Value"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/md5/{hash_value}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Md5","description":"Search JavaScript fingerprints by MD5 hash.\nOnly searches public scans.","operationId":"search_by_md5_api_v1_jsfingerprints_search_md5__hash_value__get","parameters":[{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","title":"Hash Value"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/sha1/{hash_value}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Sha1","description":"Search JavaScript fingerprints by SHA-1 hash.\nOnly searches public scans.","operationId":"search_by_sha1_api_v1_jsfingerprints_search_sha1__hash_value__get","parameters":[{"name":"hash_value","in":"path","required":true,"schema":{"type":"string","title":"Hash Value"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/library/{library}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Library","description":"Search JavaScript fingerprints by library name.\nOnly searches public scans.","operationId":"search_by_library_api_v1_jsfingerprints_search_library__library__get","parameters":[{"name":"library","in":"path","required":true,"schema":{"type":"string","title":"Library"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/library/{library}/version/{version}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Library Version","description":"Search JavaScript fingerprints by library name and specific version.\nOnly searches public scans.","operationId":"search_by_library_version_api_v1_jsfingerprints_search_library__library__version__version__get","parameters":[{"name":"library","in":"path","required":true,"schema":{"type":"string","title":"Library"}},{"name":"version","in":"path","required":true,"schema":{"type":"string","title":"Version"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/bundler/{bundler}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Bundler","description":"Search JavaScript fingerprints by bundler type (webpack, rollup, vite, etc.).\nOnly searches public scans.","operationId":"search_by_bundler_api_v1_jsfingerprints_search_bundler__bundler__get","parameters":[{"name":"bundler","in":"path","required":true,"schema":{"type":"string","title":"Bundler"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/search/fuzzy/{fuzzy_hash}":{"get":{"tags":["jsfingerprints"],"summary":"Search By Fuzzy Hash","description":"Search JavaScript fingerprints by SSDEEP fuzzy hash.\nFuzzy hashing allows finding similar code even with modifications.\nOnly searches public scans.","operationId":"search_by_fuzzy_hash_api_v1_jsfingerprints_search_fuzzy__fuzzy_hash__get","parameters":[{"name":"fuzzy_hash","in":"path","required":true,"schema":{"type":"string","title":"Fuzzy Hash"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Limit"},"description":"Results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Results offset","default":0,"title":"Offset"},"description":"Results offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/statistics/bundles":{"get":{"tags":["jsfingerprints"],"summary":"Get Bundle Statistics","description":"Get statistics about bundled JavaScript across all scans.","operationId":"get_bundle_statistics_api_v1_jsfingerprints_statistics_bundles_get","parameters":[{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/statistics/libraries":{"get":{"tags":["jsfingerprints"],"summary":"Get Library Statistics","description":"Get statistics about detected JavaScript libraries.","operationId":"get_library_statistics_api_v1_jsfingerprints_statistics_libraries_get","parameters":[{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"},{"name":"min_count","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Minimum occurrences to include","default":5,"title":"Min Count"},"description":"Minimum occurrences to include"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/hash-prevalence/{scan_id}":{"get":{"tags":["jsfingerprints"],"summary":"Get Hash Prevalence","description":"Get prevalence counts for script hashes in a scan.\n\nReturns how many other scans contain scripts with matching hashes.\nThis helps identify commonly used libraries vs unique scripts.\n\nResponse includes counts for:\n- content_sha256: Exact content match\n- normalized_hash: Same code after normalization (whitespace-independent)\n- fuzzy_hash: Similar code (SSDEEP matching)","operationId":"get_hash_prevalence_api_v1_jsfingerprints_hash_prevalence__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/{fingerprint_id}/similarity-counts":{"get":{"tags":["jsfingerprints"],"summary":"Get Similarity Counts","description":"Get count of similar scripts for EACH ML algorithm separately.\n\nReturns similarity counts for:\n- CodeBERT (768-dim semantic code embedding)\n- GraphCodeBERT (768-dim graph-based embedding)\n- AST Features (128-dim structural metrics)\n- Handcrafted Features (64-dim complexity metrics)\n- Composite Vector (192-dim weighted combination of AST + handcrafted)\n\nUses cosine similarity (1 - distance) where 1.0 = identical, 0.0 = opposite.\n\n**Performance Note**: Uses LIMIT-based counting for efficiency. Counts are capped at max_count.\nIf count equals max_count, actual count may be higher (indicated by 'capped' flag).","operationId":"get_similarity_counts_api_v1_jsfingerprints__fingerprint_id__similarity_counts_get","parameters":[{"name":"fingerprint_id","in":"path","required":true,"schema":{"type":"integer","description":"Fingerprint ID","title":"Fingerprint Id"},"description":"Fingerprint ID"},{"name":"threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum similarity score","default":0.7,"title":"Threshold"},"description":"Minimum similarity score"},{"name":"max_count","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":10,"description":"Max count to return (for performance)","default":1000,"title":"Max Count"},"description":"Max count to return (for performance)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/{fingerprint_id}/source":{"get":{"tags":["jsfingerprints"],"summary":"Get script source code","description":"Retrieve the original JavaScript source code for a fingerprint from object storage","operationId":"get_script_source_api_v1_jsfingerprints__fingerprint_id__source_get","parameters":[{"name":"fingerprint_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Fingerprint ID","title":"Fingerprint Id"},"description":"Fingerprint ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScriptSourceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprints/{fingerprint_id}/command-literals":{"get":{"tags":["jsfingerprints"],"summary":"Shell commands staged in the script","description":"Static check for a Windows or macOS shell command held as a string literal in this script (the ClickFix pattern), with any delivery-stealth traits.","operationId":"get_script_command_literals_api_v1_jsfingerprints__fingerprint_id__command_literals_get","parameters":[{"name":"fingerprint_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Fingerprint ID","title":"Fingerprint Id"},"description":"Fingerprint ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandLiteralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/hash/sha256/{hash}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Sha256","description":"Find exact JavaScript content matches by SHA-256 hash.\n\nUse Case: Malware detection, code reuse tracking, supply chain security\nPerformance: < 100ms (indexed lookup)","operationId":"search_by_sha256_api_v1_jsfingerprint_hash_sha256__hash__get","parameters":[{"name":"hash","in":"path","required":true,"schema":{"type":"string","minLength":64,"maxLength":64,"description":"SHA-256 hash (64 hex characters)","title":"Hash"},"description":"SHA-256 hash (64 hex characters)"},{"name":"include_scans","in":"query","required":false,"schema":{"type":"boolean","description":"Include scan references","default":true,"title":"Include Scans"},"description":"Include scan references"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/hash/md5/{hash}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Md5","description":"Find exact JavaScript content matches by MD5 hash.\n\nUse Case: Legacy hash lookups, malware detection, code reuse tracking\nPerformance: < 100ms (indexed lookup)","operationId":"search_by_md5_api_v1_jsfingerprint_hash_md5__hash__get","parameters":[{"name":"hash","in":"path","required":true,"schema":{"type":"string","minLength":32,"maxLength":32,"description":"MD5 hash (32 hex characters)","title":"Hash"},"description":"MD5 hash (32 hex characters)"},{"name":"include_scans","in":"query","required":false,"schema":{"type":"boolean","description":"Include scan references","default":true,"title":"Include Scans"},"description":"Include scan references"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/hash/sha1/{hash}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Sha1","description":"Find exact JavaScript content matches by SHA-1 hash.\n\nUse Case: Legacy hash lookups, malware detection, code reuse tracking\nPerformance: < 100ms (indexed lookup)","operationId":"search_by_sha1_api_v1_jsfingerprint_hash_sha1__hash__get","parameters":[{"name":"hash","in":"path","required":true,"schema":{"type":"string","minLength":40,"maxLength":40,"description":"SHA-1 hash (40 hex characters)","title":"Hash"},"description":"SHA-1 hash (40 hex characters)"},{"name":"include_scans","in":"query","required":false,"schema":{"type":"boolean","description":"Include scan references","default":true,"title":"Include Scans"},"description":"Include scan references"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/hash/normalized/{hash}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Normalized Hash","description":"Find whitespace-independent code matches by normalized hash.\n\nUse Case: Detect minified/formatted variants of same code\nPerformance: < 100ms (indexed lookup)","operationId":"search_by_normalized_hash_api_v1_jsfingerprint_hash_normalized__hash__get","parameters":[{"name":"hash","in":"path","required":true,"schema":{"type":"string","minLength":64,"maxLength":64,"description":"Normalized hash (64 hex characters)","title":"Hash"},"description":"Normalized hash (64 hex characters)"},{"name":"include_scans","in":"query","required":false,"schema":{"type":"boolean","description":"Include scan references","default":true,"title":"Include Scans"},"description":"Include scan references"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (ISO 8601)","title":"From Date"},"description":"Start date (ISO 8601)"},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (ISO 8601)","title":"To Date"},"description":"End date (ISO 8601)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/hash/fuzzy/{fuzzy_hash}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Fuzzy Hash","description":"Find similar code using SSDEEP fuzzy hashing.\n\nUse Case: Detect obfuscated/modified variants of malware\nPerformance: 500ms-2s (requires fuzzy comparison)\n\nNote: Full SSDEEP comparison requires external library - this endpoint does exact fuzzy_hash matches.\nFor true fuzzy matching, SSDEEP library integration is required.","operationId":"search_by_fuzzy_hash_api_v1_jsfingerprint_hash_fuzzy__fuzzy_hash__get","parameters":[{"name":"fuzzy_hash","in":"path","required":true,"schema":{"type":"string","description":"SSDEEP fuzzy hash","title":"Fuzzy Hash"},"description":"SSDEEP fuzzy hash"},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum similarity percentage","default":50,"title":"Min Similarity"},"description":"Minimum similarity percentage"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/library/{library_name}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Library","description":"Find all scripts using a specific JavaScript library.\n\nUse Case: Vulnerable library tracking, supply chain security\nPerformance: 500ms-1s","operationId":"search_by_library_api_v1_jsfingerprint_library__library_name__get","parameters":[{"name":"library_name","in":"path","required":true,"schema":{"type":"string","description":"Library name (e.g., 'react', 'vue', 'jquery')","title":"Library Name"},"description":"Library name (e.g., 'react', 'vue', 'jquery')"},{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Specific version (e.g., '16.13.1')","title":"Version"},"description":"Specific version (e.g., '16.13.1')"},{"name":"version_pattern","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Version wildcard (e.g., '16.*')","title":"Version Pattern"},"description":"Version wildcard (e.g., '16.*')"},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum detection confidence","default":0.5,"title":"Min Confidence"},"description":"Minimum detection confidence"},{"name":"include_cdn_only","in":"query","required":false,"schema":{"type":"boolean","description":"Filter to CDN-hosted only","default":false,"title":"Include Cdn Only"},"description":"Filter to CDN-hosted only"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Per Page"},"description":"Results per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/library/{library}/version/{version}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Library Version","description":"Find exact library+version combinations.\n\nUse Case: CVE tracking - find all scans using vulnerable version\nPerformance: < 500ms","operationId":"search_by_library_version_api_v1_jsfingerprint_library__library__version__version__get","parameters":[{"name":"library","in":"path","required":true,"schema":{"type":"string","description":"Library name","title":"Library"},"description":"Library name"},{"name":"version","in":"path","required":true,"schema":{"type":"string","description":"Library version","title":"Version"},"description":"Library version"},{"name":"include_deprecated","in":"query","required":false,"schema":{"type":"boolean","description":"Include old scans","default":true,"title":"Include Deprecated"},"description":"Include old scans"},{"name":"group_by_url","in":"query","required":false,"schema":{"type":"boolean","description":"Group by unique URL","default":false,"title":"Group By Url"},"description":"Group by unique URL"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/library-inventory":{"get":{"tags":["jsfingerprint-search"],"summary":"Get Library Inventory","description":"Get library version inventory aggregated across all scans.\n\nReturns a catalog of detected JavaScript libraries and their versions, showing usage\nstatistics and prevalence. Useful for understanding your web application dependencies.\n\nUse Case: Library inventory, dependency tracking, version auditing\nPerformance: 1-2s (aggregation query)\n\nNote: This endpoint returns version data only. For vulnerability detection, integrate\nwith external CVE databases (NVD, Snyk, etc.).","operationId":"get_library_inventory_api_v1_jsfingerprint_library_inventory_get","parameters":[{"name":"library","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to specific library","title":"Library"},"description":"Filter to specific library"},{"name":"min_count","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Minimum fingerprint count to include","default":10,"title":"Min Count"},"description":"Minimum fingerprint count to include"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/cdn/{cdn_type}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Cdn","description":"Find all scripts hosted on specific CDN.\n\nUse Case: Infrastructure analysis, CDN compromise detection\nPerformance: < 1s","operationId":"search_by_cdn_api_v1_jsfingerprint_cdn__cdn_type__get","parameters":[{"name":"cdn_type","in":"path","required":true,"schema":{"type":"string","description":"CDN provider (e.g., 'cloudflare', 'fastly', 'akamai')","title":"Cdn Type"},"description":"CDN provider (e.g., 'cloudflare', 'fastly', 'akamai')"},{"name":"cdn_cache_status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cache status (HIT, MISS, STALE)","title":"Cdn Cache Status"},"description":"Cache status (HIT, MISS, STALE)"},{"name":"unpinned_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only URLs without version pinning","default":false,"title":"Unpinned Only"},"description":"Only URLs without version pinning"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results","default":100,"title":"Limit"},"description":"Max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/server/{server_type}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Server","description":"Find scripts by HTTP server type.\n\nUse Case: Infrastructure fingerprinting, attack surface analysis\n`total_scripts` is capped at 1,000; `total_is_lower_bound` is true when more exist.","operationId":"search_by_server_api_v1_jsfingerprint_server__server_type__get","parameters":[{"name":"server_type","in":"path","required":true,"schema":{"type":"string","description":"Server type (e.g., 'nginx', 'apache', 'cloudflare')","title":"Server Type"},"description":"Server type (e.g., 'nginx', 'apache', 'cloudflare')"},{"name":"include_headers","in":"query","required":false,"schema":{"type":"boolean","description":"Include full HTTP headers","default":true,"title":"Include Headers"},"description":"Include full HTTP headers"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/obfuscated":{"get":{"tags":["jsfingerprint-search"],"summary":"Search Obfuscated","description":"Find heavily obfuscated JavaScript.\n\nUse Case: Malware hunting, suspicious code detection\nPerformance: 1-2s","operationId":"search_obfuscated_api_v1_jsfingerprint_obfuscated_get","parameters":[{"name":"min_score","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum obfuscation score","default":0.7,"title":"Min Score"},"description":"Minimum obfuscation score"},{"name":"max_score","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Maximum obfuscation score","default":1.0,"title":"Max Score"},"description":"Maximum obfuscation score"},{"name":"classification","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by classification","title":"Classification"},"description":"Filter by classification"},{"name":"exclude_libraries","in":"query","required":false,"schema":{"type":"boolean","description":"Exclude known libraries","default":false,"title":"Exclude Libraries"},"description":"Exclude known libraries"},{"name":"min_code_length","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum code size","title":"Min Code Length"},"description":"Minimum code size"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Per Page"},"description":"Results per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/patterns":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Patterns","description":"Advanced pattern-based malware hunting.\n\nUse Case: Threat intelligence, malware research\nPerformance: 2-5s (complex JSONB queries)\n\nNote: Pattern detection depends on AST and feature extraction during fingerprinting.","operationId":"search_by_patterns_api_v1_jsfingerprint_patterns_get","parameters":[{"name":"has_eval","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Contains eval() calls","title":"Has Eval"},"description":"Contains eval() calls"},{"name":"has_crypto","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Contains crypto operations","title":"Has Crypto"},"description":"Contains crypto operations"},{"name":"has_websocket","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Contains WebSocket usage","title":"Has Websocket"},"description":"Contains WebSocket usage"},{"name":"high_entropy","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"High string entropy (suspicious)","title":"High Entropy"},"description":"High string entropy (suspicious)"},{"name":"no_library","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"No library detected","title":"No Library"},"description":"No library detected"},{"name":"cdn_mismatch","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"CDN URL but no library detected","title":"Cdn Mismatch"},"description":"CDN URL but no library detected"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/bundler/{bundler_type}":{"get":{"tags":["jsfingerprint-search"],"summary":"Search By Bundler","description":"Find scripts by bundler type.\n\nUse Case: Build tool analysis, supply chain security\nPerformance: < 1s","operationId":"search_by_bundler_api_v1_jsfingerprint_bundler__bundler_type__get","parameters":[{"name":"bundler_type","in":"path","required":true,"schema":{"type":"string","description":"Bundler type (webpack, rollup, vite, parcel, esbuild)","title":"Bundler Type"},"description":"Bundler type (webpack, rollup, vite, parcel, esbuild)"},{"name":"bundle_format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bundle format (esm, cjs, umd, iife, amd)","title":"Bundle Format"},"description":"Bundle format (esm, cjs, umd, iife, amd)"},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum bundler detection confidence","default":0.5,"title":"Min Confidence"},"description":"Minimum bundler detection confidence"},{"name":"include_libraries","in":"query","required":false,"schema":{"type":"boolean","description":"Include detected libraries","default":true,"title":"Include Libraries"},"description":"Include detected libraries"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page","default":50,"title":"Per Page"},"description":"Results per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jsfingerprint/similar-by-hash":{"post":{"tags":["jsfingerprint-search"],"summary":"Find Similar By Hash","description":"Find similar scripts by providing content hash (not fingerprint ID).\n\nUse Case: Public malware detection without requiring existing fingerprint\nPerformance: 100-500ms (indexed vector search)\n\nML Model: 192-dimensional composite vector (post-strip-ML cut-over)\n- AST Features (128 dims, weight 5.0x) - Abstract syntax tree analysis\n- Hand-crafted Features (64 dims, weight 3.0x) - Code complexity metrics","operationId":"find_similar_by_hash_api_v1_jsfingerprint_similar_by_hash_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimilarByHashRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/similar/{scan_id}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search Similar Fingerprints","description":"Find scans with similar behavioral fingerprints.\n\nUses weighted component comparison:\n- Call Pattern (35%): Execution behavior vector\n- Characteristics (25%): Eval calls, function counts, DOM manipulation\n- Signature (15%): Human-readable behavior signature\n- API Sequence (15%): API call sequence hash\n- Timing (5%): Timing pattern hash\n- Sequence Graph (5%): Execution sequence hash\n\n**Use Cases:**\n- Find malware variants/families\n- Detect code reuse across different domains\n- Identify obfuscated versions of same code","operationId":"search_similar_fingerprints_api_v1_js_fingerprinter2_search_similar__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum similarity threshold (0-1)","default":0.9,"title":"Min Similarity"},"description":"Minimum similarity threshold (0-1)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Maximum number of results","default":50,"title":"Limit"},"description":"Maximum number of results"},{"name":"include_self","in":"query","required":false,"schema":{"type":"boolean","description":"Include the query scan in results","default":false,"title":"Include Self"},"description":"Include the query scan in results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/composite-hash/{composite_hash}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search By Composite Hash","description":"Find all scans with an exact composite-hash match.\n\nThe composite hash is a SHA-256 digest of all behavioral data (call patterns, API\nusage, execution characteristics, timing, sequence graphs).\n\nNOTE: the composite hash incorporates exact, run-to-run-variable execution counts, so\nit is effectively unique per scan — it does NOT reliably match the same script across\nscans or sites, and this lookup typically returns only the originating scan. For\nbehavioral grouping use GET /search/stable-signature/{hash}. See\njs-fingerprinter2/BEHAVIORAL_FINGERPRINT_EVALUATION_PLAN.md (F-09, F-12).","operationId":"search_by_composite_hash_api_v1_js_fingerprinter2_search_composite_hash__composite_hash__get","parameters":[{"name":"composite_hash","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 composite hash from behavioral fingerprint","title":"Composite Hash"},"description":"SHA-256 composite hash from behavioral fingerprint"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum number of results","default":100,"title":"Limit"},"description":"Maximum number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/stable-signature/{signature_hash}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search By Stable Signature","description":"Find all scans with matching stable behavioral signature.\n\nThe stable signature buckets API usage into categories (none/low/medium/high/very_high)\nand complexity into tiers, producing deterministic signatures that cluster similar behavior.\nUnlike compositeHash (exact SHA-256), this groups scans with similar behavioral patterns.\n\n**Use Case:** Find behaviorally similar scripts across different sites","operationId":"search_by_stable_signature_api_v1_js_fingerprinter2_search_stable_signature__signature_hash__get","parameters":[{"name":"signature_hash","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 hash of stable behavioral signature","title":"Signature Hash"},"description":"SHA-256 hash of stable behavioral signature"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum number of results","default":100,"title":"Limit"},"description":"Maximum number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/behavior-vector/similar/{scan_id}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search By Behavior Vector","description":"Find scans with similar behavior vectors using L1 (Manhattan) distance.\n\nThe behavior vector is a 32-byte feature vector encoding API usage intensity,\ncode complexity, risk flags, call patterns, timing, and sequence topology.\nL1 distance between vectors gives a continuous similarity score (0-1).\n\n**Use Case:** Find the most behaviorally similar scans to a given scan,\neven when they don't share the exact same stable signature.","operationId":"search_by_behavior_vector_api_v1_js_fingerprinter2_search_behavior_vector_similar__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum similarity threshold (0-1)","default":0.7,"title":"Min Similarity"},"description":"Minimum similarity threshold (0-1)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Maximum number of results","default":50,"title":"Limit"},"description":"Maximum number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/code-hash/{code_hash}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search By Code Hash","description":"Find all scans containing scripts with exact code hash match.\n\nThe code hash is a SHA-256 hash of the script's source code.\nThis allows finding identical scripts across different scans, even if:\n- Served from different URLs\n- Embedded inline vs external\n- Part of different pages\n\n**Use Case:** Track script prevalence, identify reused malicious code","operationId":"search_by_code_hash_api_v1_js_fingerprinter2_search_code_hash__code_hash__get","parameters":[{"name":"code_hash","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 hash of individual script code","title":"Code Hash"},"description":"SHA-256 hash of individual script code"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum number of results","default":100,"title":"Limit"},"description":"Maximum number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/signature/{signature}":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Search By Signature","description":"Find scans with matching behavior signature.\n\nSignature format: `eval:X|Function:Y|api:count|complexity`\n\nExample: `eval:15|Function:3|setTimeout:45|medium`\n\n**Use Case:** Quick search for scans with similar API usage patterns","operationId":"search_by_signature_api_v1_js_fingerprinter2_search_signature__signature__get","parameters":[{"name":"signature","in":"path","required":true,"schema":{"type":"string","description":"Human-readable behavior signature","title":"Signature"},"description":"Human-readable behavior signature"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum number of results","default":100,"title":"Limit"},"description":"Maximum number of results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/malware-families":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Detect Malware Families","description":"DISABLED (2026-05-19) — behavioral malware-family clustering.\n\nThis endpoint grouped scans by the behavioral `compositeHash`. An evaluation found\nthat hash to be a per-scan nonce — 0% stable across rescans of the same URL, 0%\nshared across scans of the same known malware family — so the \"families\" it returned\nwere clusters of degenerate near-empty traces, not malware families. It is disabled\npending the behavioral-fingerprint rework.\n\nSee js-fingerprinter2/BEHAVIORAL_FINGERPRINT_EVALUATION_PLAN.md (F-09, F-12).\nFor behavioral grouping use GET /search/stable-signature/{hash}.","operationId":"detect_malware_families_api_v1_js_fingerprinter2_search_malware_families_get","parameters":[{"name":"min_cluster_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":2,"description":"Minimum scans per family","default":2,"title":"Min Cluster Size"},"description":"Minimum scans per family"},{"name":"similarity_threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Similarity threshold for clustering","default":0.95,"title":"Similarity Threshold"},"description":"Similarity threshold for clustering"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Maximum number of families to return","default":50,"title":"Limit"},"description":"Maximum number of families to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinter2/search/fingerprint-coverage":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Get Fingerprint Coverage","description":"Get statistics on behavioral fingerprint coverage.\n\nShows how many scans have fingerprints enabled vs disabled.","operationId":"get_fingerprint_coverage_api_v1_js_fingerprinter2_search_fingerprint_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/js-fingerprinter2/search/health":{"get":{"tags":["js-fingerprinter2-search"],"summary":"Health Check","description":"Health check for JS-Fingerprinter2 search API","operationId":"health_check_api_v1_js_fingerprinter2_search_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/js-fingerprinting3/scan/{scan_id}":{"get":{"tags":["js-fingerprinting3"],"summary":"Fingerprints For Scan","description":"All structural fingerprints recorded for one scan.\n\nEach row is enriched with corpus-wide prevalence counts (`content_seen`,\n`canonical_seen`) and, where one is found, a code-signature library match.","operationId":"fingerprints_for_scan_api_v1_js_fingerprinting3_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinting3/canonical/{canonical_ast_hash}":{"get":{"tags":["js-fingerprinting3"],"summary":"Search Canonical","description":"Every script whose canonical AST hash matches — the same code structure even\nunder identifier renaming (the obfuscation-resistant identity).","operationId":"search_canonical_api_v1_js_fingerprinting3_canonical__canonical_ast_hash__get","parameters":[{"name":"canonical_ast_hash","in":"path","required":true,"schema":{"type":"string","description":"canonical_ast_hash","title":"Canonical Ast Hash"},"description":"canonical_ast_hash"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinting3/content/{content_sha256}":{"get":{"tags":["js-fingerprinting3"],"summary":"Search Content","description":"Every scan where a byte-identical script appeared.","operationId":"search_content_api_v1_js_fingerprinting3_content__content_sha256__get","parameters":[{"name":"content_sha256","in":"path","required":true,"schema":{"type":"string","description":"content SHA-256","title":"Content Sha256"},"description":"content SHA-256"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinting3/similar/{row_id}":{"get":{"tags":["js-fingerprinting3"],"summary":"Search Similar","description":"Scripts that are structurally similar to this one, nearest-neighbour ranked.","operationId":"search_similar_api_v1_js_fingerprinting3_similar__row_id__get","parameters":[{"name":"row_id","in":"path","required":true,"schema":{"type":"integer","description":"js_fingerprinting3.id of the anchor","title":"Row Id"},"description":"js_fingerprinting3.id of the anchor"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"default":0.9,"title":"Min Similarity"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinting3/hunts":{"get":{"tags":["js-fingerprinting3"],"summary":"List Kits","description":"All registered kits in the roster + a running sighting count per kit.","operationId":"list_kits_api_v1_js_fingerprinting3_hunts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["js-fingerprinting3"],"summary":"Add Kit","description":"Register a new malicious-kit build (analyst/admin only). Anchors may be\ngiven directly (content_sha256 / canonical_ast_hash / tlsh / yara_rule_name) or\nderived from an existing js_fingerprinting3 row via `from_jsfp3_id`. A YARA anchor\nis for inline-HTML kits that leave no JS fingerprint (e.g. brand-clone phishing);\nits sightings are collected at the page level. On success the endpoint\nbackfills sightings for existing matches, so the kit is immediately useful.\nIdempotent per (hunt_family, anchor).","operationId":"add_kit_api_v1_js_fingerprinting3_hunts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HuntCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/js-fingerprinting3/hunt/{hunt_id}":{"get":{"tags":["js-fingerprinting3"],"summary":"Kit Detail","description":"Kit metadata + every sighting recorded against it.","operationId":"kit_detail_api_v1_js_fingerprinting3_hunt__hunt_id__get","parameters":[{"name":"hunt_id","in":"path","required":true,"schema":{"type":"string","description":"hunt public_id (UUID); legacy int id also accepted","title":"Hunt Id"},"description":"hunt public_id (UUID); legacy int id also accepted"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-fingerprinting3/stats":{"get":{"tags":["js-fingerprinting3"],"summary":"Stats","description":"Coverage statistics for js-fingerprinting3.","operationId":"stats_api_v1_js_fingerprinting3_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/hunts":{"get":{"tags":["hunts"],"summary":"Hunts List","operationId":"hunts_list_api_v1_hunts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["hunts"],"summary":"Hunts Create","operationId":"hunts_create_api_v1_hunts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HuntCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/hunts/{hunt_id}":{"get":{"tags":["hunts"],"summary":"Hunts Detail","operationId":"hunts_detail_api_v1_hunts__hunt_id__get","parameters":[{"name":"hunt_id","in":"path","required":true,"schema":{"type":"string","description":"hunt public_id (UUID); legacy int id also accepted","title":"Hunt Id"},"description":"hunt public_id (UUID); legacy int id also accepted"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands":{"get":{"tags":["brands"],"summary":"List Brands","description":"The brand catalog with per-brand published counts.\n\nPaginated and filterable. The unparameterised call used to return all 651 rows\n(~156 KB) on every request, which is also the shape that hurts a memory-tight MCP\nhost if this is ever exposed as a tool.\n\n`total` is the count AFTER filtering, so a client can page without a second call.","operationId":"list_brands_api_v1_brands_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"brands per page","default":60,"title":"Limit"},"description":"brands per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to one sector","title":"Sector"},"description":"filter to one sector"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"description":"match brand name, slug or official domain","title":"Q"},"description":"match brand name, slug or official domain"},{"name":"has_sightings","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"true = only brands with at least one published sighting","title":"Has Sightings"},"description":"true = only brands with at least one published sighting"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"sightings | hosts | recent | name","default":"sightings","title":"Sort"},"description":"sightings | hosts | recent | name"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands/sectors":{"get":{"tags":["brands"],"summary":"List Sectors","description":"Sector facet counts (for the gallery filter chips).","operationId":"list_sectors_api_v1_brands_sectors_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/brands/{slug_or_id}":{"get":{"tags":["brands"],"summary":"Brand Detail","description":"One brand + the published hosts caught impersonating it.\n\nOne entry per HOST (most recently seen first), carrying that host's repeat count and\nthe newest scan's title/verdict — not one entry per raw sighting. `limit` bounds\nhosts, not sightings.\n\nKeyset-paginated on (last_seen, host). The endpoint previously capped at 100 hosts\nwith no way to reach the rest, so 89% of the largest brand's hosts were unreachable.","operationId":"brand_detail_api_v1_brands__slug_or_id__get","parameters":[{"name":"slug_or_id","in":"path","required":true,"schema":{"type":"string","description":"brand slug (e.g. 'microsoft'), public_id UUID, or legacy int id","title":"Slug Or Id"},"description":"brand slug (e.g. 'microsoft'), public_id UUID, or legacy int id"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"opaque cursor from `next_cursor`","title":"Cursor"},"description":"opaque cursor from `next_cursor`"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands/{slug_or_id}/timeline":{"get":{"tags":["brands"],"summary":"Brand Timeline","description":"Published sightings and distinct hosts per day, oldest first.\n\nExists so this can be consumed as a feed rather than read as a web page — a\nbrand-protection team wants the delta, not the gallery.","operationId":"brand_timeline_api_v1_brands__slug_or_id__timeline_get","parameters":[{"name":"slug_or_id","in":"path","required":true,"schema":{"type":"string","title":"Slug Or Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":730,"minimum":1,"default":90,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands/{slug_or_id}/export":{"get":{"tags":["brands"],"summary":"Brand Export","description":"The published host rows as CSV or JSON, for offline analysis.","operationId":"brand_export_api_v1_brands__slug_or_id__export_get","parameters":[{"name":"slug_or_id","in":"path","required":true,"schema":{"type":"string","title":"Slug Or Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(csv|json)$","default":"csv","title":"Format"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":1000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tls/{scan_id}":{"get":{"tags":["TLS Certificates"],"summary":"Get Tls Certificate","description":"Get TLS/SSL certificate analysis for a scan\n\nReturns comprehensive certificate details including:\n- Subject and issuer information\n- Validity dates and expiration status\n- Certificate fingerprints (SHA1, SHA256, MD5)\n- Key algorithm and size analysis\n- Subject Alternative Names (SANs)\n- Certificate Transparency (CT) log data\n- CAA record validation\n- Security analysis and risk scoring\n- Chain validation\n- Full certificate PEM data\n\nResults are cached for 60 seconds (only when data exists).","operationId":"get_tls_certificate_api_v1_tls__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TLSCertificateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tls/{scan_id}/certificate/download":{"get":{"tags":["TLS Certificates"],"summary":"Download Certificate","description":"Download the TLS/SSL certificate in PEM format\n\nReturns the certificate as a downloadable .pem file that can be:\n- Imported into browsers/keychains\n- Inspected with OpenSSL (openssl x509 -in cert.pem -text -noout)\n- Used for verification and analysis\n\nResults are cached for 60 seconds (only when data exists).","operationId":"download_certificate_api_v1_tls__scan_id__certificate_download_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tls/{scan_id}/asn1":{"get":{"tags":["TLS Certificates"],"summary":"Get Certificate Asn1","description":"Get ASN.1 parsed certificate structure\n\nReturns the raw ASN.1 structure of the certificate parsed using asn1crypto,\nproviding detailed information about all certificate fields, extensions,\nand encoded values in a human-readable format.\n\nResults are cached for 60 seconds (only when data exists).","operationId":"get_certificate_asn1_api_v1_tls__scan_id__asn1_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/scan/{scan_id}":{"get":{"tags":["JavaScript Segments"],"summary":"Get Segments By Scan","description":"Get all code segments for a scan.\n\nReturns detailed information about all extracted functions, classes, and code blocks.\nOptionally filter by script_url to get segments for a specific script.","operationId":"get_segments_by_scan_api_v1_js_segments_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"script_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific script URL","title":"Script Url"},"description":"Filter by specific script URL"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Maximum segments to return","default":100,"title":"Limit"},"description":"Maximum segments to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/search/hash/{code_hash}":{"get":{"tags":["JavaScript Segments"],"summary":"Search By Code Hash","description":"Find all segments with matching exact code hash.\n\nUseful for finding identical code segments across different scans.","operationId":"search_by_code_hash_api_v1_js_segments_search_hash__code_hash__get","parameters":[{"name":"code_hash","in":"path","required":true,"schema":{"type":"string","description":"SHA-256 code hash","title":"Code Hash"},"description":"SHA-256 code hash"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/search/normalized/{normalized_hash}":{"get":{"tags":["JavaScript Segments"],"summary":"Search By Normalized Hash","description":"Find all segments with matching normalized code hash.\n\nNormalized hashes remove whitespace and comments, enabling fuzzy matching\nof functionally identical code with different formatting.","operationId":"search_by_normalized_hash_api_v1_js_segments_search_normalized__normalized_hash__get","parameters":[{"name":"normalized_hash","in":"path","required":true,"schema":{"type":"string","description":"Normalized code hash (whitespace removed)","title":"Normalized Hash"},"description":"Normalized code hash (whitespace removed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/search/tlsh/{tlsh_hash}":{"get":{"tags":["JavaScript Segments"],"summary":"Search By Tlsh Similarity","description":"Find code segments similar to the given TLSH hash.\n\nTLSH (Trend Micro Locality Sensitive Hash) enables fuzzy matching of code that has been:\n- Minified or beautified\n- Variable names changed\n- Whitespace modified\n- Slightly obfuscated\n\n**Distance thresholds:**\n- 0: Identical code\n- 1-30: Very similar (minor changes)\n- 31-50: Similar (same structure, some modifications)\n- 51-100: Related (significant changes but similar patterns)\n- >100: Different code\n\n**Use cases:**\n- Find malware variants\n- Detect code reuse across sites\n- Identify obfuscated versions of known malicious code\n- Track supply chain compromises\n\n**Coverage — read this before trusting an empty result.** The corpus holds\n~21.4M distinct TLSH values and no single request can compare against all of\nthem. The search runs in tiers, and the response reports which ran:\n\n- `exact_tlsh` — index-complete. Every stored segment whose TLSH equals the\n  query is returned, at distance 0.\n- `normalized_hash_family` — index-complete, and only reachable when the\n  query hash is in the corpus. Covers the reformatted / renamed / whitespace\n  cases above, which `normalized_hash` already collapses. A real TLSH\n  distance is still computed for each member, so a family member beyond\n  `max_distance` is dropped rather than assumed similar.\n- `random_sample_<n>pct` — a genuine random sample (TABLESAMPLE), NOT\n  exhaustive. Present so an unknown hash still gets some fuzzy reach.\n\n`exhaustive` is true only when every tier that CONTRIBUTED was index-complete.\nWhen it is false, an empty `matches` means \"not found in what was compared\",\nnever \"not in the corpus\" — use `total_candidates_scanned` to judge.\nWith `sample_percent=0` only the index-complete tiers run, so the search is\nexhaustive for exact and normalized-family matches (and nothing else). An\n`lsh_bands` banded-similarity tier existed 2026-09-09..22 and was retired\nbecause its index was never maintained (see the comment in the handler).","operationId":"search_by_tlsh_similarity_api_v1_js_segments_search_tlsh__tlsh_hash__get","parameters":[{"name":"tlsh_hash","in":"path","required":true,"schema":{"type":"string","minLength":70,"description":"TLSH hash to search for similar segments","title":"Tlsh Hash"},"description":"TLSH hash to search for similar segments"},{"name":"max_distance","in":"query","required":false,"schema":{"type":"integer","maximum":300,"minimum":0,"description":"Maximum TLSH distance (0=identical, <50=similar, <100=related)","default":50,"title":"Max Distance"},"description":"Maximum TLSH distance (0=identical, <50=similar, <100=related)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Maximum results to return","default":100,"title":"Limit"},"description":"Maximum results to return"},{"name":"include_known_libraries","in":"query","required":false,"schema":{"type":"boolean","description":"Include segments from known libraries","default":false,"title":"Include Known Libraries"},"description":"Include segments from known libraries"},{"name":"sample_percent","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Percentage of the corpus to additionally sample at random for fuzzy matching (TABLESAMPLE). 0 disables it, leaving only the index-complete exact and normalized-family tiers. Read the exhaustive flag in the response.","default":0.02,"title":"Sample Percent"},"description":"Percentage of the corpus to additionally sample at random for fuzzy matching (TABLESAMPLE). 0 disables it, leaving only the index-complete exact and normalized-family tiers. Read the exhaustive flag in the response."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TLSHSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/{scan_id}/unknown":{"get":{"tags":["JavaScript Segments"],"summary":"Get Unknown Segments","description":"Identify segments not matching known libraries.\n\nReturns code segments that aren't recognized as part of known JavaScript libraries.\nThese are candidates for further malware analysis.","operationId":"get_unknown_segments_api_v1_js_segments__scan_id__unknown_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"min_code_length","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Minimum code length to include","default":50,"title":"Min Code Length"},"description":"Minimum code length to include"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/{scan_id}/suspicious":{"get":{"tags":["JavaScript Segments"],"summary":"Get Suspicious Segments","description":"Get high-risk segments that aren't known libraries.\n\nReturns segments with elevated risk scores that are unknown, indicating\npotential malicious code (eval usage, base64 encoding, high entropy, etc.).","operationId":"get_suspicious_segments_api_v1_js_segments__scan_id__suspicious_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"min_risk_score","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum risk score (0-100)","default":60,"title":"Min Risk Score"},"description":"Minimum risk score (0-100)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentSearchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/differential":{"post":{"tags":["JavaScript Segments"],"summary":"Perform Differential Analysis","description":"Compare bundle segments against known library database.\n\nAnalyzes all segments in a scan and identifies:\n- Which segments match known libraries (jQuery, React, etc.)\n- Which segments are unknown (potential malware)\n- Which unknown segments have high risk scores (suspicious)\n\nReturns a breakdown of library composition and unknown code.","operationId":"perform_differential_analysis_api_v1_js_segments_differential_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DifferentialAnalysisRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DifferentialAnalysisResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/js-segments/{scan_id}/differential":{"get":{"tags":["JavaScript Segments"],"summary":"Get Differential Analysis","description":"GET form of POST /differential, returning the identical result.\n\nIt exists so the analysis can be opened as a link. The result page's Code\nSegments panel links its raw API from the Scripts sub-tab bar, and the GET\nsegment endpoints cannot stand in: they count on different predicates\n(e810ce57: /scan 4,614 total and /unknown 3,257, against this analysis's\n4,565 and 4,452), so a link to them would show numbers the panel does not.\nThe defaults match the ones the panel sends.","operationId":"get_differential_analysis_api_v1_js_segments__scan_id__differential_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum library match confidence","default":0.8,"title":"Min Confidence"},"description":"Minimum library match confidence"},{"name":"include_known_libraries","in":"query","required":false,"schema":{"type":"boolean","description":"Include known-library segments in the details","default":false,"title":"Include Known Libraries"},"description":"Include known-library segments in the details"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DifferentialAnalysisResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ApiKeyCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"expires_in_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Expires In Days","default":90}},"type":"object","required":["name"],"title":"ApiKeyCreate"},"CommandLiteralCandidate":{"properties":{"literal":{"type":"string","title":"Literal"},"stealth":{"items":{"type":"string"},"type":"array","title":"Stealth"}},"type":"object","required":["literal","stealth"],"title":"CommandLiteralCandidate"},"CommandLiteralResponse":{"properties":{"fingerprint_id":{"type":"integer","title":"Fingerprint Id"},"analyzed":{"type":"boolean","title":"Analyzed"},"candidates":{"items":{"$ref":"#/components/schemas/CommandLiteralCandidate"},"type":"array","title":"Candidates"},"stealth_markers":{"items":{"type":"string"},"type":"array","title":"Stealth Markers"},"has_clipboard_sink":{"type":"boolean","title":"Has Clipboard Sink"},"corroborated":{"type":"boolean","title":"Corroborated"}},"type":"object","required":["fingerprint_id","analyzed","candidates","stealth_markers","has_clipboard_sink","corroborated"],"title":"CommandLiteralResponse","description":"Shell commands (Windows or macOS) staged as string literals in ONE script (static ClickFix indicator)."},"CtDnsRecord":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","description":"The hostname this record is for."},"ip":{"items":{"type":"string"},"type":"array","title":"Ip","description":"Addresses it resolved to. FREQUENTLY EMPTY, and that is meaningful, not missing data: the hostname was published in a certificate but did not resolve when observed. `resolution_error` says why."},"record_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Type","description":"DNS record type, e.g. A or AAAA."},"timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp","description":"When the observation was made (ISO 8601)."},"ttl":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttl","description":"Record TTL in seconds."},"root_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Domain","description":"Registrable parent of `domain`."},"resolution_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolution Error","description":"Why `ip` is empty, e.g. `nxdomain`. Null when it resolved."}},"type":"object","title":"CtDnsRecord","description":"One observed DNS record for a hostname seen in Certificate Transparency."},"CtDnsResponse":{"properties":{"domain":{"type":"string","title":"Domain","description":"The domain queried, normalised to lower case."},"dns_records":{"items":{"$ref":"#/components/schemas/CtDnsRecord"},"type":"array","title":"Dns Records","description":"The 100 most recent observations."},"ip_addresses":{"items":{"type":"string"},"type":"array","title":"Ip Addresses","description":"Addresses for the apex and www ONLY. Each subdomain's own addresses are in its record's `ip` field."},"total_records":{"type":"integer","title":"Total Records","description":"Number of entries in `dns_records`."},"subdomains":{"items":{"type":"string"},"type":"array","title":"Subdomains","description":"Distinct hostnames below the domain, `www` included. Names that were NXDOMAIN every time we resolved them are listed in `subdomains_unresolved` instead."},"subdomain_count":{"type":"integer","title":"Subdomain Count","description":"Number of entries in `subdomains`."},"subdomains_unresolved":{"items":{"type":"string"},"type":"array","title":"Subdomains Unresolved","description":"ALWAYS PRESENT. Hostnames below the domain that appear in certificates but were NXDOMAIN every time we resolved them. Most are retired or internal names. Kept apart from `subdomains` so that list holds names that existed in public DNS when observed."},"subdomains_unresolved_count":{"type":"integer","title":"Subdomains Unresolved Count","description":"Number of entries in `subdomains_unresolved`.","default":0},"subdomains_truncated":{"type":"boolean","title":"Subdomains Truncated","description":"True when `subdomain_limit` was reached, so a partial list is never mistaken for a complete one. ⚠️ This answers ONLY 'did the cap bite'. It is `false` on a degraded response too, because no cap was reached — check `degraded` for 'is this an answer at all'."},"degraded":{"type":"boolean","title":"Degraded","description":"ALWAYS PRESENT. `false` means the counters are a measurement: we looked and this is what exists. `true` means we could NOT look, and every zero above is an absence of data about the domain rather than a fact about it — retry rather than recording `subdomain_count: 0`. This is the field to branch on; `subdomains_truncated` answers a different question."},"degraded_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Degraded Reason","description":"Present only when `degraded` is true. One of `back_pressure` (we shed this request to protect the upstream store and never queried it — by far the most common, and a plain retry usually succeeds), `timeout`, `circuit_open`, `partial_result`, `upstream_error`, `internal_error`."},"stale":{"type":"boolean","title":"Stale","description":"ALWAYS PRESENT. `true` means this is a real, previously-measured answer served from cache past its freshness window, because a re-look could not be performed. The hostnames in it are genuine; the list may be missing anything observed since. `degraded` stays `false` — the counters are a measurement, just an older one."},"stale_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stale Age Seconds","description":"Present only when `stale` is true: how long ago this answer was measured."},"stale_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stale Reason","description":"Present only when `stale` is true: why the re-look did not happen. Same vocabulary as `degraded_reason`."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Human-readable form of `degraded_reason`. Present only when `degraded` is true; absent on success. Branch on `degraded`/`degraded_reason`, not on this string — its wording is not a stable interface."}},"type":"object","required":["domain","total_records","subdomain_count","subdomains_truncated","degraded","stale"],"title":"CtDnsResponse","description":"DNS observations for a domain and, by default, its subdomains."},"DifferentialAnalysisRequest":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"min_confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Min Confidence","default":0.8},"include_known_libraries":{"type":"boolean","title":"Include Known Libraries","default":false}},"type":"object","required":["scan_id"],"title":"DifferentialAnalysisRequest","description":"Request for differential analysis"},"DifferentialAnalysisResult":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"total_segments":{"type":"integer","title":"Total Segments"},"matched_segments":{"type":"integer","title":"Matched Segments"},"unknown_segments":{"type":"integer","title":"Unknown Segments"},"suspicious_segments":{"type":"integer","title":"Suspicious Segments"},"library_breakdown":{"additionalProperties":{"type":"integer"},"type":"object","title":"Library Breakdown"},"unknown_segment_details":{"items":{"$ref":"#/components/schemas/SegmentInfo"},"type":"array","title":"Unknown Segment Details"},"suspicious_segment_details":{"items":{"$ref":"#/components/schemas/SegmentInfo"},"type":"array","title":"Suspicious Segment Details"}},"type":"object","required":["scan_id","total_segments","matched_segments","unknown_segments","suspicious_segments","library_breakdown","unknown_segment_details","suspicious_segment_details"],"title":"DifferentialAnalysisResult","description":"Differential analysis result"},"DomainAge":{"properties":{"days":{"type":"integer","title":"Days"},"category":{"type":"string","title":"Category"},"risk_level":{"type":"string","title":"Risk Level"},"risk_score":{"type":"number","title":"Risk Score"}},"type":"object","required":["days","category","risk_level","risk_score"],"title":"DomainAge","description":"Domain age information with risk scoring"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HuntCreate":{"properties":{"hunt_name":{"type":"string","maxLength":200,"minLength":1,"title":"Hunt Name"},"category":{"type":"string","title":"Category"},"severity":{"type":"string","title":"Severity","default":"high"},"hunt_family":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Hunt Family"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"reference_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Reference Urls"},"content_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Sha256"},"canonical_ast_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Ast Hash"},"tlsh":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tlsh"},"yara_rule_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yara Rule Name"},"smql_query":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Smql Query"},"from_jsfp3_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"From Jsfp3 Id"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["hunt_name","category"],"title":"HuntCreate"},"ImageSearchRequest":{"properties":{"hash_value":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Hash Value"},"hash_type":{"type":"string","pattern":"^(phash|ahash|dhash|whash)$","title":"Hash Type","default":"phash"},"max_distance":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Max Distance","default":3},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":20}},"type":"object","required":["hash_value"],"title":"ImageSearchRequest","description":"Body for POST /api/v1/screenshot/search.\n\n`hash_value` takes either form, and the type is what disambiguates them — a JSON\nNUMBER is the hash's numeric value, a JSON STRING is the 16-char hex that\n`imagehash` prints and that GET /api/v1/search/screenshot/{type}/{hash} expects.\nThe string form was added because every other screenshot-hash surface speaks hex,\nand a caller holding `b83898c3c3c7ce3c` had to convert it by hand.\n\n`max_distance` allows 0 (exact match). It used to start at 1, which was the exact\ninverse of /api/v1/screenshot/duplicates where 0 is the ONLY accepted value — so\nthe two fuzzy-adjacent endpoints rejected each other's entire input range."},"ImageSimilarityResponse":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"url":{"type":"string","title":"Url"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"submitted_at":{"type":"string","title":"Submitted At"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot"},"distance":{"type":"integer","title":"Distance"},"hash_match_type":{"type":"string","title":"Hash Match Type"},"similarity_score":{"type":"number","title":"Similarity Score"}},"type":"object","required":["scan_id","url","title","submitted_at","screenshot","distance","hash_match_type","similarity_score"],"title":"ImageSimilarityResponse"},"PaginationInfo":{"properties":{"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"},"has_next":{"type":"boolean","title":"Has Next"},"has_prev":{"type":"boolean","title":"Has Prev"}},"type":"object","required":["total","page","limit","total_pages","has_next","has_prev"],"title":"PaginationInfo"},"RDAPResponse":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"domain":{"type":"string","title":"Domain"},"rdap_query_timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rdap Query Timestamp"},"registration_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registration Date"},"expiration_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expiration Date"},"domain_age":{"anyOf":[{"$ref":"#/components/schemas/DomainAge"},{"type":"null"}]},"registrar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registrar"},"nameservers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Nameservers","default":[]},"status":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Status","default":[]},"data_source":{"type":"string","title":"Data Source"},"ip_rdap_data":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Ip Rdap Data","default":[]},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["scan_id","domain","data_source"],"title":"RDAPResponse","description":"RDAP/WHOIS domain and IP registration information"},"RegistrarSearchResponse":{"properties":{"registrar_query":{"type":"string","title":"Registrar Query"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"results":{"items":{"$ref":"#/components/schemas/RegistrarSearchResult"},"type":"array","title":"Results"},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}},"type":"object","required":["registrar_query","total","page","limit","results","pagination"],"title":"RegistrarSearchResponse"},"RegistrarSearchResult":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"url":{"type":"string","title":"Url"},"domain":{"type":"string","title":"Domain"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"asn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asn"},"primary_asn":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Asn"},"asns":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Asns","default":[]},"asn_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Asn Names","default":[]},"asn_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asn Display"},"submitted_at":{"type":"string","title":"Submitted At"},"screenshot_thumbnail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Thumbnail"}},"type":"object","required":["scan_id","url","domain","submitted_at"],"title":"RegistrarSearchResult"},"ScanReport":{"properties":{"scan_id":{"type":"string","pattern":"^[a-f0-9-]{36}$","title":"Scan Id","description":"Scan ID to report"},"report_type":{"type":"string","pattern":"^(positive_feedback|phishing|spam|counterfeit|scam|broken_scan|malware|illegal_content|copyright|technical_issue|other)$","title":"Report Type"},"report_details":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Report Details","description":"Additional details, especially for 'other' category"},"captcha_answer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captcha Answer","description":"Captcha answer"},"captcha_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captcha Token","description":"Captcha token"},"skip_captcha":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Skip Captcha","description":"Skip captcha for positive feedback","default":false},"voter_token":{"anyOf":[{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},{"type":"null"}],"title":"Voter Token","description":"Random per-browser id sent with Mark as Safe / Mark as Malicious, so a vote can be changed"}},"type":"object","required":["scan_id","report_type"],"title":"ScanReport","description":"Model for reporting issues with scanned URLs"},"ScanReportResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"report_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Report Id"},"current_vote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Vote"}},"type":"object","required":["success","message"],"title":"ScanReportResponse"},"ScanRequest":{"properties":{"url":{"type":"string","title":"Url"},"scan_type":{"type":"string","title":"Scan Type","default":"public"},"options":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Options","default":{}},"csrf_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Csrf Token"}},"type":"object","required":["url"],"title":"ScanRequest"},"ScanResponse":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"status":{"type":"string","title":"Status"},"message":{"type":"string","title":"Message"},"scan_type":{"type":"string","title":"Scan Type"},"submitted_at":{"type":"string","title":"Submitted At"}},"type":"object","required":["scan_id","status","message","scan_type","submitted_at"],"title":"ScanResponse"},"ScanResult":{"properties":{"scan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Id"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"final_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Url"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"scan_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot"},"submitted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitted At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"load_time":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Load Time"},"load_time_comparison":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Load Time Comparison"},"links":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Links","default":[]},"forms":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Forms","default":[]},"cookies":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Cookies","default":[]},"scripts":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Scripts","default":[]},"intercepted_scripts":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Intercepted Scripts","default":[]},"meta_tags":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Meta Tags","default":[]},"console_logs":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Console Logs","default":[]},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"http_transactions":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Http Transactions","default":[]},"redirect_chains":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Redirect Chains","default":[]},"redirects":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Redirects","default":[]},"security_verdict":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Security Verdict","default":{}},"certificate_status":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Certificate Status"},"tracker_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Tracker Analysis","default":{}},"technologies":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Technologies","default":{}},"domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Domains","default":[]},"ip_addresses":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Ip Addresses","default":[]},"page_stats":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Page Stats","default":{}},"screenshot_hashes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Screenshot Hashes","default":{}},"favicon_hash":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Favicon Hash"},"fuzzy_hashes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Fuzzy Hashes"},"content_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Content Analysis"},"domain_rankings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Domain Rankings"},"rdap_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rdap Data"},"domains_contacted":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"string"},{"type":"null"}],"title":"Domains Contacted","default":[]},"unique_asns":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Unique Asns","default":[]},"countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Countries","default":[]},"ip_table":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Ip Table","default":[]},"asn_table":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Asn Table","default":[]},"asns":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Asns","default":[]},"primary_asn":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Asn"},"primary_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Ip"},"asn_orgs":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Asn Orgs","default":{}},"asn_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Asn Names","default":[]},"ip_asn_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ip Asn Info","default":{}},"security_headers":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Security Headers","default":{}},"csp_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Csp Analysis"},"csp_policy":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Csp Policy"},"iframes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Iframes"},"cors_findings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cors Findings"},"network_requests":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Network Requests","default":[]},"total_requests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Requests","default":0},"ai_security_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Security Analysis"},"network_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Network Data","default":{}},"local_storage":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Local Storage","default":[]},"session_storage":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Session Storage","default":[]},"page_content":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Page Content","default":{}},"domain_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain Description"},"bot_detection":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Bot Detection"},"capture_recovered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Capture Recovered"},"recovered_capture_refused":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Recovered Capture Refused"},"navigation_committed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Navigation Committed"},"title_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title Source"},"screenshot_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Version"},"warning_page_detected":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Warning Page Detected","default":false},"warning_page_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warning Page Type"},"warning_page_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warning Page Url"},"extracted_target_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extracted Target Url"},"warning_bypass_successful":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Warning Bypass Successful"},"warning_bypass_load_time":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Warning Bypass Load Time"},"sections_available":{"anyOf":[{"additionalProperties":{"type":"boolean"},"type":"object"},{"type":"null"}],"title":"Sections Available"},"warning_bypass_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warning Bypass Error"},"ocr_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Text"},"javascript_files":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Javascript Files","default":[]},"url_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Url Metadata"},"parent_scan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Scan Id"},"scan_relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Relationship"},"child_scans":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Child Scans","default":[]},"ioc_matches":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Ioc Matches"}},"type":"object","title":"ScanResult"},"ScriptSourceResponse":{"properties":{"fingerprint_id":{"type":"integer","title":"Fingerprint Id"},"content_sha256":{"type":"string","title":"Content Sha256"},"script_url":{"type":"string","title":"Script Url"},"code_length":{"type":"integer","title":"Code Length"},"source":{"type":"string","title":"Source"},"retrieved_from":{"type":"string","title":"Retrieved From"}},"type":"object","required":["fingerprint_id","content_sha256","script_url","code_length","source","retrieved_from"],"title":"ScriptSourceResponse","description":"Response model for script source code"},"SegmentInfo":{"properties":{"segment_id":{"type":"integer","title":"Segment Id"},"scan_id":{"type":"string","title":"Scan Id"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"script_url":{"type":"string","title":"Script Url"},"script_url_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Script Url Id"},"segment_type":{"type":"string","title":"Segment Type"},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name"},"start_line":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Start Line"},"end_line":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"End Line"},"start_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Start Offset"},"end_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"End Offset"},"code_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Code Length"},"code_snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Snippet"},"code_hash":{"type":"string","title":"Code Hash"},"normalized_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Normalized Hash"},"tlsh_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tlsh Hash"},"patterns":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Patterns"},"risk_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Risk Score"},"risk_factors":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Risk Factors"},"library_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Library Match"},"library_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Library Confidence"},"is_known_library":{"type":"boolean","title":"Is Known Library","default":false},"is_suspicious":{"type":"boolean","title":"Is Suspicious","default":false},"is_internal_code":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Internal Code"},"corpus_occurrences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Corpus Occurrences"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["segment_id","scan_id","script_url","segment_type","code_hash","created_at"],"title":"SegmentInfo","description":"Individual code segment information"},"SegmentSearchResult":{"properties":{"total_count":{"type":"integer","title":"Total Count"},"segments":{"items":{"$ref":"#/components/schemas/SegmentInfo"},"type":"array","title":"Segments"},"query_params":{"additionalProperties":true,"type":"object","title":"Query Params"},"scope":{"type":"string","title":"Scope"},"inline_attribution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inline Attribution"}},"type":"object","required":["total_count","segments","query_params","scope"],"title":"SegmentSearchResult","description":"Search result for segment queries"},"SimilarByHashRequest":{"properties":{"content_sha256":{"type":"string","title":"Content Sha256","description":"SHA-256 hash of JavaScript content"},"threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Threshold","description":"Minimum similarity score","default":0.7},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Maximum results","default":10},"exclude_exact_matches":{"type":"boolean","title":"Exclude Exact Matches","description":"Exclude exact hash matches","default":false}},"type":"object","required":["content_sha256"],"title":"SimilarByHashRequest","description":"Request model for similarity search by hash"},"TLSCertificateResponse":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"subject_common_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Common Name"},"subject_organization":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Organization"},"subject_organizational_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Organizational Unit"},"subject_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Country"},"subject_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject State"},"subject_locality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Locality"},"issuer_common_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer Common Name"},"issuer_organization":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer Organization"},"issuer_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer Country"},"not_before":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Not Before"},"not_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Not After"},"is_valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Valid"},"is_expired":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Expired"},"is_not_yet_valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Not Yet Valid"},"days_until_expiry":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Until Expiry"},"validity_period_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Validity Period Days"},"serial_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Serial Number"},"signature_algorithm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signature Algorithm"},"key_algorithm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Algorithm"},"key_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Key Size"},"version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version"},"fingerprint_sha1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint Sha1"},"fingerprint_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint Sha256"},"fingerprint_md5":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint Md5"},"ja4x":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ja4X"},"ja4x_certificate_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ja4X Certificate Count"},"rsa_modulus_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rsa Modulus Hash"},"rsa_modulus_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rsa Modulus Size"},"rsa_public_exponent":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rsa Public Exponent"},"rsa_key_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rsa Key Analysis"},"is_debian_weak_key":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Debian Weak Key","default":false},"is_roca_vulnerable":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Roca Vulnerable","default":false},"has_common_modulus":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Common Modulus","default":false},"key_entropy_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Key Entropy Score"},"is_self_signed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Self Signed","default":false},"is_wildcard":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Wildcard","default":false},"is_ev_cert":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Ev Cert","default":false},"is_lets_encrypt":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Lets Encrypt","default":false},"certificate_pem":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certificate Pem"},"sans":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Sans"},"extensions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extensions"},"chain":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Chain"},"chain_valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Chain Valid"},"chain_validation":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Chain Validation"},"hostname_match":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Hostname Match"},"security_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Security Analysis"},"risk_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Risk Score","default":0},"risk_factors":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Risk Factors"},"is_in_ct_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is In Ct Logs","default":false},"ct_log_entries":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}],"title":"Ct Log Entries"},"ct_first_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ct First Seen"},"ct_last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ct Last Seen"},"ct_log_sources":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ct Log Sources","default":[]},"ct_certificate_history":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}],"title":"Ct Certificate History"},"ct_related_domains":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}],"title":"Ct Related Domains"},"ct_ip_history":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}],"title":"Ct Ip History"},"ct_certificate_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ct Certificate Count"},"ct_days_since_first_cert":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ct Days Since First Cert"},"cert_recently_issued":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cert Recently Issued","default":false},"cert_recently_changed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cert Recently Changed","default":false},"shared_with_domains":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Shared With Domains","default":0},"has_caa_records":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Caa Records","default":false},"caa_records":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Caa Records","default":[]},"caa_authorized_cas":{"anyOf":[{"items":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"}]},"type":"array"},{"type":"null"}],"title":"Caa Authorized Cas","default":[]},"caa_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Caa Compliant"},"caa_validation_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Caa Validation Data"},"revocation_checked":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Revocation Checked","default":false},"is_revoked":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Revoked"},"processing_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Processing Time Ms"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["scan_id"],"title":"TLSCertificateResponse","description":"TLS/SSL certificate analysis response"},"TLSHSearchResult":{"properties":{"query_hash":{"type":"string","title":"Query Hash"},"max_distance":{"type":"integer","title":"Max Distance"},"total_candidates_scanned":{"type":"integer","title":"Total Candidates Scanned"},"matches_found":{"type":"integer","title":"Matches Found"},"matches":{"items":{"$ref":"#/components/schemas/TLSHSimilarSegment"},"type":"array","title":"Matches"},"tlsh_available":{"type":"boolean","title":"Tlsh Available","default":true},"exhaustive":{"type":"boolean","title":"Exhaustive","default":false},"search_strategy":{"items":{"type":"string"},"type":"array","title":"Search Strategy","default":[]},"filtered_known_library":{"type":"integer","title":"Filtered Known Library","default":0}},"type":"object","required":["query_hash","max_distance","total_candidates_scanned","matches_found","matches"],"title":"TLSHSearchResult","description":"TLSH similarity search result"},"TLSHSimilarSegment":{"properties":{"segment_id":{"type":"integer","title":"Segment Id"},"scan_id":{"type":"string","title":"Scan Id"},"script_url":{"type":"string","title":"Script Url"},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name"},"code_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Code Length"},"code_snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Snippet"},"tlsh_hash":{"type":"string","title":"Tlsh Hash"},"tlsh_distance":{"type":"integer","title":"Tlsh Distance"},"similarity_score":{"type":"number","title":"Similarity Score"},"risk_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Risk Score"},"is_known_library":{"type":"boolean","title":"Is Known Library","default":false},"library_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Library Match"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["segment_id","scan_id","script_url","tlsh_hash","tlsh_distance","similarity_score","created_at"],"title":"TLSHSimilarSegment","description":"Segment found via TLSH similarity search"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"OptionalHTTPBearer":{"type":"http","scheme":"bearer"},"HTTPBearer":{"type":"http","scheme":"bearer"}}}}