Signal-based domain risk indicator (0–100). Technical indicators only — no verdicts, no advice.
OpenAPI (fixed contract): openapi.yaml (download)
Current version: v2.1 (Changelog).
POST /risk-score
| Name | Type | Required | Description |
|---|---|---|---|
explain |
integer | No | Set to 1 to include explanations[] (one-line notes per signal). |
Note: explanations are designed for UI display and remain intentionally short.
Send your API key in the request header:
X-API-Key: YOUR_API_KEY
curl -X POST https://riskapi.analyses-web.com/risk-score?explain=1 \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"url":"https://example.com"}'
{
"url": "https://example.com"
}
Rules: absolute HTTP/HTTPS URLs only · max length 2048 · computed per domain · cached (default TTL 24h).
{
"riskScore": 12,
"riskLevel": "low",
"signals": [
"domain_age_lt_12_months",
"dns_caa_missing"
],
"version": "v2.1",
"meta": {
"cached": false,
"processingMs": 83,
"requestId": "b7f2d7b6d2d44d6aa0c96a5b1e9c7d7b",
"cacheHours": 24,
"scoringPolicy": "2026-01"
}
}
POST /risk-score?explain=1
{
"riskScore": 42,
"riskLevel": "medium",
"signals": [
"dns_spf_allows_all",
"dns_dmarc_missing",
"dns_caa_missing"
],
"version": "v2.1",
"meta": {
"cached": true,
"processingMs": 7,
"requestId": "d0b0d9b1b8a44a8c8a5c2b9c8f6d1a2c",
"cacheHours": 24,
"scoringPolicy": "2026-01"
},
"explanations": [
{
"signal": "dns_spf_allows_all",
"category": "risk",
"severity": "high",
"note": "Permissive SPF (+all or all without -/~/?all): makes email spoofing easier."
},
{
"signal": "dns_caa_missing",
"category": "informational",
"severity": "info",
"note": "CAA missing: very common; not meaningful on its own."
}
]
}
The score is a weighted sum of risk signals. Informational signals remain visible but do not increase the score.
| Score range | riskLevel |
|---|---|
| 0 – 24 | low |
| 25 – 49 | medium |
| 50 – 100 | high |
meta.scoringPolicy identifies the internal scoring band (weights/thresholds) used to compute the score.
| Signal | Category | What it indicates (short) |
|---|---|---|
domain_age_lt_6_months | risk | Domain appears recently created. |
domain_age_lt_12_months | risk | Domain appears relatively new. |
suspicious_keywords_in_domain | risk | Login/verify/billing-type keywords with context patterns. |
long_or_hyphenated_domain | informational | Length/hyphen pattern; weak on its own. |
dns_spf_missing | risk | No SPF policy found in TXT records. |
dns_spf_allows_all | risk | SPF effectively allows any sender (permissive “all”). |
dns_dmarc_missing | risk | No DMARC policy found at _dmarc. |
dns_dmarc_policy_none | informational | DMARC present but policy is monitoring-only (p=none). |
dns_caa_missing | informational | No CAA record (common); low signal strength. |
dns_no_mx_records | informational | No MX records; may be normal for some domains. |
dns_ns_count_high | informational | Unusually high NS count. |
dns_null_a_record | risk | A record resolves to 0.0.0.0 (often used for sinkholes/blocks). |
rdap_unavailable | informational | RDAP lookup failed/unavailable. |
registrar_missing_in_rdap | informational | Registrar name missing in RDAP response. |
whois_redacted_or_privacy | informational | Registrant data redacted/privacy indicated. |
recent_nameserver_or_delegation_change | risk | Recent NS/delegation change (short window). |
recent_rdap_update_unknown | informational | Recent RDAP update event (unknown action). |
recent_rdap_update_last_changed | informational | Recent RDAP event: “last changed”. |
recent_rdap_update_rdap_db | informational | Recent RDAP event: database update. |
recent_rdap_update_other | informational | Recent RDAP event: other action. |
cctld_registrant_country_mismatch | risk | ccTLD vs registrant country mismatch (best-effort). |
spamhaus_drop_listed_ip | risk | Resolved IP is listed in a DROP-style blocklist. |
drop_list_unavailable | informational | Blocklist check failed/unavailable. |
dns_lookup_failed | informational | DNS resolution/query failed for at least one lookup. |
shared_hosting_asn_listed | informational | IP maps to a high-density hosting ASN (only if ASN lookup is enabled). |
registrar_high_risk_listed | informational | Registrar name matches a heuristic list (weak; informational only). |
Signal IDs are stable. Informational signals have weight 0 and do not increase the score.
Requests are rate-limited per IP (no-key) and enforced per key (monthly quota).
When your key reaches its monthly quota, the API returns quota_exceeded (HTTP 429).
You can query your current monthly usage with GET /usage (requires API key header).
curl -s "https://riskapi.analyses-web.com/usage" \
-H "X-API-Key: YOUR_KEY"
| HTTP | error |
When |
|---|---|---|
| 400 | missing_url | Request body missing url. |
| 400 | url_too_long | URL exceeds maximum length. |
| 400 | invalid_url | Not an absolute HTTP/HTTPS URL. |
| 401 | missing_api_key | API key header missing. |
| 401 | invalid_api_key | Key not found or disabled. |
| 503 | auth_unavailable | Key store unavailable. |
| 429 | rate_limited | Per-IP rate limit exceeded (no-key). |
| 429 | quota_exceeded | Monthly quota exceeded (per key). |
All errors share the same JSON shape:
{
"error": "invalid_url",
"requestId": "..."
}
This API provides automated indicators derived from public technical signals. It does not provide security, legal, or financial advice. Accuracy is not guaranteed.