HTTP header inspection and security audit. Three concurrent probes — HTTPS chain, HTTP port-80 upgrade, and CORS with an evil origin — analyse CSP, HSTS, security headers, cookies, and redirect behaviour.
See also: interactive API reference (auto-generated OpenAPI)
Endpoints
GET /api/inspect?url=
Inspect a URL's HTTP headers and security posture. Returns a synchronous JSON response.
curl -s 'https://http.netray.info/api/inspect?url=https%3A%2F%2Fexample.com' | jq .
POST /api/inspect
Same inspection via POST body.
curl -s -X POST https://http.netray.info/api/inspect \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com"}' | jq .
Response Structure
The response contains several top-level sections:
{
"url": "https://example.com",
"probes": [
{
"type": "https",
"status": 200,
"headers": { ... },
"csp": { ... },
"hsts": { "max_age": 31536000, "include_subdomains": true, "preload": false },
"cookies": [ ... ],
"cdn": "cloudflare"
},
{
"type": "http_upgrade",
"status": 301,
"redirect_target": "https://example.com/"
},
{
"type": "cors",
"origin_reflected": false,
"allows_credentials": false,
"allowed_methods": ["GET"]
}
],
"redirects": [
{ "url": "http://example.com", "status": 301, "location": "https://example.com/" }
],
"quality": {
"verdict": "Pass",
"checks": [
{ "name": "hsts", "label": "HSTS", "status": "pass", "message": "HSTS enabled with adequate max-age" },
{ "name": "csp", "label": "Content Security Policy", "status": "warn", "message": "CSP present but uses unsafe-inline" },
...
]
}
}
Quality Checks
The quality.checks array contains up to 11 checks.
Each check has a status of pass, skip,
warn, or fail:
| Check | What It Tests |
|---|---|
hsts | HSTS header present with adequate max-age |
csp | Content Security Policy present and effective |
cors | CORS configuration is not overly permissive |
x_frame_options | X-Frame-Options set to DENY or SAMEORIGIN |
x_content_type_options | X-Content-Type-Options: nosniff is present |
referrer_policy | Referrer-Policy is set and not unsafe |
permissions_policy | Permissions-Policy restricts sensitive features |
cookies | Session cookies have Secure, HttpOnly, SameSite |
redirect_chain | HTTP-to-HTTPS redirect is present and correct |
content_type | Content-Type header includes charset |
redirect_limit | Redirect chain is not excessively long |
Useful One-Liners
# Get the overall verdict
curl -s 'https://http.netray.info/api/inspect?url=https%3A%2F%2Fexample.com' \
| jq '.quality.verdict'
# List all failing checks
curl -s 'https://http.netray.info/api/inspect?url=https%3A%2F%2Fexample.com' \
| jq '[.quality.checks[] | select(.status == "fail")]'
# Check HSTS max-age
curl -s 'https://http.netray.info/api/inspect?url=https%3A%2F%2Fexample.com' \
| jq '.probes[] | select(.type == "https") | .hsts'
# CI gate: fail if verdict is not Pass
curl -sf 'https://http.netray.info/api/inspect?url=https%3A%2F%2Fexample.com' \
| jq -e '.quality.verdict == "Pass"'
Rate Limits
Per-IP GCRA rate limiting. Each request triggers up to three outbound probes (HTTPS, HTTP upgrade, CORS), so the effective cost is higher than a simple GET request.
When rate-limited, you receive a 429 response with a
Retry-After header.
Errors
{
"error": {
"code": "bad_request",
"message": "Missing required parameter: url"
}
}
Common error codes:
| Code | Meaning |
|---|---|
bad_request | Missing or invalid url parameter |
rate_limited | Too many requests; check Retry-After |
target_not_allowed | Target URL is in a disallowed range (private IP, localhost) |
internal_error | Server error; include X-Request-Id in reports |