CRM Contact Cleanup & Duplicate Review avatar

CRM Contact Cleanup & Duplicate Review

Pricing

from $0.08 / 1,000 processed rows

Go to Apify Store
CRM Contact Cleanup & Duplicate Review

CRM Contact Cleanup & Duplicate Review

Clean up your contact list before the next import. Spot formatting issues and possible duplicates, compare suggested changes, and keep the originals while you decide.

Pricing

from $0.08 / 1,000 processed rows

Rating

0.0

(0)

Developer

Critical Distinction

Critical Distinction

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 days ago

Last modified

Share

A cleaner contact list starts here.

Turn a messy CRM export into a review of formatting fixes and possible duplicates. Compare suggestions with the originals and decide what to change. Your CRM stays untouched.

Try the example · Use your file · Pricing · Help

What you receive

Your resultWhat it helps you do
Contact reviewSee possible duplicates and formatting suggestions together.
Complete review fileCompare original values and suggestions in CSV or JSON.
Supporting detailsUnderstand a suggested match and what still needs checking.

Website, email and U.S.-leaning address formatting are reviewed. Other columns stay with your records. Suggestions are not verified contact details or automatic merges. The review page is read-only: it does not save approvals.

Start here

Try the fictional contact example. No contact list needed. Check the displayed price, click Start, then open Start here: Contact review in Output. Open Complete review file for the full result.

You can also select Input source → Try the fictional example in the form. The built-in example uses 12 fictional rows and costs $0.0012 at the base rate; plan discounts may apply. An example is not automatically free.

Try a small file of your own

  1. Keep your original export. Choose My stored data / file → File upload, upload a supported file, and use Match your columns for the ID, website, email and address columns.
  2. Set Source Row Cap for the file. Use Preview Only (check source, no files) to check the source first; turn it off when ready for results.
  3. Open Contact review, then download Complete review file. Use the decision template to prepare a copy with approved changes, then use your CRM's own test-import and rollback controls.

CSV, JSON Lines and JSON arrays are supported. The three-row CSV example provides a starting file. Use one input route at a time. When switching routes, remove the previous route's data, including empty or null fields.

Prepare your approved changes

Turn the changes you approve into a separate import copy.

Review the suggestions, choose the changes you want, and receive a separate file containing those changes while keeping the other records and values intact. A change record shows what was edited and what still needs attention. Your CRM stays untouched.

The file is prepared from your supplied records and decisions. It does not verify contact identities, merge people, import data or guarantee that your CRM will accept the file. Keep your original and use your CRM's own test-import controls.

  1. Run an ordinary review and download Decision template — no changes approved (APPROVAL_TEMPLATE.json). The read-only review page does not save decisions.
  2. Keep the complete source reference, row positions, field names and original values. Set each selected decision to approved, rejected or unreviewed. Missing and unreviewed choices never authorize an edit.
  3. Supply the same original records, select Prepare a copy with my approved changes, and paste the complete JSON file into Your decisions about these suggestions (decisionFile). API callers send that file as a JSON string.
  4. Check final run status and Contact review. If preparation succeeded, download Prepared import copy, What changed in this copy and Reversal plan for this exact copy.

Each run is a new review charged at the normal accepted-row price, including a valid review whose import copy is withheld. Extra handoff files and cell changes add no separate charge. Check the displayed maximum cost before starting.

Stale snapshots, duplicate cell decisions, stale original values, identity edits, missing columns and unsupported edits withhold the entire copy. Fix the listed decisions before trying again. An empty selection says No approved changes supplied. Your records are unchanged. Original duplicate findings and other review warnings remain visible even when a copy is prepared.

APPROVED_IMPORT.csv preserves CSV header order and literal string cells; lexical quoting and line endings can differ. JSON originals produce APPROVED_IMPORT.json with native values, all rows and canonical original object fields, regardless of the ordinary review export format. Null, empty string, absent field, number and string stay distinct. Structured values may remain untouched; this feature edits existing scalar cells only. Source-row position plus the whole-table fingerprint distinguishes duplicate or blank CRM IDs; the configured ID field cannot be edited. No rows or columns are added, removed or merged.

The versioned fingerprint binds the complete preserved logical table: row order and ordinals, original field names/order and values/types. JSON objects use the existing canonical key order; CSV uses its original header order. It excludes upload/run time and generated review fields. A source revision label is not a substitute. Duplicate original JSON properties withhold the handoff even though the ordinary review retains its existing last-value parsing. Dataset slices or sources whose complete original table cannot be established cannot produce a complete import copy.

