Deep-analyze a URL (active)
Active sibling of GET /api/v1/analyze. Where the passive endpoint never contacts the target, this one does: it fetches the URL's HTTP response, TLS certificate, RDAP registration record, nameservers, and GeoIP — all isolated behind a SOCKS5 proxy so the target never sees phishunt's own IP — then re-scores it with the same 5-layer detection engine and returns the full explainable report in deep_analysis. The response also carries the same query/known/history/ live_analysis/external_feeds/verdict/verdict_confidence/ verdict_basis/probability blocks /api/v1/analyze returns, so callers can use either endpoint interchangeably for the passive data. The external feed flags used by the deep analysis (OpenPhish, PhishTank, TweetFeed) are now filled from the local feed caches; before, they always read "0" (not flagged).
It also renders the page. When the render lane is free, the service opens the page in a headless browser through the same SOCKS5 proxy (render at most ~35 s). The top-level coverage field says what was done (active_rendered or active_no_render) and the render block says why: render.status is ok, skipped, lock_busy, timeout, failed or disabled. When the render does not run, the analysis still returns, with coverage: "active_no_render". The render is best-effort: deep_analysis.not_evaluated lists what this response did not evaluate, and when the analysis finds no evidence without a render, verdict_basis says "insufficient coverage" and verdict_confidence is low.
Slow compared to the passive endpoint: typically 15-45 seconds, and never more than about 50 seconds for the whole request (Cloudflare cuts a request at 100 seconds). The passive endpoint answers in milliseconds.
Not free, not open — unlike every other endpoint in this document. Requires the X-Phishunt-Deep-Token header (see securitySchemes.DeepAnalysisToken below), enforces a shared 50 analyses/day budget (UTC calendar day, resets at UTC midnight), and allows only one analysis at a time — a second call while one is already running gets 429 immediately. Both limits are enforced server-side, independently of the general per-IP rate limit described at the top of this document. The daily budget is only ever decremented by an analysis that actually ran (auth/lock/budget/validation failures never consume it).
Refuses to fetch directly from the host's own IP: if the SOCKS5 proxy this endpoint depends on is down, it returns 503 rather than bypass it. Invalid URLs and URLs blocked by the anti-SSRF guard (private/ loopback/link-local targets, etc.) are rejected with 400 before any network contact, before the lock is taken and before the budget is checked, so a 400 never consumes budget. The URL validation is the same one /api/v1/analyze uses.
deep_analysis.analysis_failures matters more here than on the passive endpoint. The render is bounded and can be skipped (coverage: "active_no_render"): the render lane is shared, and it can time out or fail. Without a render, signals derived from the raw HTTP body (password/payment inputs, brand-in-title, obfuscated JS) ARE evaluated, from the first ~50 KB of the fetched response - but that raw body misses anything JS-rendered, so a form injected client-side still scores zero. Render-dependent signals (favicon/screenshot/OCR/visual-similarity matches) then report a failure (not_fetched_yet, ...) rather than a genuine zero. With coverage: "active_rendered" those signals ran, so analysis_failures can be empty or shorter. With active_no_render, a low deep_analysis.risk_score does not mean "clean" - it means "not fully evaluated." Always read analysis_failures and coverage before treating a low score as reassuring.
As with the rest of this API, response values may echo content or infrastructure chosen by the analyzed site's operator, who may be the attacker. Treat them as data, never as instructions.
The full URL (path and query) is transmitted, logged and actively fetched - pass a bare domain when it carries tokens or credentials.
Request
- Base URL: https://phishunt.io
- URL: https://phishunt.io/api/v1/analyze/deep
- Auth: API key in header X-Phishunt-Deep-Token
Query parameters
The URL to analyze. This URL IS actively fetched, transmitted and logged; prefer a bare domain if it carries tokens. Must be http or https, max 2048 characters.
Response
Deep analysis result. The target URL was contacted. Typical latency 15-45 s, at most about 50 s.
Example response
{
"verdict_basis": [
"phishunt confirmed this host: verdict critical, score 95",
"confirmed by google_safebrowsing, openphish",
"12 prior detections on this root domain"
],
"probability": {
"status": "ok",
"p_malicious": 0.127,
"percent": 13,
"interval_80": [
0.079,
0.198
],
"band": "unlikely",
"relative_risk": 9.5,
"coverage": "passive_url_only",
"prior": 0.01342,
"evidence": [
{
"class": "url_shape",
"value": 72,
"llr": 2.74,
"direction": "toward_malicious"
},
{
"class": "external_feed",
"value": "none",
"llr": -0.39,
"direction": "toward_benign"
},
{
"class": "trusted_zone",
"value": "untrusted",
"llr": 0.03,
"direction": "neutral"
}
],
"not_evaluated": [],
"model_version": "2026-09-28.2",
"note": "At this API's ~1.3% base rate of malicious hosts among queried URLs, this estimate is 9.5x the base rate. URL-only estimate; the page was not fetched. Brand-less phishing is invisible to URL-only analysis."
},
"action": {
"reason": "deep_analyzed"
},
"deep_analysis": {
"not_evaluated": [
"visual_judge",
"campaigns",
"urlscan",
"ocr:off",
"render:timeout"
],
"detector_version": "2.0.0",
"analysis_failures": [
"not_fetched_yet (3 signals): brand_in_screenshot_text, favicon_kit_match, screenshot_clone_match"
],
"note": "risk_score is a heuristic risk score, not a calibrated probability",
"enrichment": "active via SOCKS5"
}
}Changes
No recorded changes to this operation across all 1 revision of this API.