Domain Extractor Grouper
Pricing
from $1.95 / 1,000 domain extracteds
Domain Extractor Grouper
Extract, normalize, and group root domains from URLs, emails, and mixed text. Export account-level domain groups, counts, source traces, and reports.
Pricing
from $1.95 / 1,000 domain extracteds
Rating
0.0
(0)
Developer
junipr
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Store Positioning
Store title: Domain Extractor Grouper
Short description: Extract, normalize, and group root domains from URLs, emails, and mixed text. Export account-level domain groups, counts, source traces, and reports.
SEO title: Domain Extractor Grouper — fast deterministic data utility
SEO description: Extract, normalize, and group root domains from URLs, emails, and mixed text. Export account-level domain groups, counts, source traces, and reports. Use it for fast, low-cost normalization or validation at scale with predictable pay-per-event pricing.
Categories: SEO_TOOLS, DEVELOPER_TOOLS
Keywords: domain, extractor, grouper, tiny deterministic utility
Pay-Per-Event Pricing
This actor uses pay-per-event pricing. Event prices include Apify platform usage; users are not expected to pay a separate platform-usage pass-through charge for the configured pricing model.
- Primary event:
domain-extractedat $0.00195 base
Event set:
actor-start: $0.00176 when run setup is accepted.domain-extracted: $0.00195 for each root-domain group emitted to the dataset.report-generated: $0.02000 when grouped JSON, summary, and Markdown files are created.
Public Task Concepts
- Normalize Domain Extractor Grouper records
- Validate Domain Extractor Grouper values in bulk
- Generate a small utility report for Domain Extractor Grouper
- Group lead records by root domain
- Map subdomains to parent domains
What does Domain Extractor Grouper do?
Domain Extractor Grouper turns messy URLs, email addresses, and free-text notes into clean root-domain groups. It is built for lead lists, CRM exports, enrichment queues, partner inventories, SEO research, and any workflow where sales@sub.example.com, https://www.example.com/path, and docs.example.com should roll up to example.com.
Key features:
- Extract domains from URL fields, email fields, and mixed text fields in the same run.
- Normalize hosts by removing protocol, path, port, query, common
wwwprefixes, and casing differences. - Group by root domain with support for common multi-part suffixes such as
co.uk,com.au, andco.jp. - Return source IDs, subdomains, counts by source type, and source match examples for traceability.
- Run deterministically with no network calls, no scraping, and no external paid APIs.
Why Use This Actor
Most domain cleanup starts as a brittle spreadsheet formula or one-off script. This actor packages the repeatable parts into an Apify-ready utility that can run from the Console, API, schedules, or webhooks.
| Capability | Domain Extractor Grouper | Spreadsheet regex formulas | Ad hoc parsing scripts |
|---|---|---|---|
| URL, email, and free text in one run | Yes | Usually manual | Depends on script |
| Root-domain grouping | Built in | Hard to maintain | Requires custom code |
| Multi-part suffix handling | Common suffixes included, user-extensible | Rare | Depends on library |
| Source traceability | Source IDs and match examples | Manual columns | Depends on script |
| Deterministic offline execution | Yes, no network calls | Yes | Usually yes |
| Apify dataset and KVS artifacts | Included | No | Requires custom integration |
| Cost per 1,000 groups | $1.95 | Tool-dependent | Maintenance time |
Use it when the output needs to be consumed by another actor, API job, CRM import, enrichment process, or QA checklist. It is intentionally narrow: it does not enrich companies, call WHOIS, resolve DNS, or score domains. It extracts and groups what is already present in your data.
How to Use
Start with the default input or paste a small list of records:
{"inputItems": [{"sourceId": "lead-001","website": "https://www.Example.com/pricing","email": "Sales@Example.com","notes": "Docs are at docs.example.com"}],"maxItems": 100,"includeReport": true}
- Open the actor and paste records into
inputItems, or provide a single free-text block intext. - Confirm the URL, email, and mixed-text field names match your input.
- Run the actor from the Console, API, schedule, or webhook.
- Read domain groups from the default dataset.
- Download
DOMAIN_SUMMARY.json,DOMAIN_GROUPS.json, orDOMAIN_REPORT.mdfrom the key-value store when report generation is enabled.
CRM account grouping
Map website, email, and notes from exported lead records. Use rootDomain as the account key and sourceIds to trace grouped contacts back to their source rows.
Research note cleanup
Paste a notes block into text or pass string inputItems. The actor extracts URLs, emails, and bare domains from the text without calling external services.
Custom suffix handling
If your data uses a private or uncommon suffix, add it to knownMultiPartSuffixes. The actor appends your suffixes to its built-in deterministic suffix list.
Input Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
inputItems | array | Included fixture rows | Strings or row objects to scan. |
text | string | Empty | Fallback free text used when inputItems is empty. |
urlFields | string array | url, website, site, homepage, sourceUrl, profileUrl | Fields parsed as URLs or website/domain values. |
emailFields | string array | email, emails, contactEmail, ownerEmail, supportEmail | Fields parsed as email addresses or email lists. |
textFields | string array | text, notes, description, body, content, message | Fields scanned for URLs, emails, and bare domains. |
extractFromAllStringFields | boolean | false | Scan unmapped string fields as mixed text. |
includeSubdomains | boolean | true | Include normalized subdomains seen for each root domain. |
includeSamples | boolean | true | Include source match examples in dataset rows. |
maxSamplesPerDomain | integer | 5 | Caps source match examples stored per root-domain group. |
knownMultiPartSuffixes | string array | [] | Extra suffixes used for root-domain reduction. |
maxItems | integer | 100 | Maximum input items to scan, capped at 50,000. |
includeReport | boolean | true | Write JSON and Markdown report artifacts to KVS. |
debug | boolean | false | Enable verbose logs. |
Output Format
Each dataset row is one root-domain group:
{"groupId": "c984d06aafbecf6b","rootDomain": "example.com","status": "grouped","totalMatches": 4,"uniqueNormalizedHosts": 3,"urlMatches": 2,"emailMatches": 1,"textMatches": 1,"sourceItemCount": 2,"sourceIds": ["lead-001", "item-2"],"firstSeenItemIndex": 0,"lastSeenItemIndex": 2,"subdomains": ["docs.example.com", "sub.example.com"],"sampleMatches": [{"sourceType": "url","field": "website","sourceItemIndex": 0,"sourceId": "lead-001","originalValue": "https://www.Example.com/pricing","normalizedHost": "example.com","rootDomain": "example.com"}],"issueCount": 0,"issues": [],"processedAt": "2026-07-02T00:00:00.000Z","recommendation": "Use this root domain as an account-level key across email and website records."}
Report artifacts:
DOMAIN_GROUPS.json: full grouped output.DOMAIN_SUMMARY.json: run-level counts and top root domains.DOMAIN_REPORT.md: compact Markdown summary for QA or delivery notes.
Integration Examples
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('junipr/domain-extractor-grouper').call({inputItems: [{ sourceId: 'lead-1', website: 'https://www.example.com', email: 'sales@example.com' }]});const { items } = await client.dataset(run.defaultDatasetId).listItems();const accountDomains = items.map((group) => group.rootDomain);console.log(accountDomains);
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("junipr/domain-extractor-grouper").call(run_input={"inputItems": [{"sourceId": "lead-1", "website": "https://www.example.com", "email": "sales@example.com"}]})groups = client.dataset(run["defaultDatasetId"]).list_items().itemsprint([group["rootDomain"] for group in groups])
Tips and Advanced Usage
Keep field mappings explicit
For the cleanest output, map only the fields that are supposed to contain URLs, emails, or notes. Use extractFromAllStringFields only for exploratory cleanup runs where extra false positives are acceptable.
Use source IDs
If your rows include stable IDs, put them in sourceId or id. The actor preserves those values in sourceIds and sampleMatches, which makes it easier to merge grouped results back into your source table.
Understand root-domain limits
Root-domain parsing uses a deterministic built-in suffix list plus your optional knownMultiPartSuffixes. It does not call the public suffix list at runtime. That keeps runs fast and offline, but highly unusual suffixes should be supplied explicitly.
Limitations
- The actor normalizes and groups domains from supplied rows only; it does not fetch websites, resolve DNS, enrich contacts, or call WHOIS APIs.
- Root-domain handling uses deterministic suffix rules plus optional
knownMultiPartSuffixes, not a live public suffix list lookup. - Invalid hosts, private network names, and ambiguous free-text fragments are skipped rather than guessed.
- Use downstream validation if decisions depend on domain ownership, deliverability, or current DNS state.
FAQ
Does this actor make network calls?
No. It does not fetch websites, resolve DNS, call WHOIS, enrich companies, or use paid APIs.
What is a root domain?
A root domain is the account-level domain used for grouping, such as example.com from www.example.com or vendor.co.uk from blog.vendor.co.uk.
Can it parse domains from notes?
Yes. Fields listed in textFields are scanned for URLs, email addresses, and bare domains inside mixed text.
How are invalid values handled?
Invalid hosts, IP addresses, localhost values, and strings without a valid dotted domain are ignored rather than emitted as groups.
Can I add more suffix rules?
Yes. Add suffixes to knownMultiPartSuffixes, for example ["co.example"], when your data needs custom root-domain reduction.
Why does it emit one row per domain group?
The grouped row is the useful unit for downstream deduplication, enrichment, routing, and reporting. Match examples preserve the source-level trace.
Related Actors
- CSV Deduper Normalizer
- Domain WHOIS Lookup
- MX Lookup
- Email Validator
- Dataset QA Auditor