Domain Portfolio Automation at Scale: Bulk WHOIS Audits and Drift Detection
Stop managing your domain portfolio in spreadsheets. This guide covers automated WHOIS audits, expiration tracking, DNS drift detection, and webhook alerting for teams managing hundreds or thousands of domains.
Why Spreadsheets Fail at Portfolio Scale
A company with 50 domains can track renewals in a spreadsheet. At 500 domains, the spreadsheet becomes a liability. Registrars change, name servers migrate, SSL certificates expire on different schedules, and DNS records drift as teams make ad-hoc changes. Nobody notices until a domain expires and the website goes dark, or until a DNS misconfiguration causes an outage.
The operational cost is not just the risk of outages. Audits for SOC 2, ISO 27001, and similar frameworks require documented evidence that someone is actively monitoring domain ownership, registration status, and DNS configuration. Manual spot-checks do not satisfy auditors. An automated system that runs daily, logs every check, and alerts on anomalies does.
The Automation Architecture
A domain portfolio automation system has four layers, each running on a different schedule and querying different API endpoints. All four layers share one API key and one dashboard, which is the main advantage of using a unified platform over stitching together separate WHOIS, DNS, and SSL providers.
| Layer | API Calls | Schedule | Alert Trigger |
|---|---|---|---|
| Expiration Monitoring | WHOIS lookup per domain | Daily | 90 / 60 / 30 days before expiry |
| DNS Drift Detection | DNS lookup per domain | Hourly or daily | Record change vs. baseline |
| SSL Certificate Tracking | SSL check per domain | Daily | 30 / 14 / 7 days before expiry |
| Ownership Audit | WHOIS + DNS per domain | Weekly | Registrar or registrant change |
Workflow 1: Automated Expiration Monitoring
The most critical workflow. A domain expiration goes unnoticed until the domain stops resolving. By then, email stops working, the website returns NXDOMAIN, and recovery requires emergency registrar contact. The automation runs a daily bulk WHOIS query against the full portfolio, compares expiration dates against configured thresholds, and fires alerts.
// expiration-monitor.ts
// Daily bulk WHOIS audit for domain expiration tracking
interface DomainRecord {
domain: string;
registrar: string;
expirationDate: string;
lastChecked: string;
status: 'ok' | 'warning' | 'critical' | 'expired';
}
const EXPIRY_THRESHOLDS = {
critical: 30, // 30 days
warning: 90, // 90 days
};
function classifyExpiry(expirationDate: string): DomainRecord['status'] {
const daysUntilExpiry = Math.ceil(
(new Date(expirationDate).getTime() - Date.now()) / (1000 * 60 * 60 * 24)
);
if (daysUntilExpiry <= 0) return 'expired';
if (daysUntilExpiry <= EXPIRY_THRESHOLDS.critical) return 'critical';
if (daysUntilExpiry <= EXPIRY_THRESHOLDS.warning) return 'warning';
return 'ok';
}
async function auditPortfolio(domains: string[]): Promise<DomainRecord[]> {
const API_KEY = process.env.OPS_TOOLS_API_KEY;
const results: DomainRecord[] = [];
// Process in batches to respect rate limits
const batchSize = 50;
for (let i = 0; i < domains.length; i += batchSize) {
const batch = domains.slice(i, i + batchSize);
const batchResults = await Promise.allSettled(
batch.map(async (domain) => {
const res = await fetch(
`https://api.ops.tools/v1/whois/${domain}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const data = await res.json();
return {
domain,
registrar: data.registrar ?? 'unknown',
expirationDate: data.expirationDate,
lastChecked: new Date().toISOString(),
status: classifyExpiry(data.expirationDate),
} satisfies DomainRecord;
})
);
for (const result of batchResults) {
if (result.status === 'fulfilled') {
results.push(result.value);
}
}
// Throttle between batches
if (i + batchSize < domains.length) {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return results;
}The audit results feed directly into your alerting system. Critical and expired domains trigger immediate Slack or PagerDuty notifications. Warning domains generate a weekly digest. All results write to a database for trend analysis and compliance reporting.
Workflow 2: DNS Drift Detection
DNS drift happens when records change outside of a controlled change process. An engineer updates an A record directly in the registrar console instead of through infrastructure-as-code. A marketing team adds a CNAME for a campaign landing page. A third-party SaaS provider changes their integration endpoints. These changes are often invisible until something breaks.
Drift detection works by establishing a baseline of DNS records for each domain, then comparing live API results against the baseline on a scheduled interval. Changes that do not match a known change request get flagged.
// drift-detector.ts
// Compare live DNS records against stored baseline
interface DriftResult {
domain: string;
recordType: string;
expected: string[];
actual: string[];
driftType: 'added' | 'removed' | 'changed';
}
async function detectDnsDrift(domain: string): Promise<DriftResult[]> {
const API_KEY = process.env.OPS_TOOLS_API_KEY;
const recordTypes = ['A', 'AAAA', 'MX', 'CNAME', 'TXT', 'NS'];
const drifts: DriftResult[] = [];
for (const recordType of recordTypes) {
const res = await fetch(
`https://api.ops.tools/v1/dns/lookup?domain=${domain}&recordType=${recordType}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const data = await res.json();
const actualRecords = data.records?.[recordType] ?? [];
// Load baseline from your config store or last-known-good state
const baseline = await getBaseline(domain, recordType);
const expectedRecords = baseline ?? [];
const added = actualRecords.filter((r: string) => !expectedRecords.includes(r));
const removed = expectedRecords.filter((r: string) => !actualRecords.includes(r));
if (added.length > 0) {
drifts.push({ domain, recordType, expected: expectedRecords, actual: actualRecords, driftType: 'added' });
}
if (removed.length > 0) {
drifts.push({ domain, recordType, expected: expectedRecords, actual: actualRecords, driftType: 'removed' });
}
}
return drifts;
}Workflow 3: SSL Certificate Lifecycle Tracking
SSL certificates expire on fixed dates, and unlike domain renewals, there is no mandatory registrar grace period. An expired certificate means immediate browser warnings and broken API connections. For organizations with hundreds of domains, tracking certificate validity manually is not feasible.
// ssl-audit.ts
// Bulk SSL certificate validation across the portfolio
interface SslAuditResult {
domain: string;
issuer: string;
validFrom: string;
validTo: string;
daysRemaining: number;
isExpired: boolean;
isSelfSigned: boolean;
status: 'valid' | 'expiring-soon' | 'expired' | 'self-signed';
}
async function auditSslCertificates(domains: string[]): Promise<SslAuditResult[]> {
const API_KEY = process.env.OPS_TOOLS_API_KEY;
const results: SslAuditResult[] = [];
for (const domain of domains) {
const res = await fetch(
`https://api.ops.tools/v1/ssl/check?domain=${domain}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const data = await res.json();
const daysRemaining = Math.ceil(
(new Date(data.validTo).getTime() - Date.now()) / (1000 * 60 * 60 * 24)
);
let status: SslAuditResult['status'] = 'valid';
if (data.isSelfSigned) status = 'self-signed';
else if (daysRemaining <= 0) status = 'expired';
else if (daysRemaining <= 30) status = 'expiring-soon';
results.push({
domain,
issuer: data.issuer ?? 'unknown',
validFrom: data.validFrom,
validTo: data.validTo,
daysRemaining,
isExpired: daysRemaining <= 0,
isSelfSigned: data.isSelfSigned ?? false,
status,
});
}
return results.sort((a, b) => a.daysRemaining - b.daysRemaining);
}The SSL audit surfaces a prioritized list sorted by days remaining. Domains with fewer than 14 days get immediate alerts. Self-signed certificates flag separately because they may be intentional (internal services) or accidental (misconfigured deployment).
Quick Reference: cURL Commands for Portfolio Audits
# WHOIS lookup for a single domain curl -s "https://api.ops.tools/v1/whois/example.com" \ -H "Authorization: Bearer YOUR_API_KEY" # DNS record check for drift detection curl -s "https://api.ops.tools/v1/dns/lookup?domain=example.com&recordType=A,MX,TXT,NS" \ -H "Authorization: Bearer YOUR_API_KEY" # SSL certificate validation curl -s "https://api.ops.tools/v1/ssl/check?domain=example.com" \ -H "Authorization: Bearer YOUR_API_KEY" # Reverse IP lookup for shared hosting detection curl -s "https://api.ops.tools/v1/ip/reverse?ip=93.184.216.34" \ -H "Authorization: Bearer YOUR_API_KEY"
Compliance Reporting Without the Manual Work
Automated portfolio audits produce exactly the evidence that SOC 2, ISO 27001, and GDPR auditors want to see: timestamped records showing that domain ownership, DNS configuration, and SSL certificate status are being monitored continuously. Here is what the automated audit covers for each framework.
| Framework | Requirement | Automation Coverage |
|---|---|---|
| SOC 2 Type II | CC6.1 - Logical access security | DNS drift detection + SSL validity monitoring |
| ISO 27001 | A.12.2.1 - Information systems audit | Full portfolio WHOIS + DNS + SSL audit logs |
| GDPR | Article 32 - Security of processing | SSL/TLS certificate monitoring across all data-handling domains |
Store audit results with timestamps in a structured format (JSON lines, database rows, or CSV exports). When the auditor requests evidence, you provide a report covering the audit period with per-domain check results, drift incidents, and remediation actions taken.
Webhook Alerting for Real-Time Response
Batch audits catch most issues, but some events need immediate attention. WHOIS registrant changes, DNS record modifications, and SSL certificate re-issuance can indicate unauthorized activity. Webhook notifications deliver these events as they happen, enabling your team to respond within minutes rather than waiting for the next scheduled audit.
Configure webhooks to send alerts to your existing notification channels: Slack for team visibility, PagerDuty for on-call escalation, or a custom webhook endpoint that routes to your incident management system. Each webhook payload includes the domain, the change type, the previous and current values, and a timestamp.
Frequently Asked Questions
How many domains can I audit with a bulk WHOIS API?
With ops.tools, bulk WHOIS queries can process thousands of domains per session. Throughput depends on plan tier, concurrency limits, and response time per domain. Start with a batch of 100 domains to calibrate timing, then scale up based on your plan quota and desired completion window.
What is infrastructure drift detection for domains?
Infrastructure drift detection monitors DNS records, name servers, SSL certificates, and IP configurations for unexpected changes. When a domain's DNS records change without a corresponding change request, or when an SSL certificate is replaced by a different issuer, the system flags it as potential drift requiring investigation.
How do I set up domain expiration alerts?
Run a daily or weekly bulk WHOIS query against your full domain portfolio. Compare each domain's expiration date against your alert thresholds (typically 90, 60, and 30 days before expiry). Configure webhook notifications to fire alerts to Slack, PagerDuty, or your incident management tool when a domain crosses a threshold.
What compliance requirements does domain portfolio automation help with?
Automated domain audits support SOC 2, ISO 27001, and similar compliance frameworks by maintaining an auditable record of domain ownership, registration status, DNS configuration changes, and SSL certificate validity across the entire portfolio. Automated reports replace manual spreadsheets and provide evidence of ongoing monitoring.
Continue Reading
Automate Your Domain Portfolio Today
DNS, WHOIS, SSL, and IP geolocation under one API key with bulk processing and webhook support. Plans starting at $6.99/month.
Related Articles
Domain Data API Buyer’s Guide 2026: What to Evaluate Before You Commit
Evaluation framework for choosing between DNS, WHOIS, IP geolocation, and SSL certificate APIs. Covers pricing models, SLA criteria, bulk processing, and hidden costs vendors rarely advertise.
Read ArticleHow Security Teams Enrich Alerts with DNS, WHOIS, and IP Data in 2026
Practical workflow for enriching SIEM alerts, SOC triage, and incident response with DNS record data, WHOIS registration intelligence, and IP geolocation using infrastructure APIs.
Read ArticleSSL Certificate Checker: Complete Guide to SSL Verification
Learn how to check SSL certificate validity, understand SSL errors, and monitor certificate expiration. Includes automation examples with the Ops.Tools API.
Read Article