Skip to main content

Overview

The Domain Analysis API performs deep reconnaissance on any domain, providing:
  • DNS record resolution (A, AAAA, MX, TXT, NS, CNAME, SOA)
  • WHOIS registration information
  • SSL/TLS certificate details
  • Security header analysis
  • Technology stack detection
  • HTTP response information
  • Subdomain enumeration (optional)
  • Reputation and threat intelligence
This endpoint uses Server-Sent Events (SSE) streaming to provide real-time progress updates as each analysis step completes.

Endpoint

POST /api/domain/analyze

Request

Headers

Content-Type: application/json

Body Parameters

domain
string
required
Domain name to analyze. Protocol, www prefix, paths, and ports are automatically removed.Examples:
  • "example.com"
  • "https://www.example.com/path" → cleaned to "example.com"
  • "subdomain.example.com:8080" → cleaned to "subdomain.example.com"
options
object
Analysis options

Request Example

curl -X POST http://localhost:3000/api/domain/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "options": {
      "includeSubdomains": true
    }
  }'

Response

The endpoint returns a Server-Sent Events (SSE) stream with Content-Type: text/event-stream.

Event Types

progress
object
Progress update during analysis
result
object
Partial result from a completed step
complete
object
Final complete analysis result
error
object
Error event

Complete Result Structure

DomainAnalysisResult
object

Response Example

{
  "type": "progress",
  "data": {
    "step": "Fetching WHOIS data",
    "total": 7,
    "completed": 2
  }
}

Error Responses

400
Domain required
{
  "success": false,
  "error": "Domain is required"
}
400
Invalid domain format
{
  "success": false,
  "error": "Invalid domain format"
}
500
Request failed
{
  "success": false,
  "error": "Request failed"
}

Source Code Reference

  • API Route: source/app/api/domain/analyze/route.ts:50
  • Domain Functions: source/lib/domain/
  • Type Definitions: source/lib/domain/types.ts

Performance Notes

Timeouts: Domain analysis can take 10-60 seconds depending on options.

Analysis Duration

  • Basic analysis (no subdomains): 5-10 seconds
  • With subdomain enumeration: 25-35 seconds
  • Subdomain timeout: 25 seconds (to prevent hanging)

Optimization Tips

  1. Disable subdomains for faster results
  2. Cache results to avoid redundant analyses
  3. Parallel requests are handled by the server
  4. Streaming updates provide real-time feedback

Best Practices

Recommendations

  1. Domain cleaning: Submit clean domains (protocol and path are auto-removed)
  2. Handle timeouts: Some steps may fail or timeout gracefully
  3. Cache wisely: Cache for 1-24 hours depending on use case
  4. Monitor SSL expiry: Alert when daysUntilExpiry < 30
  5. Security scoring: Flag domains with securityHeaders.score < 50

Example Implementation

interface DomainReport {
  domain: string;
  status: 'available' | 'registered';
  sslValid: boolean;
  sslExpiry?: string;
  securityScore: number;
  technologies: string[];
  riskLevel: 'safe' | 'suspicious' | 'dangerous';
}

async function analyzeDomainComplete(domain: string): Promise<DomainReport> {
  const response = await fetch('/api/domain/analyze', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ domain })
  });

  const reader = response.body!.getReader();
  const decoder = new TextDecoder();
  let result: any;

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const text = decoder.decode(value);
    const lines = text.split('\n');

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const event = JSON.parse(line.slice(6));
        if (event.type === 'complete') {
          result = event.data.result;
        }
      }
    }
  }

  // Generate report
  const report: DomainReport = {
    domain: result.domain,
    status: result.isAvailable ? 'available' : 'registered',
    sslValid: result.ssl?.isValid ?? false,
    sslExpiry: result.ssl?.validTo,
    securityScore: result.securityHeaders?.score ?? 0,
    technologies: result.technologies?.map((t: any) => t.name) ?? [],
    riskLevel: result.reputation?.isMalicious || result.reputation?.isPhishing
      ? 'dangerous'
      : result.reputation?.riskScore > 50
      ? 'suspicious'
      : 'safe'
  };

  return report;
}

Build docs developers (and LLMs) love