Merge & Deduplicate Datasets: Remove Duplicates, Only New Items avatar

Merge & Deduplicate Datasets: Remove Duplicates, Only New Items

Pricing

from $0.10 / 1,000 output rows

Go to Apify Store
Merge & Deduplicate Datasets: Remove Duplicates, Only New Items

Merge & Deduplicate Datasets: Remove Duplicates, Only New Items

Merge Apify datasets, CSV and JSON files into one, remove duplicates by any field, output only new items since the last run, filter, rename and flatten. $0.10 per 1,000 rows.

Pricing

from $0.10 / 1,000 output rows

Rating

0.0

(0)

Developer

Giorgos Myrianthous

Giorgos Myrianthous

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 hours ago

Last modified

Share

Merge datasets and remove duplicates from Apify datasets, CSV and JSON files, and output only new items since your last run, which is perfect for scheduled scrapers feeding Google Sheets, CRMs and Slack.

💲 $0.10 per 1,000 output rows. Duplicates and filtered rows are free. Pay only for results. No subscription, and the Apify free plan's monthly credit covers small jobs.

Also known as: merge datasets, deduplicate dataset, remove duplicates, dedup CSV, only new items, combine scraper runs, JSON to CSV, dataset transformer.

Quick start

  1. Click Start. The prefilled input works as is.
  2. Or paste this input (JSON tab):
{
"inlineItems": [
{
"url": "https://example.com/a",
"title": "A"
},
{
"url": "https://example.com/b",
"title": "B"
},
{
"url": "https://example.com/a",
"title": "A (duplicate)"
}
],
"dedupFields": [
"url"
]
}

Output (one dataset item):

{
"url": "https://example.com/a",
"title": "A"
}

Use it from the API, AI agents (MCP), n8n, Make or Zapier

curl -X POST "https://api.apify.com/v2/acts/gmyri~dataset-merge-dedup/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"datasetIds":["<DATASET_ID_1>","<DATASET_ID_2>"],"dedupFields":["url"],"onlyNewItems":true}'
  • AI agents / MCP: connect https://mcp.apify.com/?actors=gmyri/dataset-merge-dedup to Claude, Cursor, ChatGPT or any MCP client. The input schema is fully described for tool calling.
  • Python: ApifyClient(token).actor("gmyri/dataset-merge-dedup").call(run_input={...})
  • n8n / Make / Zapier: use the Apify "Run Actor" action with gmyri/dataset-merge-dedup, then read the dataset items.

Quick FAQ

  • How does 'only new items' work? The keys of rows already output are stored in a named key-value store (stateStoreName). The next run outputs only rows it has never seen, so you can schedule a scraper and get just the new results.
  • Can it read my other Actors' datasets? Yes. Pass dataset IDs in datasetIds. The Actor runs with limited permissions and only reads the datasets you select.
  • What if I set a spending limit? The Actor stops cleanly at your Max cost per run and you're never charged above it.

Details

Combine the outputs of several scraper runs, CSV exports and JSON files into one clean dataset:

  • remove duplicates by any fields
  • output only the rows that are new since your last run
  • filter, keep, drop, rename and flatten fields
  • export to an Apify dataset, CSV or JSON

You pay only for rows that make it into the output. Duplicates and filtered rows are free.

Why this Actor

  • Reliable. Rows are streamed in batches of 500, a missing or broken source never kills the run (it is reported in SUMMARY), and a spending limit stops the run cleanly instead of failing it.
  • Incremental pipelines. Schedule a scraper, chain this Actor after it with onlyNewItems: true, and send only fresh rows to Slack, Sheets or your CRM. Dedup keys are remembered in a named key-value store between runs.
  • Mixed sources. Read Apify datasets, CSV/TSV (delimiter auto-detected), JSON arrays, { "items": [...] } wrappers, JSON Lines and inline JSON, all in one run.
  • Agent-friendly. Inline items plus a simple JSON filter language make it a handy cleaning tool for AI agents through the Apify MCP server.

Typical uses

  • Merge 10 daily runs of a product or price scraper and keep the newest row per URL (keepOccurrence: "last").
  • Dedup a lead or company list by domain (case- and whitespace-insensitive).
  • Turn nested JSON into a flat CSV for Excel (flattenNested + saveCsvFile).
  • Keep only rows with price < 100 that contain "mug" in title.

Input example

{
"datasetIds": ["<dataset-id-run-1>", "<dataset-id-run-2>"],
"fileUrls": ["https://example.com/export.csv"],
"dedupFields": ["url"],
"keepOccurrence": "last",
"filters": [{ "field": "price", "op": "lt", "value": 100 }],
"omitFields": ["debug"],
"renameFields": { "meta.brand": "brand" },
"flattenNested": true,
"saveCsvFile": true
}

Options

FieldDefaultDescription
datasetIds–Apify datasets to merge, in order
fileUrls–CSV, TSV, JSON or JSONL URLs (Google Sheets "publish to web" CSV links work)
inlineItems–JSON array of rows
deduplicatetrueRemove duplicate rows
dedupFieldswhole rowFields that define a duplicate (dot paths such as address.city work)
dedupCaseInsensitive / dedupTrimWhitespacetrue / trueNormalise values before comparing
keepOccurrencefirstfirst or last (newest data wins)
onlyNewItemsfalseSkip rows already output in previous runs
stateStoreNamedataset-dedup-stateNamed store that remembers keys between runs. Use one per pipeline.
filters–[{field, op, value}]. Ops: eq ne contains notContains in notIn gt gte lt lte exists notExists regex
pickFields / omitFields / renameFields–Reshape rows
flattenNested, trimStrings, dropEmptyFields, addSourceFieldfalseExtra clean-up
inferCsvTypestrueTurn CSV "12" into 12 and "true" into true
maxOutputItems0Cap on output rows
saveCsvFile / saveJsonFilefalseAlso save OUTPUT.csv / OUTPUT.json in the key-value store

Output

  • The default dataset holds the cleaned rows.
  • SUMMARY (key-value store) holds the counts, for example:
    { "inputRows": 11, "filteredOut": 1, "duplicates": 4, "seenInPreviousRuns": 0, "outputRows": 6,
    "sources": [{ "source": "dataset:abc", "rows": 2 }], "sourceErrors": [] }
  • OUTPUT.csv and OUTPUT.json are saved if requested.

Pricing (pay per event)

EventPriceWhen
row-output$0.0001 ($0.10 per 1,000 rows)Each row written to the output
apify-actor-start$0.00005Platform default, once per run

Input rows, duplicates and filtered-out rows are not charged. Example: merging 60,000 rows down to 25,970 unique rows costs about $2.60. Set a maximum cost per run, and the Actor stops output cleanly at the limit.

Integrations

  • Chain after a scraper: add an Apify webhook or integration on your scraper's RUN.SUCCEEDED event and pass {"datasetIds": ["{{resource.defaultDatasetId}}"], "onlyNewItems": true}.
  • MCP: https://mcp.apify.com/?tools=<your-username>/dataset-merge-dedup. The Actor uses pay-per-event pricing only and limited permissions, with no Standby, so it is eligible for agentic payments.

Notes and limits

  • In keepOccurrence: "last" mode, rows are held in memory until all sources are read. Use 1–4 GB of memory for multi-million-row merges.
  • Rows whose dedup fields are all empty are always kept. In incremental mode they are remembered by their full content.
  • With limited permissions, the Actor can read only the datasets you pick in the input.