Skip to content

API Documentation

Query a public URL and receive technology detections, metadata, confidence levels, evidence, safe enrichment probes, scan limits, and typed error codes. HEAD returns the same status and headers without a body; OPTIONS lists supported methods. Successful reports can be cached for 60 seconds and retain their original analyzedAt timestamp.

Analyze endpoint

GEThttps://stack.leunos.com/api/analyze

Analyze a public website. Host-only inputs are normalized to HTTPS, with an HTTP fallback when HTTPS was inferred.

Query parameters

url
stringrequired

Public URL or host to analyze. Example: https://example.com

Example request

Copyable example
curl "https://stack.leunos.com/api/analyze?url=https://example.com"

Response format

Responses include stable slugs, rule IDs, confidence breakdowns, structured signals, summary totals, scan limits, bounded DNS/resource probes, and warnings.

Example response

Copyable example
{ "requestedUrl": "https://example.com", "url": "https://example.com/", "title": "Example Domain", "meta": { "responseTime": 182, "statusCode": 200, "redirected": false, "contentType": "text/html; charset=UTF-8", "htmlBytes": 1653, "hostname": "example.com" }, "technologies": [ { "name": "Cloudflare", "slug": "cloudflare", "category": "CDN", "icon": "Cloud", "confidence": "high", "confidenceScore": 90, "ruleIds": ["cdn.cloudflare"], "confidenceBreakdown": { "header": 90, "dns": 90 }, "evidence": ["header cf-ray: 8a12..."], "signals": [ { "source": "header", "label": "header cf-ray", "value": "8a12..." } ] } ], "summary": { "total": 1, "categories": { "CDN": 1 }, "confidence": { "high": 1, "medium": 0, "low": 0 } }, "scan": { "durationMs": 182, "rulesVersion": "2026.09.15", "limits": { "totalTimeoutMs": 30000, "requestTimeoutMs": 10000, "dnsTimeoutMs": 1500, "maxHtmlBytes": 2097152, "maxRedirects": 4, "maxProbeRequests": 6, "maxProbeRedirects": 1, "maxConcurrentProbes": 2, "maxProbeBytes": 262144, "maxTotalProbeBytes": 1048576, "probeTimeoutMs": 3000, "maxDnsRecords": 12, "maxDnsResponseBytes": 65536, "maxSubrequests": 40, "maxInputUrlChars": 4096, "maxResourceUrlChars": 4096, "maxDiscoveredAssets": 256, "maxTitleChars": 300, "maxDescriptionChars": 1024, "maxGeneratorChars": 256, "maxLanguageChars": 64, "maxApiBodyBytes": 8192 }, "warnings": [], "probes": [ { "type": "dns", "target": "A example.com", "status": "ok", "durationMs": 18 } ] } }

Errors

StatusCodeMeaning
400INVALID_URLMissing URL, malformed URL, unsupported scheme, or embedded credentials.
405METHOD_NOT_ALLOWEDUse GET or HEAD; OPTIONS describes the supported methods.
400BLOCKED_TARGETLocalhost, private/reserved IPs, internal suffixes, or unsafe DNS answers.
502TOO_MANY_REDIRECTSThe upstream site exceeded the redirect limit.
502UPSTREAM_UNREACHABLEThe upstream site could not be reached or returned invalid redirect behavior.
502UNSUPPORTED_CONTENTThe upstream response was not HTML, XML, or text.
503SCAN_LIMIT_REACHEDThe analyzer exhausted its outbound request budget.
504UPSTREAM_TIMEOUTThe upstream site timed out, or the total scan deadline was reached.
500INTERNAL_ERRORAn unexpected analyzer failure. The response never includes a stack trace.

Safety limits

Total scan budget
30 seconds
Request timeout
10 seconds
Redirects
4 hops
HTML size
2 MB
DNS response limit
64 KiB
Probe timeout
3 seconds
Probe requests
6 resources
Probe size
256 KB
Concurrent probes
2
Outbound requests
40

Notes

The analyzer is stateless and heuristic. It blocks known unsafe URL forms, validates redirects, checks public DNS answers before fetching, and only enriches from discovered manifests/assets with strict limits. Oversized primary HTML is truncated and analysis continues with a CONTENT_TRUNCATED warning; oversized probes are skipped rather than failing the scan. Production deployments should still pair it with Cloudflare-level rate limiting and abuse controls.