Dataset Deduplicator & Cleaner — Dedup + Report avatar

Dataset Deduplicator & Cleaner — Dedup + Report

Pricing

Pay per usage

Go to Apify Store
Dataset Deduplicator & Cleaner — Dedup + Report

Dataset Deduplicator & Cleaner — Dedup + Report

Deduplicate and clean any dataset: exact, normalized and fuzzy dedup, per-type field cleaning (emails, phones, URLs, HTML) and a data-quality report.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Radosław Szal

Radosław Szal

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Dataset Deduplicator & Cleaner

🔗 Part of the Apify actors collection — 6 reliable, tested scrapers & data tools.

Quick start: paste a JSON array into Inline data (or give a Source dataset ID), then Run.

Turn messy, duplicate-ridden data into analysis-ready records in one deterministic run. Point it at any Apify dataset (or paste JSON directly), and get back deduplicated, cleaned, type-consistent records — plus a data-quality report. No scraping, no external APIs, no maintenance.


✨ What it does

  • Deduplicates records — exact, normalized, or fuzzy (near-duplicate) matching.
  • Cleans fields by type — emails, phones, URLs, whitespace, HTML, empty values, and more.
  • Reports quality — input/output counts, duplicates removed, and per-field fill rates, saved to the key-value store as QUALITY_REPORT.
  • Two ways in — pipe another actor's output via Source dataset ID, or paste Inline data.
  • Zero maintenance — deterministic, no third-party services, pay only per output record.

🎯 Who is it for

RoleWhat it solves
Scraper usersClean and de-dupe an actor's output before loading it into a DB or spreadsheet.
Data / ops teamsStandardize messy exports (leads, catalogs, contacts) without writing scripts.
AnalystsDe-dupe and normalize lists, then check fill rates at a glance.

⚙️ Deduplication modes (dedupMode)

ModeDescription
noneDon't deduplicate — clean only.
exactByte-identical values.
normalizedIgnores case, whitespace and punctuation — catches "John Smith" vs "john smith!". (default)
fuzzyAlso merges near-duplicates by string similarity (similarityThreshold, 0.5–0.99). Best for a few thousand rows; on very large or low-diversity inputs it automatically degrades to normalized and tells you in the run status (so a run never hangs).

Set dedupKeys to the fields that identify a duplicate (e.g. email, url); leave it empty to compare the whole record. When duplicates are found, keepStrategy decides which one survives:

  • most_complete — keep the record with the most filled fields (default)
  • first / last — keep the first or last occurrence

🧹 Field cleaning

Fields are cleaned by type. With smartFields on (default), emails, phones and URLs are detected by field name; everything else is treated as text.

OptionWhat it does
cleanEmailsLowercase + trim values that look like a valid email (invalid ones are left as text, not dropped).
cleanPhonesCompact phone-like fields to digits, keeping a leading +/00 country prefix.
cleanUrlsLowercase the scheme and host, drop a trailing slash.
stripHtmlRemove HTML tags and unescape entities (&&).
emptyToNullTurn empty / blank values into null for consistency. (default on)
dropEmptyFieldsRemove empty fields entirely instead of keeping them as null.
caseForce plain-text fields to lower / upper / title case.
coerceTypesConvert numeric and true/false strings into real numbers and booleans.

Whitespace collapse, end-trimming and control-character stripping are always applied to text.


📥 Input

Provide either sourceDatasetId or data:

{
"sourceDatasetId": "abc123XYZ",
"dedupMode": "normalized",
"dedupKeys": ["email"],
"keepStrategy": "most_complete",
"cleanEmails": true,
"cleanPhones": true,
"cleanUrls": true,
"emptyToNull": true,
"includeReport": true,
"maxItems": 0
}

Or clean records inline:

{
"data": [
{ "name": " Acme Corp ", "email": "SALES@ACME.COM", "phone": "+1 555 123 4567", "website": "https://acme.com/", "notes": "<p>Top client</p>" },
{ "name": "Acme Corp", "email": "sales@acme.com", "phone": "+15551234567", "website": "http://acme.com", "notes": "Top client" },
{ "name": "Globex Inc", "email": "info@globex.io", "phone": "", "website": "https://globex.io/", "notes": "" }
],
"dedupMode": "normalized",
"dedupKeys": ["name"],
"stripHtml": true
}

Output (deduplicated on name, HTML stripped, empty → null):

[
{ "name": "Acme Corp", "email": "sales@acme.com", "phone": "+15551234567", "website": "https://acme.com", "notes": "Top client" },
{ "name": "Globex Inc", "email": "info@globex.io", "phone": null, "website": "https://globex.io", "notes": null }
]

📊 Quality report

When includeReport is on, a report is saved to the key-value store under QUALITY_REPORT:

{
"inputRecords": 3,
"outputRecords": 2,
"duplicatesRemoved": 1,
"dedupMode": "normalized",
"fieldValuesCleaned": 7,
"fieldCount": 5,
"fields": {
"email": { "filled": 2, "empty": 0, "fillRate": 1.0 },
"phone": { "filled": 1, "empty": 1, "fillRate": 0.5 },
"website": { "filled": 2, "empty": 0, "fillRate": 1.0 },
"notes": { "filled": 1, "empty": 1, "fillRate": 0.5 }
}
}

🚀 How to use

  1. Open the actor in Apify Console (or call it via API).
  2. Pick a data source — a Source dataset ID from a previous run, or paste a JSON array into Inline data.
  3. Adjust dedup and cleaning if you like — the defaults (normalized dedup + sensible cleaning) work out of the box.
  4. Run. Clean records land in the default dataset; the quality report goes to the key-value store as QUALITY_REPORT.
  5. Export as JSON / CSV / Excel, or push onward with Apify integrations.

💰 Pricing & reliability

  • Pay per result — you're billed only for the clean records written to the dataset.
  • Deterministic — same input and config always produce the same output.
  • No external dependencies — no third-party APIs, no browser, nothing to break.
  • Handles up to 50,000 records per run (exact/normalized). Fuzzy is meant for a few thousand rows and degrades gracefully above that. Larger source datasets are paginated in full, and if the 50,000 cap truncates the input the run says so in its status and quality report.

License

Licensed under the Apache License 2.0.