Exposure Scanner
/api/v1/exposure/scanScan a domain or IP address for attack surface exposure. Discovers subdomains, open ports, SSL certificates, DNS records, WHOIS data, network intelligence, and known vulnerabilities using 11 intelligence providers.
exposure:read
10 fresh / 0 cached
Starter, Professional, Enterprise
Up to 180 seconds
Request Body
{
"target": "example.com",
"target_type": "auto"
}| Field | Type | Description |
|---|---|---|
| target | string | Domain name or IP address to scan (required) |
| target_type | string | "domain", "ip", or "auto" (optional — default: auto-detect) |
Response
{
"data": {
"cached": false,
"scan_id": "jd72k8m0x9...",
"target": "example.com",
"targetType": "domain",
"status": "completed",
"riskScore": 42,
"riskLevel": "medium",
"subdomains": [
{ "subdomain": "www.example.com", "source": "crt.sh", "isLive": true },
{ "subdomain": "mail.example.com", "source": "crt.sh, hackertarget" },
{ "subdomain": "api.example.com", "source": "securitytrails" }
],
"ports": [
{ "host": "93.184.216.34", "port": 22, "protocol": "tcp", "state": "open", "service": "ssh", "product": "OpenSSH", "version": "8.9p1", "source": "shodan" },
{ "host": "93.184.216.34", "port": 80, "protocol": "tcp", "state": "open", "service": "http", "product": "nginx", "version": "1.24.0", "source": "shodan, criminalip" },
{ "host": "93.184.216.34", "port": 443, "protocol": "tcp", "state": "open", "service": "https", "product": "nginx", "version": "1.24.0", "source": "shodan" }
],
"certificates": [
{
"host": "example.com",
"port": 443,
"subject": "*.example.com",
"issuer": "R3",
"issuerOrg": "Let's Encrypt",
"validFrom": "2026-01-15T00:00:00Z",
"validTo": "2026-04-15T00:00:00Z",
"isExpired": false,
"keySize": 2048,
"signatureAlgorithm": "SHA256withRSA",
"sans": ["*.example.com", "example.com"],
"grade": "A",
"source": "ssllabs"
}
],
"dns": [
{ "domain": "example.com", "recordType": "A", "values": ["93.184.216.34"], "ttl": 3600, "source": "hackertarget" },
{ "domain": "example.com", "recordType": "MX", "values": ["10 mail.example.com"], "source": "hackertarget" },
{ "domain": "example.com", "recordType": "NS", "values": ["ns1.example.com", "ns2.example.com"], "source": "hackertarget" }
],
"whois": {
"domain": "example.com",
"registrar": "ICANN",
"createdDate": "1995-08-14T04:00:00Z",
"expiryDate": "2027-08-13T04:00:00Z",
"updatedDate": "2024-08-14T07:01:44Z",
"nameservers": ["ns1.example.com", "ns2.example.com"],
"source": "WhoisXML"
},
"network": [
{ "ip": "93.184.216.34", "asn": 15133, "asnName": "Edgecast", "country": "US", "source": "ipapi, bgpview" }
],
"vulnerabilities": [
{
"host": "93.184.216.34",
"port": 443,
"cveId": "CVE-2023-44487",
"cvssScore": 7.5,
"severity": "high",
"description": "HTTP/2 Rapid Reset Attack",
"affectedProduct": "nginx/1.24.0",
"source": "shodan"
}
],
"providers": [
{ "name": "crt.sh", "status": "complete", "durationMs": 1200, "categories": ["subdomains"] },
{ "name": "shodan", "status": "complete", "durationMs": 890, "categories": ["ports", "vulnerabilities"] },
{ "name": "ssllabs", "status": "complete", "durationMs": 9500, "categories": ["certificates"] }
],
"stats": {
"subdomainCount": 3,
"openPortCount": 3,
"certificateCount": 1,
"vulnerabilityCount": 1,
"criticalVulnCount": 0,
"highVulnCount": 1
},
"scannedAt": "2026-03-20T14:23:01Z",
"durationMs": 12847
},
"meta": {
"request_id": "req_a1b2c3d4-...",
"credits_used": 10,
"credits_remaining": 490,
"processing_time_ms": 12903
}
}| Field | Type | Description |
|---|---|---|
| data.cached | boolean | Whether this result was served from cache (0 credits if true) |
| data.scan_id | string | Unique Convex document ID for this scan result |
| data.target | string | The normalized target that was scanned |
| data.targetType | string | "domain" or "ip" |
| data.status | string | "completed", "partial" (some providers failed), or "failed" |
| data.riskScore | number | Overall risk score from 0 (safe) to 100 (critical exposure) |
| data.riskLevel | string | "info", "low", "medium", "high", or "critical" |
| data.subdomains | array | Discovered subdomains with source provider, resolved IPs, and live status |
| data.ports | array | Open ports with host, protocol, state, service, product, version, and banner |
| data.certificates | array | SSL/TLS certificates with issuer, validity, key size, SANs, grade, and TLS vulnerabilities |
| data.dns | array | DNS records as typed entries (A, AAAA, MX, NS, TXT, CNAME, etc.) with TTL |
| data.whois | object | null | WHOIS registration data including registrar, dates, name servers, and DNSSEC status |
| data.network | array | Network intelligence — ASN, CIDR, geolocation, hosting/VPN/proxy/Tor flags |
| data.vulnerabilities | array | Known CVEs matched against discovered service versions with CVSS scores |
| data.providers | array | Per-provider status objects with name, status, duration, and data categories |
| data.stats | object | Summary counts: subdomainCount, openPortCount, certificateCount, vulnerabilityCount, criticalVulnCount, highVulnCount |
| data.scannedAt | string | Timestamp of the scan in ISO 8601 format |
| data.durationMs | number | Total scan duration in milliseconds |
| meta.request_id | string | Unique request identifier for support and debugging |
| meta.credits_used | number | Credits consumed (10 for fresh scan, 0 for cache hit) |
| meta.credits_remaining | number | Remaining credit balance after this request |
| meta.processing_time_ms | number | Server-side processing time in milliseconds |
Intelligence Providers
Each scan queries multiple intelligence providers to build a comprehensive picture of the target's attack surface. Provider availability may vary; partial results are returned if some providers are unreachable.
| Provider | Data Collected |
|---|---|
| crt.sh | Certificate Transparency logs — discovers subdomains from issued SSL certificates |
| hackertarget | DNS lookups, reverse DNS, and host search for subdomain enumeration |
| criminalip | IP threat intelligence — open ports, banners, and risk scoring |
| shodan | Open ports, service banners, device fingerprinting, and known CVEs |
| ipapi | IP geolocation — country, city, ASN, and hosting/VPN/proxy detection |
| bgpview | BGP routing data — ASN ownership, network CIDR, and prefix information |
| ssllabs | SSL/TLS certificate analysis, grading, and protocol vulnerability detection |
| netlas | Internet-wide scan data for hosts, open ports, and service detection |
| securitytrails | Subdomains, DNS history, and associated domains |
| WhoisXML | WHOIS registration data, registrar info, expiry dates, and name servers |
| OTX Passive DNS | AlienVault OTX passive DNS resolution and indicator correlation |
Caching
Results are cached for 24 hours. Subsequent scans of the same target within 24 hours return cached results. The response includes "cached": true when serving from cache.
Cached results cost 0 credits. Credits are only deducted for fresh scans. To force a fresh scan, wait for the cache to expire.
Code Examples
curl -X POST https://api.dfir-lab.ch/v1/exposure/scan \
-H "Authorization: Bearer sk-dfir-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"target": "example.com",
"target_type": "auto"
}'import requests
url = "https://api.dfir-lab.ch/v1/exposure/scan"
headers = {
"Authorization": "Bearer sk-dfir-your-key-here",
"Content-Type": "application/json",
}
response = requests.post(
url,
json={"target": "example.com", "target_type": "auto"},
headers=headers,
)
body = response.json()
scan = body["data"]
meta = body["meta"]
print(f"Risk score: {scan['riskScore']}/100 ({scan['riskLevel']})")
print(f"Subdomains found: {len(scan['subdomains'])}")
print(f"Open ports: {len(scan['ports'])}")
print(f"Vulnerabilities: {len(scan['vulnerabilities'])}")
print(f"Scan duration: {scan['durationMs']}ms")
print(f"Credits used: {meta['credits_used']}")
for vuln in scan["vulnerabilities"]:
print(f" [{vuln['severity']}] {vuln['cveId']}: {vuln.get('description', '')}")Important Notes
- Scans can take up to 3 minutes to complete. All providers are queried in parallel, but SSL Labs analysis is the slowest — the endpoint waits for all providers before returning the aggregated result.
- Private and internal IP addresses (
10.x.x.x,192.168.x.x,172.16-31.x.x,127.0.0.1) are blocked and will return a400 Bad Request. - Rate limits apply per API key: 3 scans/min (Starter), 10 scans/min (Professional). Enterprise plans have configurable limits.