At most 6,000 supplied decisions are accepted within the existing separate narrow/wide profiles. Original input plus the decision file must fit 5 MiB (inline input includes received encryption, whitespace and control overhead); the combined additional handoff files and summary must also fit 5 MiB. Optional templates can be unavailable at these bounds while the ordinary review remains usable; oversized opted-in preparation refuses before result publication. A template is a decision file, never an import file.

The reversal plan binds the generated output fingerprint and records the inverse cell changes, initially unreviewed. It does not undo a CRM import and must not be applied after other edits have changed the file. Supply that exact prepared file and explicitly approve the inverse decisions only if you intend a new, separately paid file review.

Preserve your original file. Spreadsheet software may interpret values as formulas or change leading-zero identifiers. Use controlled text import and your CRM's own test-import and rollback controls. Quoting does not make formula-like values harmless; values are never silently sanitized.

Follow a fictional approval through to a file

Use the fictional approved-change CSV with sourceMaxRows: 14 and this column map:

{"recordId":"crm_id","email":"email","url":"website","address":"address"}

It has 12 contact rows plus two blank rows. Two contacts share the literal ID 00017; another ID is blank. The notes include Unicode, an embedded newline and formula-like text. Review the original first, then download its actual decision template. Keep the template's schemaVersion and sourceFingerprint. The following are the three fictional decisions for its decisions array:

[
{"sourceRow":1,"column":"email","before":" FIRST@EXAMPLE.INVALID ","after":"FIRST@example.invalid","decision":"approved"},
{"sourceRow":2,"column":"website","before":"https://example.invalid/b","after":"https://example.invalid/updated","decision":"rejected"},
{"sourceRow":2,"column":"address","before":"2 Fictional Lane","after":"2 Fictional Ln","decision":"unreviewed"}
]

These choices are an example of a person's supplied decisions, not instructions to approve your own suggestions automatically. Paste the complete template object, with these fictional decisions, into the decision-file setting and request the prepared copy against the same original.

APPROVED_IMPORT.csv contains all 14 rows and the original six columns. Only row 1's email changes; its local part stays FIRST. The repeated and blank IDs, rejected website, unreviewed address, notes and two different blank rows stay intact. APPROVED_CHANGES.json identifies that one edit and the remaining review work. REVERSAL_PLAN.json contains its inverse, unreviewed and bound to the prepared copy. Each review has 12 billable accepted rows: $0.0012 per run at the base rate, or $0.0024 for the ordinary review and preparation run together; plan discounts may apply.

Changing even an unrelated original value before the preparation run makes the snapshot stale and withholds the whole copy. An approved edit with a mismatched before value also withholds it. A completed ordinary review can still be billable in that case. Read the explanation before deciding whether to start another run.

Pricing and limits

$0.10 per 1,000 accepted review rows at the base rate. Three accepted rows cost $0.0003; 12 cost $0.0012. Review files and this Actor's platform usage are included. Accepted rows are billable even when unchanged or still needing review. Preview creates no billable result rows, but uses platform resources. This is Pay Per Event pricing.

Check current pricing and the displayed maximum cost before starting. Plan discounts may apply; account subscriptions, taxes and unrelated services are separate.

Choose a tested file size

Accepted rowsDistinct source columns
1,0006
12261

These are separate tested profiles, not a combined 1,000-row, 261-column allowance or a guarantee for every file. The older 10,000-row schema guard is not supported customer capacity. Set Source Row Cap explicitly; an over-limit file stops rather than quietly losing rows. Byte and output limits also apply. Preview confirms its source check, not import readiness or a later run's completion.

Check a returned file before accepting it

Already received a cleaned file from someone else? The optional returned-file check compares it with your original records and an independent list of the changes you approved. It highlights missing corrections, unexpected edits, missing rows and additions.

This checks the supplied delivery against your instructions. It does not verify people's identities, approve a supplier's work, or perform a merge. Open Contact review for the summary and CLEANUP_ACCEPTANCE.json for all findings. After-only rows, cell findings and exceptions add no billing units; the Dataset still contains only the accepted original review rows.

The returned-file settings below explain the required keys and approval list. Leave this option off for an ordinary contact review.

Your data

Results contain the contact information you supply. The Actor uses limited permissions; selected source storage requires READ access. Choose suitable Apify access and retention settings; this Actor does not delete your source or results, connect to your CRM, or relay your files to our workstation.

Stored inline records, confidentialRecords and the optional cleanupAcceptance and decisionFile inputs have Apify secret protection. That does not encrypt uploaded files, source storage, results or older plaintext inputs. Keep credentials and unrelated personal information out of the input.

