How to Detect a Parked Domain
You need to automatically detect parked or placeholder domains so you can block them from ad buys, flag them in your brand-safety rules, or avoid enriching junk signups in your CRM. By the end of this guide, you’ll have a reliable, production-ready way to detect parked domains using Klazify’s categorization endpoint, feed the result into your pipeline, and handle edge cases at scale.
Why Klazify is the right API for parked-domain detection
Parked domains look deceptively simple—often thin or templated content, ad-filled placeholders, or “for sale” notices—but they’re hard to catch with basic checks. Klazify combines real-time website content analysis with a robust categorization model and domain signals, giving you practical levers to detect parked and low-quality domains without maintaining your own crawlers.
- Accurate content analysis for parked-like patterns: Klazify’s machine learning analyzes full website content instead of relying on metadata. This allows you to detect signals typical of parked pages (thin content, generic landing templates, sparse navigation) when present in the page content you submit.
- Global coverage for international domains: Parked domains show up worldwide. Klazify analyzes content in multiple languages so you’re not blind to non-English placeholders.
- Real-time classification: Parked status can change quickly (for sale today, launched next week). The endpoint returns fresh analysis instead of an outdated table lookup, enabling timely decisions.
- IAB taxonomy mapping: When content exists, you get IAB-aligned categories you can plug into brand safety and ad placement workflows that speak IAB natively.
- Simple REST integration: A single POST to the categorization endpoint returns categorization and domain signals that your services can consume with minimal plumbing.
- Compliance and filtering: Whether you’re building a blocklist, enforcing category policies, or whitelisting vetted domains, Klazify’s categories and domain data help you implement deterministic filters.
What makes a domain “parked,” and how to infer it with Klazify
Klazify does not expose a dedicated “parked” boolean flag. Instead, you combine multiple fields to build a robust parked-domain heuristic. This gives you transparency and control over thresholds and failure modes.
- Content categories and confidence: Many parked pages have little or no meaningful content. If Klazify can’t extract specific content signals, categories may be sparse. When categories are present, check confidence scores: very low, generic, or inconsistent categories can indicate thin content.
- Domain registration signals: Recently registered domains with minimal content can be suspect, while very old domains with no present content are also candidates for parking. Use domain_age_date and domain_expiration_days_left as context, not as sole determinants.
- Logo and social signals: A missing logo_url and null social_media may correlate with low-quality or placeholder sites. Not definitive alone, but valuable as a supporting signal.
- Similar domains: If the API suggests only broad or unrelated similar sites, that might indicate the analyzed domain lacks distinctive topical content.
A practical, explainable heuristic
Consider a domain “likely parked” if most of the following are true:
- No or very generic categories, or unusually low confidence across categories.
- No logo_url and social_media is null.
- Domain registration data indicates either very new domains with no content signals or surprisingly old domains without active content (context-dependent).
- Similar domains do not cluster around a clear niche.
Because each business has different tolerances, keep your thresholds adjustable and log the contributing signals for auditing.
Make your first request
Use the categorization endpoint with a Bearer token. Failed or unreachable calls are not billed. The Starter plan is $39.99/mo with a 7-day trial so you can validate your detection logic before scaling.
curl -X POST "https://www.klazify.com/api/categorize" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://cbsnews.com"}'
To get an API key, create a free account here: Register. Review request/response details in the Documentation. You can also learn about supported models and categorization mapping in MCP.
Understand the response and extract parked-domain signals
Below is the official sample response format. Use it to see where parked-domain signals appear.
{
"domain": {
"categories": [
{
"confidence": 0.92,
"name": "/Computers & Electronics/Consumer Electronics",
"IAB-632-596": "Consumer Electronics/Technology & Computing/Consumer Electronics"
},
{
"confidence": 0.89,
"name": "/Internet & Telecom/Mobile & Wireless/Mobile Phones"
}
],
"social_media": null,
"logo_url": "https://klazify.s3.amazonaws.com/2110787991611585019600ed5fb1d1300.04730104.png"
},
"success": true,
"objects": {
"company": {
"url": "https://www.apple.com/",
"name": "Apple",
"city": "Cupertino",
"stateCode": "CA",
"countryCode": "US",
"employeesRange": "100K+",
"revenue": 274515000000,
"raised": null,
"tags": [
"E-commerce",
"Consumer Electronics",
"Mobile",
"B2C"
],
"tech": [
"omniture_adobe_analytics",
"atlassian_confluence",
"successfactors",
"apache_apex",
"talend",
"oracle_peoplesoft",
"salesforce",
"stripe",
"dell_boomi_atomsphere",
"gigya",
"sage_50cloud",
"quickbooks",
"webmethods",
"apache_tomcat",
"alteryx",
"tibco_rendezvous",
"atlassian_jira",
"..."
]
}
},
"domain_registration_data": {
"domain_age_date": "1987-02-19",
"domain_age_days_ago": "13026",
"domain_expiration_date": "2030-02-20",
"domain_expiration_days_left": "123"
},
"similar_domains": [
"bestbuy.com",
"icloud.com",
"microsoft.com",
"macrumors.com",
"google.com",
"samsung.com",
"twitter.com",
"hp.com",
"bhphotovideo.com",
"dell.com"
]
}
Fields you will use for parked detection and enrichment:
- domain.categories: A list with name and confidence per detected category. Use the presence, specificity, and confidence values as core signals.
- domain.social_media: If null, treat as a soft signal that the domain might be unestablished. Combine with other checks; many legitimate sites also choose not to link social profiles.
- domain.logo_url: A valid logo URL indicates a stronger brand footprint. Absence is a soft parked indicator.
- objects.company: When present, the domain likely represents an established entity. Use fields like name and url for enrichment, and tags/tech for product analytics or CRM enrichment flows.
- domain_registration_data: Use domain_age_date, domain_age_days_ago, domain_expiration_date, and domain_expiration_days_left as context—e.g., very new domains with no categories may be parked or under construction.
- similar_domains: Use as a sanity check. If similar domains cluster in a relevant niche, the domain likely has some topical footprint; otherwise, treat as weak evidence of low content.
- success: Verify the call succeeded before logging or acting on results.
Implement a parked-domain detector in code
The snippet below calls the same endpoint and computes a simple “parked_score.” Adjust thresholds to match your policies. Store both raw fields and computed signals to audit decisions later.
import requests
API_URL = "https://www.klazify.com/api/categorize"
API_KEY = "YOUR_API_KEY"
def fetch_klazify(url):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {"url": url}
r = requests.post(API_URL, json=payload, headers=headers, timeout=20)
r.raise_for_status()
return r.json()
def compute_parked_score(resp):
# Defensive reads
domain = resp.get("domain", {}) or {}
categories = domain.get("categories") or []
social = domain.get("social_media")
logo = domain.get("logo_url")
reg = resp.get("domain_registration_data", {}) or {}
similar = resp.get("similar_domains") or []
success = resp.get("success", False)
if not success:
# Unknown; treat conservatively (not parked) and retry later
return {"score": 0.0, "reason": ["unsuccessful_response"]}
# Heuristic components
signals = []
score = 0.0
# 1) Category presence and confidence
if not categories:
score += 0.4
signals.append("no_categories")
else:
low_conf = [c for c in categories if c.get("confidence", 1.0) < 0.4]
if len(categories) <= 1:
score += 0.15
signals.append("few_categories")
if low_conf:
score += 0.15
signals.append("low_confidence_categories")
# 2) Missing logo and social
if not logo:
score += 0.15
signals.append("no_logo")
if social is None:
score += 0.1
signals.append("no_social")
# 3) Domain registration context (do not overfit; treat as soft)
age_days = reg.get("domain_age_days_ago")
if age_days is not None:
try:
age_days = int(age_days)
# Very new domains: more likely to be parked/placeholder
if age_days < 45:
score += 0.15
signals.append("very_new_domain")
except ValueError:
pass
# 4) Similar domains breadth (weak evidence)
if similar and len(similar) <= 2:
score += 0.05
signals.append("few_similar_domains")
return {"score": round(min(score, 1.0), 2), "reason": signals}
if __name__ == "__main__":
test_url = "https://example.com"
data = fetch_klazify(test_url)
parked = compute_parked_score(data)
print({"url": test_url, **parked})
How to interpret the parked score:
- Low score: Content is present and categorized with confidence; likely not parked.
- Mid score: Potential placeholder or under construction; route to manual review or soft block.
- High score: Likely parked; block from ad placements, mark as low-priority lead, or exclude from enrichment.
Operational details for production pipelines
Batching, concurrency and rate limits
When classifying domains at scale, send requests in batches and apply client-side concurrency control. Use backoff on HTTP failures. Keep per-domain retries low to avoid reprocessing the same failing inputs. Failed or unreachable calls are not billed, but you still want to efficiently manage retries to reduce latency and noise.
Caching and TTLs
- Domain-level caching: Cache categorization and domain_registration_data per domain. Most domains don’t change frequently; refresh on a schedule or on-demand when your pipeline flags anomalies.
- Invalidation: Refresh if last fetch failed, or if the domain is newly observed in your traffic/events.
- Partial caching: Even if some fields are missing (e.g., social_media), cache the response and annotate gaps. Recheck later to capture improvements as the site evolves.
Handling unknown or newly created domains
- Unsuccessful or minimal responses: Treat as “unknown” and schedule a recheck (e.g., next day or next crawl cycle) rather than defaulting to parked or safe. Log the response with success and reason codes if you maintain them.
- Graceful degradation: If you can’t categorize confidently, fall back to stricter policies for ad placements and to limited enrichments for CRM entries.
Mapping to your taxonomy
Klazify provides category names and, where available, IAB mappings. If your internal taxonomy differs, maintain a mapping table from Klazify category names or IAB labels to your codes. Store both the raw category path and confidence so that you can revisit historical decisions if your mapping evolves.
Auditability and explainability
- Record raw fields: domain.categories (with confidence), domain.social_media, domain.logo_url, domain_registration_data, similar_domains, and success.
- Record computed signals: “no_categories,” “low_confidence_categories,” “no_logo,” “no_social,” etc. Keep an array of reasons for every decision.
- Human review: For high-value flows (e.g., large ad budgets), route mid-score domains to review before permanent blocking.
Deciding actions for common workflows
Brand safety and ad placement
- Block: High parked score, or no categories with absent logo and social signals. Avoid spending impressions on likely parked/placeholder domains.
- Allow: Clear categories with strong confidence, present logo_url, and coherent similar_domains.
- Review: Conflicting indicators or borderline scores.
Signup enrichment and CRM hygiene
- Defer enrichment: If a submitted domain looks parked, skip expensive enrichment steps and set a retry flag.
- Lead scoring: Deduct points for parked-like signals to prevent your sales teams from chasing low-quality accounts.
Security and content filtering
- Policy routing: Unknown or parked-like domains can be subject to restricted access on corporate networks until they accumulate credible content signals.
- Alerting: High-throughput sudden appearances of new, parked-like domains in network logs can be interesting for security analytics.
A compact signal comparison table
Use the table below to decide how to weigh each response field when inferring a parked domain. The exact weights will depend on your tolerance for false positives/negatives.
| Response Field | Signal When Present | Signal When Missing/Weak | How to Use |
|---|---|---|---|
| domain.categories | Specific, consistent categories with reasonable confidence indicate active content. | No categories or very generic/low-confidence categories suggest thin or placeholder content. | Primary determinant; feed confidence into your score. |
| domain.logo_url | Brand presence; often correlates with a real site. | Soft parked signal; some legit sites may omit logos. | Use as a secondary boost/penalty. |
| domain.social_media | Non-null indicates external presence. | null is a soft parked indicator. | Use as tie-breaker alongside categories. |
| domain_registration_data | Older domains with clear content reduce parked likelihood. | Very new domains with weak content increase parked likelihood. | Use as context; avoid relying on age alone. |
| similar_domains | Clustered, topical neighbors reinforce legitimacy. | Few or incoherent neighbors weakly suggest low content. | Apply small adjustments only. |
| success | Process the result normally. | Do not decide; queue for retry. | Controls your “unknown” handling. |
Batch classification and pipeline integration
Input sanitization
- Normalize to a canonical domain/URL form before calling the API.
- Deduplicate within the batch to avoid redundant calls.
Batch processing flow
- Partition inputs: Group by domain to maximize cache hits.
- Concurrency: Use a small worker pool to stay within service policies and to avoid transient throttling.
- Backoff: On HTTP or network errors, retry with exponential backoff and jitter. Mark items for later replay if retries exceed your limit.
Data storage and refresh policy
- Persist the raw JSON response so you can re-score as your heuristics improve without re-calling the API.
- Store a computed parked score, reasons array, and the evaluation timestamp.
- Refresh domains periodically or on-demand when business events require it (e.g., ad campaign activation).
End-to-end example: integrating into an ad placement audit
Goal: Exclude likely parked domains from a campaign’s allowlist.
- Extract all unique domains from your inventory or supply-path feed.
- For each domain, check your cache:
- Cached and fresh: Use stored score/decision.
- Missing/stale: Call the categorization endpoint.
- Compute a parked score using the fields described above.
- Thresholds:
- Score ≥ high threshold: Remove from allowlist.
- Low ≤ score < high: Queue for analyst review.
- Score < low: Keep in allowlist.
- Log the decision with raw fields and reasons for audit trails.
Cost control and measurement
- Trial and validation: The Starter plan is $39.99/mo with a 7-day trial, suitable for validating your heuristic at low cost.
- Avoid wasted calls: Cache per domain, deduplicate input, and prefilter obvious junk (e.g., malformed hosts).
- Not billed on failure: Because failed or unreachable calls are not billed, you can safely retry transient issues but still keep retries bounded.
Testing strategy
- Golden sets: Build a labeled set of known parked vs. active domains from your traffic history to tune thresholds.
- A/B policy: Gradually enforce the block in shadow mode, logging which domains would be blocked, before activating the policy live.
- Drift monitoring: Re-score a sample of previously parked domains over time to detect when they launch real content.
Practical tips that save time
- Per-domain lock: When multiple jobs request the same domain simultaneously, coalesce them to a single API call.
- UTC timestamps: When you store evaluation timestamps, use UTC for consistency across services.
- Traceability: Include the input URL, normalized domain, request ID, and response hash in your logs to simplify debugging.
FAQ
Does Klazify return a parked flag?
No. The categorization endpoint returns content categories, confidence, domain signals (e.g., logo_url, social_media), domain registration data, and similar domains. Combine these to infer parked status using your own thresholds.
What should I do if a domain is unreachable or the call fails?
Failed or unreachable calls are not billed. Mark the domain as “unknown,” schedule a retry, and avoid making a blocking decision until you receive a successful response.
How do I handle newly registered domains?
Treat very new domains without clear categories as higher risk. Use domain_registration_data for context and recheck after a cooling period to avoid permanent misclassification.
Can I map Klazify categories to my internal taxonomy?
Yes. Use the returned category name and, when present, IAB mapping to build a translation table to your internal codes. Keep the original values and confidence for auditability.
How often should I refresh a domain’s classification?
Refresh on a schedule that aligns with your risk tolerance and business events—e.g., before launching an ad campaign, when a domain’s score is borderline, or when you detect significant site changes.
Ready to build your parked-domain detector and plug it into your pipeline? Create a free account to get your API key: Register. For endpoint details and examples, see the Documentation and learn more about categorization models in MCP.
Ready to use Klazify?
Start classifying websites, enriching company data, and exploring web intelligence.
Get Started Free