List Cleaner & Normalizer avatar

List Cleaner & Normalizer

Pricing

from $0.0001 / actor start

Go to Apify Store
List Cleaner & Normalizer

List Cleaner & Normalizer

Free email list cleaner & email list dedupe / contact list normalizer & mailing list dedupe tool: paste JSON/CSV contact lists, deduplicate, validate emails & domains, download clean rows plus a reject report. B2B list hygiene — free when empty.

Pricing

from $0.0001 / actor start

Rating

0.0

(0)

Developer

Valunex

Valunex

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Security

Limited permissions

Share

List Cleaner & Normalizer — free email list cleaner, email list dedupe & contact list normalizer / mailing list dedupe tool

Paste a raw list of names, emails, domains and phones (JSON or CSV text) and get back a clean, deduplicated, normalized dataset plus a reject report. This Actor is a free email list cleaner / email list dedupe / list validation free / contact list normalizer / mailing list dedupe tool / B2B list cleaner for sales ops teams — no scraping, no SMTP probing, no per-email fees.

Actor: apex-nexus~list-cleaner-normalizer Store listing: FREE — email list cleaner & contact list normalizer

What it is for

Bring your own data — paste messy prospect, vendor or contact lists as a JSON array of objects or CSV text with a header row (Apify Actor input has no file upload, so pasted text is the input). See Input for the full schema and Output for the returned shapes. The Actor:

  1. Parses the pasted input (JSON or CSV).
  2. Normalizes every field: trimmed, whitespace-collapsed; emails and domains lowercased; domains checked as IDNA-valid.
  3. Deduplicates rows by normalized email (or, when a row has no email, by the name + domain + phone signature) — first occurrence wins.
  4. Validates email syntax plus domain/MX format (best-effort DNS: a hard domain failure rejects the row, transient DNS problems keep it).
  5. Strips invalid rows and returns the clean rows plus one reject report with counts, reason codes and the rejected rows.

Typical workflows:

  • Sales list cleanup. Paste a messy prospect export; download clean CSV with valid emails only, plus the reject report showing exactly which rows were dropped and why.
  • B2B list dedupe. De-dupe by email across merged lists while keeping domain-only and name-only contact fragments.
  • Mailing list hygiene. Run before a campaign to strip invalid addresses and typos (not-an-email, empty rows) without paying per-email validation fees.
  • Domain list normalizer. Lowercase and de-dupe domain lists, validate that each domain resolves.

What this is NOT

This is explicitly not a tracker: no watchlist state, no delta alerts, nothing remembered between runs. Each run is stateless and independent. It is also not an SMTP/MX email validator: it does not probe mail servers, does not check mailbox existence, and does not use paid enrichment APIs — the domain check is DNS format/resolution only, so it is safe on any list. The Actor is free when there is nothing to return (empty input → empty dataset).

Data sources

User-supplied data only. The Actor never fetches third-party data — the only external lookups are best-effort DNS MX/A resolution of email domains (public DNS, no credentials, no proxies, no API keys, no LLMs).

Search terms (Store discovery)

Users find this Actor on the Apify Store with terms such as:

  • email list cleaner
  • list validation free
  • domain list normalizer
  • mailing list dedupe tool
  • B2B list cleaner
  • contact list normalizer
  • email list dedupe

The Store title and description carry the core terms ("List Cleaner & Normalizer", "email list cleaner", "contact list normalizer", "mailing list dedupe tool", "reject report"); this section lists them for reference when updating the listing metadata.

Input

See .actor/input_schema.json. All fields are optional; the default run cleans the built-in mixed list (names, emails, domains, phones with duplicates and invalid rows).

FieldTypeDefaultDescription
inputTextstring (textarea)built-in mixed listPasted list: JSON array of objects (name, email, domain, phone, …) or CSV text with a header row.
normalizeDomainsbooleantrueLowercase emails/domains; trim and collapse whitespace on every field.
rejectInvalidEmailsbooleantrueDrop rows whose email fails syntax validation or whose domain publishes no MX and resolves to no A/AAAA record.
maxRejectedReportedinteger500Cap on rejected rows embedded in the reject report (counts stay exact), 1–5000.

Example input (default run):

[
{"name": "Alice Smith", "email": "ALICE@Example.COM ", "domain": "Example.COM", "phone": "+1 (555) 0100"},
{"name": "Bob Jones", "email": "bob@example.com", "domain": "example.com", "phone": "555-0100"},
{"name": "Carol Davis", "email": "not-an-email", "domain": "example.com", "phone": "555-0200"},
{"name": "Frank Miller", "email": "FRANK@Example.COM", "domain": "Example.COM", "phone": "+1-555-0100"},
{"name": "Grace Lee", "email": "", "domain": "example.com", "phone": "555-0500"}
]

