The short version
- Your files are not uploaded by the tools. The Excel, CSV, text, JSON and contacts tools read the file with the browser's own File API and deduplicate it in a script running on your machine. No request carries the contents anywhere.
- The one exception is the HTTP API, which only runs when you deliberately POST data to it. It processes the request in memory, returns the result, and does not write the request body to a database or a file. See how that works.
- We store metadata, not data. Your email address, your plan, your Stripe customer id, a one way hash of each API key, and one row per dedupe job holding counts, durations, the match mode and the column names you matched on.
- You can take all of it and you can destroy all of it, yourself, today, from your settings page. Both are already built. Neither requires emailing us.
- We use Google Analytics to count visits, and nothing else watches you here. No session recording, no advertising network, no fingerprinting. The details, including how to opt out, are in the cookies section below.
Who we are
dedupe.dev is operated by Zen Acquire LLC, the data controller for the information described here. You can reach us at support@dedupe.dev. There is one address for privacy questions, security reports, billing and support, and it is read by a person.
What we collect, and why
This table is the whole of it. It is derived from lib/db/schema.ts, which has four tables and
no column anywhere in it that could hold a file, a row, or a cell value.
| What | When it is collected | Why | Legal basis (UK and EU GDPR) |
|---|---|---|---|
| Email address | When you create an account | It is the account identifier and the login mechanism. We email you a one time sign in link; there is no password to store. | Performance of a contract |
| Plan name | At signup (free), then whenever Stripe tells us a subscription changed | Decides your API allowance and is enforced on every keyed request | Performance of a contract |
| Stripe customer id | The first time you check out | Links your account to your subscription so the billing portal can find it | Performance of a contract |
| API key hash and prefix | When you create an API key | Authenticating your API calls. We store the SHA-256 hash, the first 12 characters for display, and any label you typed. The key itself is shown once and never stored. | Performance of a contract |
| Job metadata | Each time a signed in user runs a dedupe in the browser | Your job history and dashboard. One row holding: file name, where it ran, match mode, the column names you matched on, a fuzzy threshold, rows in, rows kept, rows removed, duration. | Performance of a contract |
| API usage metadata | On every API call made with a key | Quota enforcement and your usage charts. One row holding: which key, the endpoint, the mode, input row count, rows removed, billable units, HTTP status, duration. | Performance of a contract, and our legitimate interest in preventing abuse |
| Payment details | At checkout | Collected and held by Stripe, not by us. We never see or receive a card number. | Performance of a contract |
What we do not collect
Stating this positively, because it is the reason people use this site:
- No file contents. Not from the browser tools, and not persisted from the API.
- No row values, cell values or field values. Column names are stored so your job history can say what you matched on. The values under those columns are not, anywhere.
- No password. There is none to steal, because sign in is a one time emailed link.
- No card number, expiry or CVC. Stripe holds those.
- No session recording, no fingerprinting, no advertising identifiers. Aggregate visit analytics exists (see Cookies); recordings of what you do on a page do not.
You do not have to take our word for any of this. Export your account as JSON and read it: it is every row we hold about you, and there is nothing in it but names, counts and timestamps.
IP addresses and server logs
Calls to the API without a key are limited to 500 units per IP per day. To do that, the function keeps a counter against your IP address in memory, in whichever server instance answered. It is not written to the database, it is not shared between instances, and it disappears when the instance is recycled. There is no table of IP addresses in this service.
Separately, our hosting provider keeps its own standard web and function logs, which for any web service typically include IP address, timestamp, path, status and user agent. Those are Netlify's logs, kept on Netlify's schedule under Netlify's policy. We do not export them, build profiles from them, or join them to your account.
Cookies
One cookie, and it only exists once you sign in.
| Name | Purpose | Contents | Flags | Lifetime |
|---|---|---|---|---|
dd_session |
Keeps you signed in to the dashboard | Your numeric user id, HMAC-SHA256 signed so it cannot be edited or forged | httpOnly, SameSite=Lax, Path=/ |
90 days |
We also use Google Analytics 4 (added July 27, 2026) to understand which pages are visited and
where visitors come from. It sets _ga and _ga_* cookies to tell returning browsers
apart. We have configured it with Google Signals and ad personalisation disabled: it feeds no
advertising, and we see aggregate counts rather than profiles. Data is processed by Google LLC under the
Google Privacy Policy.
To opt out, use Google's own opt-out browser add-on, or any content blocker; the site works identically without it. There is no Meta pixel, no advertising or attribution tag, and no other third party sets a cookie here.
The browser tools use no local storage and no session storage either. Close the tab and nothing about your file remains.
Sub-processors
Four companies process data on our behalf. This is the complete list.
| Provider | What it does for us | What it can see | Where |
|---|---|---|---|
| Neon | Managed Postgres. It is the database everything above lives in. | All of the stored metadata: emails, plans, key hashes, job and usage rows | United States |
| Netlify | Hosting, CDN and the serverless functions that run the API | Request metadata in its logs, and API request bodies in transit through the function that handles them | United States, global edge network |
| Stripe | Subscription payments, checkout and the billing portal | Your email, your payment method and your billing history. Stripe is the controller of your card data, not us. | United States |
| Resend | Sends the transactional sign in email | Your email address and the contents of that message | United States |
None of them receives your file contents, because we do not have your file contents to send.
Third parties your browser contacts
Not sub-processors, because they never receive your data from us, but you should know they are there because your browser makes a request to them and a request reveals an IP address:
- cdn.sheetjs.com serves the spreadsheet parsing library, on the pages where you can drop an
.xlsxfile. The library runs in your browser and reads your file there; it is downloaded from the CDN, your file is never sent to it. - fonts.googleapis.com and fonts.gstatic.com serve the two web fonts the site uses.
Both are ordinary static asset requests, and both are visible in your browser's network panel.
How long we keep things
Honestly: until you delete it. There is no automatic expiry job in this service today, so job records and API usage records accumulate for as long as your account exists. We would rather say that plainly than publish a retention schedule we do not actually run.
- Deleting your account deletes your user row, your API keys, your job records and your usage records, in one database transaction, immediately and permanently. There is no soft delete, no tombstone, no grace period and no backup we can restore you from.
- Revoking an API key stops it authenticating immediately. The key's row is kept, revoked, so your historical usage still adds up.
- Sign in links expire 30 minutes after they are issued.
- Stripe keeps billing records under its own retention rules, and financial record keeping obligations mean an invoice generally cannot be deleted on request.
Your rights, and the buttons that implement them
If you are in the UK, the EU, or somewhere with comparable law, you have rights of access, rectification, erasure, restriction, objection and portability. Two of those are self service here, which we think is the only honest way to offer them:
- Access and portability. Download a JSON export of every row we hold about you, or your job history as CSV. Immediate, no request, no waiting period. The one field left out on purpose is each key's hash, which is a one way hash of a credential and useless to you.
- Erasure. Delete your account. It takes effect the moment you confirm it.
- Rectification, restriction, objection. Email support@dedupe.dev. The only text you typed that we hold is your email address, your API key labels and the file names of your jobs, so in practice rectification means one of those three.
We do not charge for any of this and we do not require you to prove your identity beyond being signed in to the account. If you think we have handled your data badly, tell us first at support@dedupe.dev; you also have the right to complain to your local data protection authority.
International transfers
All four sub-processors above are United States companies and the data described here is processed in the United States. If you are in the UK or the EEA, that is a transfer outside your jurisdiction. Each of those providers publishes its own transfer mechanism, typically the EU Standard Contractual Clauses and the UK Addendum, in the privacy policies linked in the table above. We are a small operation and we do not currently offer a signed data processing agreement of our own; if your organisation requires one before you can use the API, email support@dedupe.dev and say so, and we will tell you honestly whether we can meet it.
Children
This service is for people running data cleanup work, and is not directed at children. We do not knowingly collect information from anyone under 16. If you believe a child has created an account, email support@dedupe.dev and we will delete it.
Security
Covered properly on its own page, including how to verify the client side claim yourself and what you should not trust us with: read the security page.
Changes to this policy
If we change something that matters, we will change the date at the bottom of this page and describe it in the changelog. If a change materially reduces the protection described here, we will email account holders before it takes effect rather than quietly reposting the page.
Contact
Privacy questions, access requests and complaints: support@dedupe.dev. More ways to reach us on the contact page.
Last updated