Recovery and help

Use the Issues tab for help choosing a file or understanding a result. Include a run ID for a run problem and use fictional examples. Public discussions must not contain contact lists, credentials or access links. No guaranteed support response time is offered.

A stopped run may already have results or charges. Check that run before starting another. A missing acknowledgement does not mean nothing happened. The recovery reference explains the retained states.

Advanced reference

These settings support custom files and existing integrations. They are not extra steps for the fictional example.

Your read-only review page and full files

CONTACT_REVIEW.html is the starting point. The complete file is CLEANED_CONTACT_REVIEW.csv or CLEANED_CONTACT_REVIEW.json. RECORDS_TO_REVIEW.json retains rows needing attention, including structurally blank or rejected rows absent from the accepted-row Dataset. POSSIBLE_MATCH_GROUPS.json keeps matching context; RUN_SUMMARY.json records source, counts and artifact keys; FOCUSED_REVIEW.json provides up to 100 distinct candidate pairs.

The HTML displays up to 20 changed or unresolved rows, 12 original fields per row and 512 characters per value, with shortening and omitted work identified. Use the full files for all values. The Dataset is not the complete import file. Complete review file (CSV/JSON record listing) opens a file listing; the page also links to the selected file.

Shared websites, mailboxes and addresses can belong to different people. Overlapping pairs do not prove that a whole group is one person. No row is merged, deleted or selected as a survivor. humanDecision starts as unreviewed; keep your decisions outside the run.

Try a small CSV file

crm_id,website,email_address,mailing_address,segment,note
00017, alpha.example/?utm_source=crm ,team@alpha.example,100 Example Road Chicago IL 60601,trial,"Keep comma, and leading zero ID"
00018,https://alpha.example,TEAM@ALPHA.EXAMPLE,100 Example Rd Chicago IL 60601,customer,Review the possible match; do not merge automatically
00019,https://beta.example,not-an-email,warehouse behind blue door,trial,Keep original values when review is required

Choose File upload, format csv, and this column map:

{"recordId":"crm_id","url":"website","email":"email_address","address":"mailing_address"}

Set sourceMaxRows: 3 and previewOnly: true. After the source check, set previewOnly: false. workflow.exportMode: "side_by_side" and workflow.exportFormat: "csv" produce the comparison file. Preview reports its accepted count in run status, not downloadable results.

Keep an import copy with your original columns and only your approved cell changes. Preserve row order, headers, leading-zero IDs and unchanged cells; leave possible duplicates separate. Record decisions using the source row number and file identity, because a CRM ID can be blank or duplicated. Use CSV-aware import with formula evaluation disabled for untrusted values. Do not invent a replacement for not-an-email or silently drop that row to satisfy an import rule.

Choose one input route

Use one of confidentialRecords, records or source. Inline arrays contain 1–1,000 objects, with recordId, url, email and address identifying reviewed fields. Other fields are preserved; the tested profiles still apply. An empty array is not an example request.

source.type is file, dataset or keyValueStore. File input uses source.file; Dataset input uses source.datasetId and optional offset; KVS input uses source.storeId and source.recordKey. File/KVS reads are bounded to 5 MiB. File/KVS formats are csv, jsonl, json_array, or auto when the name/content type identifies a supported format. Dataset rows are JSON objects without a format selector. Storage routes accept source.fieldMap and require READ access to the selected source.

Set sourceMaxRows and use the fail_over_limit policy. Source-only controls and previewOnly: true do not apply to inline input. The form may send neutral previewOnly: false with an explicit example/inline inputSource; legacy input without inputSource omits source-only controls. Form prefills are not runtime defaults for API calls or saved tasks. A minimal explicit inline input is:

{"inputSource":"records","records":[{"recordId":"demo-1","email":"team@example.invalid"}]}

Choose the cleaned-file shape

side_by_side keeps original values and appends comparison fields under a collision-safe namespace. replace_supported_fields replaces only mapped URL/email/address cells with a safe no_review value, retaining displaced originals and review fields. Missing, rejected and review-required values are not silently replaced.

CSV is UTF-8 and preserves source column order. JSON-origin values are encoded as JSON text in CSV cells so their types remain distinguishable; JSON output retains native types. Formula-like values remain literal source data, not spreadsheet-sanitized formulas. Select workflow.exportFormat: "csv" or "json".

URL cleanup does not crawl websites. Email cleanup checks syntax and formatting without sending mail or verifying an inbox. Address cleanup is U.S.-leaning and unit-aware, not geocoding or postal verification. No external enrichment service receives the contacts.