Example input (CSV):

name,email,domain,phone
Alice Smith,ALICE@Example.COM,Example.COM,+1 (555) 0100
Carol Davis,not-an-email,example.com,555-0200

Output

One clean_record dataset item per valid row, plus exactly one reject_report item (last item). Download the whole dataset as CSV or JSON from the Apify run — clean CSV and the reject report together. See .actor/output_schema.json and .actor/dataset_schema.json.

FieldTypeDescription
_typestring"clean_record" or "reject_report"
rowIdintegerSequential id of the clean row (clean_record)
namestringNormalized name
emailstringNormalized email (lowercased)
domainstringNormalized domain (lowercased, IDNA-valid)
phonestringNormalized phone
normalizedAtstringUTC timestamp (ISO 8601)
inputRows / cleanRows / rejectedRowsintegerCounts (reject_report)
reasonsobjectRejection count per reason code (reject_report)
rejectedarrayRejected rows with row index + reason (reject_report)
generatedAtstringUTC timestamp (ISO 8601, reject_report)

Reject reason codes: invalid-email, invalid-domain, domain-not-resolvable, duplicate, empty-row.

Example output item (clean record):

{
"_type": "clean_record",
"rowId": 1,
"name": "Alice Smith",
"email": "alice@example.com",
"domain": "example.com",
"phone": "+1 (555) 0100",
"normalizedAt": "2026-11-03T12:00:00+00:00"
}

Example output item (reject report):

{
"_type": "reject_report",
"inputRows": 10,
"cleanRows": 7,
"rejectedRows": 3,
"reasons": {
"invalid-email": 1,
"domain-not-resolvable": 1,
"empty-row": 1
},
"rejected": [
{"rowIndex": 3, "row": {"name": "Carol Davis", "email": "not-an-email", ...}, "reason": "invalid-email"},
{"rowIndex": 4, "row": {"name": "Dave Wilson", ...}, "reason": "domain-not-resolvable"},
{"rowIndex": 7, "row": {"name": "", "email": "", ...}, "reason": "empty-row"}
],
"generatedAt": "2026-11-03T12:00:00+00:00"
}

Limits

  • One pasted list per run (JSON or CSV text; no file upload).
  • Default mixed list (10 rows, duplicates + invalid rows) → 7 clean rows + reject report in well under 5 minutes.
  • DNS domain checks are best-effort with a short timeout; transient DNS problems keep the row instead of rejecting it.
  • Invalid input finishes with an empty clean dataset plus a reject report rather than crashing.
  • Deterministic for a given input: same list in, same clean rows out (apart from timestamps).

Example runs

Default run — built-in mixed list:

{}

CSV paste, keep everything (no domain validation):

{
"inputText": "name,email\nA,a@x.com\nB,bad-email\n",
"rejectInvalidEmails": false
}

JSON paste, large reject lists:

{
"inputText": "[{\"email\": \"a@x.com\"}, {\"email\": \"a@x.com\"}]",
"maxRejectedReported": 100
}

Quality gate (live, verified)

Actor: apex-nexus~list-cleaner-normalizer (actor id JzALhGjT7HhhQCghP, private, not published — publication is a director action). Build: 1.0.1 (Apify build id IaBMBiPQ1MYpg049c, status SUCCEEDED, tagged latest via apify push -b latest). Apify validated the input/output schemas during the build.

Default run (input {}, built-in 10-row mixed list with duplicates and invalid rows): run id WITAafDLwIoTfKxZJ, status SUCCEEDED, exit code 0, runTimeSecs 3.134 (< 5 min ✓), default dataset nlMYVJdTvIPvcDSAy.

Output: 7 clean rows (Alice Smith, Bob Jones, Eve Wong, Frank Miller, Grace Lee, Hank Boone, Heidi Cruz — emails lowercased/deduped; ALICE@... and FRANK@... kept as distinct addresses) plus 1 reject report (10 input rows, 3 rejected):

  • invalid-email: 1 — Carol Davis / not-an-email
  • domain-not-resolvable: 1 — Dave Wilson / no-such-domain-9x9.invalid (live DNS NXDOMAIN)
  • empty-row: 1 — fully empty row

Competing email list validators on the Apify Store are PAY_PER_EVENT per-address SMTP/MX checkers; this Actor is free, self-service, BYO-data list hygiene.

Claims statement

All claims in this README are limited to what the product verifiably does: it parses user-supplied JSON/CSV contact lists, normalizes and deduplicates them, validates email syntax plus domain/MX format via best-effort DNS, and returns clean rows with a reject report. This README contains no revenue, user, or adoption claims, because none are verified.