[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-77268":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":13,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":18,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":15,"starSnapshotCount":15,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},77268,"auto-identity-remove","stephenlthorn\u002Fauto-identity-remove","stephenlthorn","Automated data broker opt-out runner — removes your personal info from 30+ people-search sites on a monthly schedule",null,"JavaScript",739,34,4,1,0,25,325,18,76.13,false,"main",true,[],"2026-06-12 04:01:21","# auto-identity-remove\n\n![CI](https:\u002F\u002Fgithub.com\u002Fstephenlthorn\u002Fauto-identity-remove\u002Factions\u002Fworkflows\u002Ftest.yml\u002Fbadge.svg)\n\nAutomated data broker opt-out runner for macOS, Linux, and Windows. Removes your personal information from **500+ people-search sites and data broker databases** on a monthly schedule - with CAPTCHA solving, persistent state tracking (so completed opt-outs aren't resubmitted every run), and an iMessage notification when done. [**Privacy & data flow ->**](docs\u002FPRIVACY.md)\n\n## What it does\n\nEach month, the script:\n\n1. **Searches** each data broker site for your name + state\n2. **Finds your specific listing** (for sites that need a profile URL)\n3. **Fills and submits** the opt-out form automatically\n4. **Solves CAPTCHAs** via [CapSolver](https:\u002F\u002Fcapsolver.com) (AI-powered, ~$0.001\u002Fsolve)\n5. **Skips** brokers you were already removed from recently (90-day re-check window)\n6. **Sends you an iMessage** with the results summary\n7. **Opens** any sites that require manual action in your browser\n\n---\n\n## Requirements\n\n- Node.js 18+\n- macOS, Linux, or Windows (scheduling adapts automatically)\n- [Playwright](https:\u002F\u002Fplaywright.dev) browsers installed\n\n```bash\nnpx playwright install chromium\n```\n\n---\n\n## Quick Start\n\n```bash\n# 1. Clone the repo\ngit clone https:\u002F\u002Fgithub.com\u002Fstephenlthorn\u002Fauto-identity-remove.git\ncd auto-identity-remove\n\n# 2. Install dependencies\nnpm install\n\n# 3. Run interactive setup (creates config.json and schedules the monthly job)\nnode setup.js\n\n# 4. Run manually anytime\n.\u002Frun.sh\n```\n\n---\n\n## Setup walkthrough\n\n`node setup.js` guides you through:\n\n| Step | What it does |\n|------|-------------|\n| **Personal info** | Name, city, state, ZIP, email, phone |\n| **Aliases** | Past names or variations (e.g. \"Steve Doe\") |\n| **CapSolver key** | For CAPTCHA-protected opt-out forms |\n| **One-time accounts** | Creates accounts on sites that require login (stored in `config.json`, gitignored) |\n| **iMessage** | Phone number to text the results summary to |\n| **Monthly schedule** | Registers a monthly job to run on the 1st at 9am (launchd \u002F systemd \u002F crontab \u002F schtasks - detected automatically) |\n\n**Your personal info never leaves your machine.** `config.json` and `state.json` are both gitignored.\n\n---\n\n## CapSolver (optional but recommended)\n\nSome opt-out forms have reCAPTCHA. Without CapSolver, those sites go to your manual list instead of being handled automatically.\n\n1. Sign up at [capsolver.com](https:\u002F\u002Fcapsolver.com) - free, pay-as-you-go\n2. Add $1–2 of credits (enough for months of use at ~$0.001\u002Fsolve)\n3. Paste your API key when `setup.js` asks, or add it to `config.json`:\n\n```json\n\"capsolver\": {\n  \"apiKey\": \"CAP-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n}\n```\n\n---\n\n## Running with Docker\n\nThe included `Dockerfile` uses the official Playwright image, so Chromium and\nall system dependencies are pre-installed. No Mac required.\n\n```bash\n# Build the image (once)\ndocker build -t auto-identity-remove .\n\n# Dry-run (no opt-out forms submitted, no network calls)\ndocker run --rm \\\n  -v $(pwd)\u002Fconfig.json:\u002Fapp\u002Fconfig.json \\\n  -v $(pwd)\u002Fstate.json:\u002Fapp\u002Fstate.json \\\n  auto-identity-remove node watcher.js --dry-run\n\n# Full run\ndocker run --rm \\\n  -v $(pwd)\u002Fconfig.json:\u002Fapp\u002Fconfig.json \\\n  -v $(pwd)\u002Fstate.json:\u002Fapp\u002Fstate.json \\\n  auto-identity-remove\n```\n\n**Persistent state:** mount `state.json` so completed opt-outs are remembered\nbetween container runs. If the file does not exist yet, create an empty one\nfirst: `echo '{}' > state.json`.\n\n### Webhook notifications (any OS)\n\nWhen running headless or in Docker you won't have iMessage or a desktop - use\na webhook instead. Set `notify.webhook` in `config.json` to any ntfy.sh,\nSlack incoming-webhook, or Discord webhook URL:\n\n```json\n\"notify\": {\n  \"textTo\": \"\",\n  \"webhook\": \"https:\u002F\u002Fntfy.sh\u002Fmy-private-channel\"\n}\n```\n\nThe tool POSTs `{\"text\": \"\u003Csummary>\"}` after every run. Works on macOS, Linux,\nand Windows - the webhook fires in addition to (not instead of) any platform\nnotification that is available.\n\n---\n\n## Files\n\n```\nauto-identity-remove\u002F\n├── setup.js            ← Run once: interactive setup + scheduling\n├── watcher.js          ← Main runner\n├── brokers.js          ← Broker list with opt-out strategies\n├── run.sh              ← Manual trigger\n├── config.example.json ← Template (copy → config.json)\n├── package.json\n├── .gitignore\n│\n├── config.json         ← YOUR personal info (gitignored, created by setup.js)\n├── state.json          ← Opt-out history \u002F skip logic (gitignored)\n└── logs\u002F               ← Per-run JSON logs (gitignored)\n```\n\n---\n\n## State tracking\n\n`state.json` tracks when each broker was last successfully opted out. The default re-check window is **90 days** - brokers typically re-add your data within that window, so the script re-submits when it's time.\n\n```json\n{\n  \"optOuts\": {\n    \"Spokeo\": {\n      \"lastSuccess\": \"2026-05-01T09:00:00.000Z\",\n      \"totalRuns\": 3,\n      \"detail\": \"\"\n    }\n  }\n}\n```\n\nOn each run you'll see:\n- `✅ Submitted (form accepted)` - opt-out form was submitted this run\n- `📧 Awaiting email confirm` - broker replied \"check your email to confirm\"; click the link in your inbox. Auto-retried after 14 days if still pending.\n- `⏭  Skipped (fresh)` - removed recently, re-check not due yet\n- `🔍 Not listed` - your name wasn't found on that site\n- `📋 Manual needed` - opened in your browser for you to handle\n- `❌ Error` - network\u002Ftimeout issue, will retry next run\n- `💀 Dead (stale URL)` - broker URL is gone (DNS\u002F404); not counted as an error\n\n> **Submitted ≠ confirmed deleted.** Use `node watcher.js --verify` for spot-check verification. See [STATUS.md](STATUS.md) for a per-broker confidence table.\n\n## How confident should I be?\n\nThis tool covers 500+ data brokers in two tiers:\n\n| Tier | Count | Confidence |\n|---|---|---|\n| **Explicit brokers** ([STATUS.md](STATUS.md)) | 42 | Hand-mapped with specific selectors. `verified` entries have been tested live; `untested` ones may have drifted since they were added. |\n| **Generic runner** | ~490 | Best-effort heuristic - tries 4 strategies (Do Not Sell click, OneTrust\u002FTrustArc, generic form, DSAR link). Many succeed; some fail silently. |\n\nThe `✅ Submitted` count means the form was accepted by the broker. It does **not** prove deletion. To check:\n\n1. Run `node watcher.js --verify` - re-searches each broker where a successful opt-out was recorded and reports whether your name still appears.\n2. Look at the `📧 Awaiting email confirm` section after each run - these are half-done until you click the link.\n\nIf you want to know exactly which brokers are hand-verified vs heuristic, see [STATUS.md](STATUS.md).\n\n---\n\n## Brokers covered\n\n### Auto-removed (30+)\n\n| Site | Method |\n|------|--------|\n| Spokeo | Search → find listing → opt-out form |\n| WhitePages | Search → find listing → suppression form |\n| FastPeopleSearch | Search → opt-out form |\n| TruePeopleSearch | Direct opt-out form |\n| BeenVerified | Opt-out search form |\n| Radaris | Search → privacy form |\n| Intelius | Direct opt-out form |\n| PeopleFinders | Direct opt-out form |\n| PeopleSmart | Direct opt-out form |\n| MyLife | Search → opt-out |\n| Nuwber | Search → removal form |\n| FamilyTreeNow | Direct opt-out form |\n| CheckPeople | Direct opt-out form |\n| ThatsThem | Direct opt-out form |\n| USPhonebook | Direct opt-out form |\n| PublicDataUSA | Direct opt-out form |\n| SmartBackgroundChecks | Direct opt-out form |\n| SearchPeopleFree | Direct opt-out form |\n| PeopleSearchNow | Direct opt-out form |\n| InfoTracer | Direct opt-out form |\n| SocialCatfish | Direct opt-out form |\n| NationalPublicData | Direct opt-out form |\n| ClustrMaps | Direct opt-out form |\n| PrivateRecords | Direct opt-out form |\n| **Acxiom** | Direct form (feeds dozens of downstream brokers) |\n| **LexisNexis** | Direct form (legal\u002Ffinancial data) |\n| **ZoomInfo** | Direct form (B2B professional data) |\n| **Clearbit** | Direct form (B2B enrichment data) |\n| Pipl | Email opt-out via Mail.app |\n\n### Generic - 500+ additional brokers (auto-detected)\n\n`generic-runner.js` handles the remaining ~470 brokers from two public datasets:\n\n| Dataset | Source | Count |\n|---------|--------|-------|\n| [The Markup's data broker list](https:\u002F\u002Fthemarkup.org\u002Fprivacy\u002F2023\u002F01\u002F26\u002Fwhich-data-brokers-offer-opt-outs) | Journalism research, 494 opt-out URLs | ~494 |\n| [BADBOOL](https:\u002F\u002Fgithub.com\u002Fyaelwrites\u002FBig-Ass-Data-Broker-Opt-Out-List) | Community-maintained people-search list | ~27 extra |\n\nFor each site it tries four strategies in order:\n1. Click a \"Do Not Sell My Personal Information\" button\n2. Opt out via OneTrust \u002F TrustArc \u002F Osano privacy manager\n3. Fill any generic opt-out form (email, name, state) and submit\n4. Find and record a DSAR \u002F data request link for manual follow-up\n\nSites requiring manual action are opened in your browser automatically.\n\n### Manual (opened in browser for you)\n\n| Site | Why manual |\n|------|-----------|\n| Google - Results About You | Requires Google account interaction |\n| Google - Outdated Content | Case-by-case URL submission |\n\n---\n\n## Adding more brokers\n\nEdit `brokers.js` and add an entry:\n\n```js\n{\n  name: 'NewBrokerSite',\n  method: 'direct-form',           \u002F\u002F or 'search-form', 'email', 'manual'\n  optOutUrl: 'https:\u002F\u002Fexample.com\u002Fopt-out',\n  formFields: {\n    'input[name*=\"first\" i]': F,   \u002F\u002F F, L, N, E, ST, Z are from config\n    'input[name*=\"last\"  i]': L,\n    'input[type=\"email\"]':    E,\n  },\n  submitSelector: 'button[type=\"submit\"]',\n  captchaLikely: false,\n  priority: 2,\n}\n```\n\nPRs welcome - especially for brokers with verified working selectors.\n\n---\n\n## Manual run\n\n```bash\n.\u002Frun.sh\n```\n\n**Dry-run mode** - navigates to each site and fills forms but does NOT submit anything. Good for verifying what the script will do before your first real run:\n\n```bash\nnode watcher.js --dry-run\n```\n\nOr to run in the background and log output:\n\n```bash\n.\u002Frun.sh >> logs\u002Fmanual-run.log 2>&1 &\n```\n\n### Verifying removals (`--verify`)\n\nRun a read-only spot-check to see whether previous opt-outs are still in effect:\n\n```bash\nnode watcher.js --verify\n```\n\nThis opens a browser, searches each broker where you have a recorded successful opt-out, and reports what it finds. No forms are submitted, nothing is written to `state.json`.\n\nOutput is grouped into three sections:\n\n| Section | Meaning |\n|---------|---------|\n| `VERIFIED CLEAR` | Your name was not found in the broker's search today |\n| `STILL LISTED` | A listing was found - the opt-out may have failed, or your data was re-added |\n| `UNVERIFIABLE` | The broker uses a direct-form, email, or manual method - no automated search signal exists to check |\n\nA dated JSON report is saved to `logs\u002Fverify-YYYY-MM-DD.json`.\n\n**Important caveats:**\n\n- Only `search-form` brokers (those with a `searchUrl` and `listingPattern`) can be checked automatically. Direct-form and email opt-outs are always `unverifiable`.\n- \"Verified clear\" means your name was not found in one search today. It is **not** a legal guarantee of deletion. Brokers routinely re-ingest data from upstream sources.\n- \"Still listed\" can mean the opt-out failed **or** the broker re-added your data since the last successful opt-out was recorded. Either way, re-running `node watcher.js` will attempt removal again.\n- If the broker's search page is down or slow, the result is classified as `unverifiable` (a timeout is not counted as \"still listed\").\n\n---\n\n## Experimental: noise mode\n\n> **WARNING: This feature may violate broker Terms of Service.** Submitting fabricated opt-out requests to data broker sites is ethically questionable and could expose you to legal risk. Use at your own discretion. This feature is **off by default** and is provided only as a research\u002Fexperimental tool.\n\nThe `--pollute N` flag submits `N` randomly-generated fake person records to data brokers that are explicitly tagged `acceptsBogus: true` in `brokers.js`. The goal (inspired by a suggestion on HN) is to flood broker databases with junk records, degrading the accuracy of their search results.\n\n```bash\n# Submit 10 bogus records to each acceptsBogus broker\nnode watcher.js --pollute 10\n```\n\nEach fake record uses:\n- A random name from a small fixture list (not real people)\n- A US city\u002Fstate\u002Fzip from a fixture of 50+ valid combos (not your address)\n- A 10-digit phone with an area code valid for the fake state\n- A randomised `firstname.lastname+XXXXXX@gmail.com` email\n\nOnly brokers tagged `acceptsBogus: true` in `brokers.js` will receive noise submissions. Currently tagged: ThatsThem, SearchPeopleFree, PeopleSearchNow, InfoTracer, SocialCatfish. These are direct-form brokers with no SSN\u002FDOB gate.\n\n**Regular opt-outs run first** - noise submissions happen after the normal run. The `--pollute` flag has no effect on your real opt-out submissions.\n\n---\n\n## Maintenance\n\n### Pruning stale \u002F dead URLs\n\nThe Markup dataset is years old; many of the ~489 generic opt-out URLs now 404 or fail DNS lookup. These are classified as `💀 Dead (stale URL)` in run output and do **not** count as errors.\n\nAfter several runs have accumulated in `logs\u002F`, trim permanently-dead hostnames from future runs so they are skipped without any network request:\n\n```bash\nnode scripts\u002Fprune-dead.js\n```\n\nThe script:\n1. Reads every `logs\u002Frun-*.json` file\n2. Finds hostnames whose status was `dead` in **every** run they appeared in\n3. Merges them into `data\u002Fdead-urls.json` (deduped, sorted)\n4. Prints a summary of how many new hosts were added\n\nThe script is **idempotent** - running it twice produces no change. You can add it as a post-run step or run it manually whenever you want to prune the dead list.\n\n`data\u002Fdead-urls.json` is committed to the repo so the dead list is shared with all clones.\n\n---\n\n## Uninstall \u002F disable schedule\n\n| Platform | Command |\n|----------|---------|\n| **macOS** (launchd) | `launchctl unload ~\u002FLibrary\u002FLaunchAgents\u002Fcom.auto-identity-remove.plist` then `rm ~\u002FLibrary\u002FLaunchAgents\u002Fcom.auto-identity-remove.plist` |\n| **Linux** (systemd) | `systemctl --user disable --now auto-identity-remove.timer` then `rm ~\u002F.config\u002Fsystemd\u002Fuser\u002Fauto-identity-remove.{service,timer}` |\n| **Linux** (crontab fallback) | Run `crontab -e` and delete the `auto-identity-remove` line |\n| **Windows** (schtasks) | `schtasks \u002FDelete \u002FTN auto-identity-remove \u002FF` |\n\n---\n\n## International users\n\nThis tool supports non-US users with a few important caveats.\n\n### What works\n\n- `setup.js` will prompt for **Country** (2-letter ISO code, e.g. `CA`, `GB`, `AU`) and then replace the US-centric \"State\" \u002F \"ZIP code\" prompts with **Province\u002FRegion** and **Postal code** prompts that accept any format (`K1A 0A6`, `SW1A 1AA`, `2000`, etc.) with no coercion.\n- Phone numbers for non-US users are stored verbatim - no `(xxx) xxx-xxxx` reformatting is applied.\n- `lib\u002Fforms.js` automatically tries province\u002Fpostal\u002Fpostcode HTML field variants (e.g. `input[name*=\"province\"]`, `input[name*=\"postcode\"]`) when filling forms for non-US users, with no change needed in broker definitions.\n- A country `\u003Cselect>` on opt-out forms is targeted and filled with your 2-letter country code when present.\n- Global brokers (ZoomInfo, Clearbit, Acxiom, Radaris, etc.) are attempted for all users.\n\n### US-only brokers (automatically skipped for non-US users)\n\nThe following brokers are flagged `usOnly: true` and are silently skipped when your configured country is not `US`. These sites index US public records, voter data, or phone directories - a non-US person definitionally has no record to remove there:\n\n| Broker | Reason |\n|--------|--------|\n| Spokeo | US people-search (state-keyed search) |\n| WhitePages | US white-pages directory |\n| FastPeopleSearch | US people-search |\n| TruePeopleSearch | US people-search |\n| BeenVerified | US background-check (requires US state) |\n| USPhonebook | US phone directory |\n| PublicDataUSA | US public records |\n\nAll other brokers in the list are attempted regardless of country.\n\n### What won't help much\n\nUS people-search sites (`Spokeo`, `WhitePages`, etc.) hold records sourced from US public records - if you have never lived in the US, your data is very unlikely to appear on these sites. The script skips them for you automatically.\n\n---\n\n## Is it safe to submit my info to 500 opt-out forms?\n\nA fair concern raised by some users: aren't you just confirming your data to the brokers by filling out their forms?\n\nA few things worth knowing:\n\n- **These brokers already have your info.** You're not revealing anything new - you're using the legally-required removal mechanism they're obligated to provide.\n- **CCPA (California) and similar state laws require brokers to honor opt-out requests.** Submitting the form creates a legal obligation to remove you. Doing nothing does not.\n- **The script uses info you're already listed under** - your name as it appears publicly, your state, your email. It doesn't add new data points.\n- **The alternative is worse.** Every month that passes, more brokers scrape and resell your data. Opt-outs are imperfect, but they work more often than not.\n\nThat said: if you're in a situation where even confirming your email address to a broker is a risk, this tool is not the right approach. Consider a paid service that uses a proxy email.\n\n---\n\n## California residents: DELETE Registry (August 2025)\n\nCalifornia is launching an official **Delete Me** opt-out registry on August 1, 2025. Once registered, data brokers are legally required to delete your info automatically - no individual form submissions needed for participating brokers.\n\nRegister at: **[optoutregistry.oag.ca.gov](https:\u002F\u002Foptoutregistry.oag.ca.gov)** (live August 1)\n\n**Recommended:** Register with the CA Delete Registry first, then run this script for the brokers that aren't covered.\n\n---\n\n## Why not just use a paid service?\n\nPaid services like [Incogni](https:\u002F\u002Fincogni.com) ($96\u002Fyr) or [Optery](https:\u002F\u002Foptery.com) ($39\u002Fyr) are excellent and cover more brokers with professionally maintained opt-out flows. This tool is for people who want full control, transparency, and no recurring subscription - or who want to handle the gaps those services miss (Acxiom, LexisNexis, ZoomInfo, Clearbit).\n\nUsing both is the strongest approach: a paid service for the bulk of brokers + this script for the gaps.\n\n---\n\n## License\n\nMIT\n","auto-identity-remove 是一个自动化工具，旨在帮助用户从500多个个人信息搜索网站和数据经纪人数据库中定期移除个人资料。其核心功能包括自动填写并提交退出表单、解决CAPTCHA验证、跟踪已完成的操作以避免重复提交，并在处理完成后通过iMessage发送通知。该工具利用了Node.js环境与Playwright库来实现跨平台（macOS, Linux, Windows）的浏览器自动化操作，同时支持使用CapSolver服务来处理复杂的CAPTCHA挑战。适用于重视隐私保护、希望减少公开个人信息暴露风险的个人用户。",2,"2026-06-11 03:55:13","CREATED_QUERY"]