Returned-file settings

Add cleanupAcceptance to a normal original/before review. Supply one returned file already in Apify storage, an exact string key column, a before-revision label and independent approved changes:

{
"cleanupAcceptance": {
"beforeRevision": "my-export-r1",
"keyColumn": "recordId",
"afterFile": "apify://key-value-stores/YOUR_STORE/records/returned.json",
"afterFormat": "json_array",
"excludedColumns": [],
"approvedChanges": [{
"beforeRevision": "my-export-r1", "rowKey": "001", "column": "email",
"before": {"state":"value", "value":"UPPER@example.invalid"},
"after": {"state":"value", "value":"upper@example.invalid"}
}]
}
}

This is the optional object, not a complete original-input request. Use {"state":"missing"} for an absent column; {"state":"value","value":null} is explicit null. Blank strings, whitespace, numbers and strings remain different. Keys preserve case, spaces and leading zeros. All non-excluded scalar columns are compared, including columns outside the approval list.

Duplicate keys or approvals, stale before revisions/values, changed keys, structured cells and missing rows remain unresolved. A no-op approval is not a delivered correction. There is no automatic crosswalk, many-to-one merge, sign-off or invoice approval. Findings can overlap.

Each table must fit either 1,000 rows with at most 6 distinct columns or 12 rows with at most 261 columns. Preserved before cells, the returned file and the approval list together must fit 5 MiB; complete acceptance JSON plus its summary must fit 5 MiB; combined review HTML must fit 1 MB. Exceeding a bound stops before publication. Preview cannot produce an acceptance report.

A short CSV row is padded with blank strings to its header; an absent header is a missing column. JSON comparison uses parsed objects: property order is canonical and duplicate property names retain the last value. Use uniquely named source properties when literal duplicate-property provenance matters. Revision labels are your declarations; SHA-256 identifies the preserved logical before content, not its authenticity.

Recovery: inspect first, never retry blindly

Buyer files and review views are acknowledged before billable Dataset writes; final OUTPUT follows acknowledged files and Dataset batches. A publication checkpoint or prior output prevents the same run from submitting rows again. A stopped worker is not a successfully completed review. This is not an automatic continuation, transaction or exactly-once guarantee.

RECOVERY_STATE.json, when a failure is caught, records the last acknowledged milestone. Hard termination may leave less information. A rejected Dataset batch can be known not to have committed. A transport/5xx failure can leave an unknown commit: committedDatasetItemCount is null, automaticDatasetRetryForbidden is true, and cardinality is unknown_commit; a known rejected submission uses zero_rejected.

Inspect the existing Dataset, files, OUTPUT and billing state without writing or retrying. A failed final OUTPUT write does not erase acknowledged results. An unknown charge may already have settled. A separate new run can perform and charge work again.

Existing saved workflows

New users can start with the example. 4.3.4 is the delivered numbered build verified October 8, 2026, with the optional returned-file review and current recovery behavior. Use an exact numbered build for a fixed task selection. Movable tags can change. Preserve original files and read the public release notes before changing an established workflow.

Contact 4.0 renamed inactive dedupeKeyMode to legacyMatchMode, retaining its values and lack of effect. Rename it for the current schema. 3.2.1 was the recorded compatible selector for the old spelling; check its actual retained availability before relying on it. It does not contain the later returned-file feature or interruption changes.

The following compact selectors preserve the earlier recorded compatibility inventory. They were observed in the October 2 history, not requalified as current recommendations; availability is not promised indefinitely. Use an old build's own input/output contract and keep existing task pins unchanged until you choose a migration.

Earlier familyRecorded numbered selectorRelevant difference
4.14.1.3Current input spelling and clearer omitted-match display; before returned-file review.
4.04.0.1legacyMatchMode replaces the old input name.
3.23.2.1Earlier name and buyer guide.
3.13.1.6Review-to-import guidance and pricing refinements.
3.03.0.2Both stored inline arrays use secret protection.
2.22.2.2Example choice and read-only Contact review page.
2.12.1.1Earlier current-run price and source handling.
2.02.0.6Whole-file review; complete files rather than Dataset alone for import.
1.01.0.9Earlier input/output contract; not the current whole-file workflow.

Submit original JSON, not stored ciphertext. Older plaintext runs were not retroactively encrypted or deleted. Since Contact 2.0, the Dataset is a review projection, not the complete import file. Returned-file review is included in 4.3.4; omitting it preserves ordinary review.