# How to delete your personal data from the internet: data broker opt-outs

> AI Release · @ai_release1 · https://ai-release.org/guides/kak-udalit-svoi-personalnye-dannye-iz-interneta-zaprosy_en.html

## TL;DR
- Time to complete: about 60 minutes for setup and the first broker request; each additional broker depends on its form.
- Difficulty: Intermediate
- You will need: bash, `curl`, `python3`, a text editor, a CSV viewer or spreadsheet app, an email address you control, and access to each broker’s opt-out page or privacy contact. Record installed versions with the check commands below.

A data broker is a company that collects and resells personal profiles. An opt-out is the broker’s process for stopping the sale or display of your data. This workflow is local-first: you keep the request text, confirmations, and verification output on your own machine.

## Requirements and setup
![Illustration: Requirements and setup](https://ai-release.org/guides/img/kak-udalit-svoi-personalnye-dannye-iz-interneta-zaprosy-en-1.jpg?v=1794128022)

- Linux or macOS with bash, or Windows 10/11 with WSL or Git Bash. The commands below use bash syntax.
- `curl` and `python3` installed. Check them before starting; do not assume a version.
- A private working folder. Enable full-disk encryption before storing request confirmations; check your OS documentation for the exact setting.
- A text editor: `nano`, `vim`, VS Code, or Notepad++.
- A CSV viewer: a spreadsheet app or the `column` command. If `column` is missing, use `cat`.
- An email address you control for broker replies. Do not use a shared inbox.
- Access to each broker’s published opt-out form or privacy contact. If the broker does not publish one, check its privacy policy and documentation.
- If GDPR or CCPA applies, verify the statutory deadline in the broker’s privacy notice. GDPR is EU data protection law; CCPA is California privacy law. Do not assume a fixed number of days.

If you are choosing consumer AI tools for this workflow, see [AI tools for everyday people: what is actually useful](https://ai-release.org/guides/ii-instrumenty-dlya-zhizni.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

Check the base tools:

```bash
curl --version
python3 --version
bash --version
```

Example output shape:

```text
curl 8.x.x ...
Python 3.x.x
GNU bash, version 5.x.x ...
```

Your versions can differ. Save the output in `~/privacy-removal/tool-versions.txt` so you can reproduce the workflow later.

## Step 1. Create the local removal workspace and inventory

**What to do:** Create a folder structure, a request log, and a short inventory of the personal data you want removed. Use one row per broker, not one row per data point.

```bash
mkdir -p ~/privacy-removal/{inbox,outbox,evidence}
cd ~/privacy-removal
printf 'broker,category,profile_url,request_date,request_id,status,next_check\n' > removal-log.csv
curl --version > tool-versions.txt
python3 --version >> tool-versions.txt
```

Create the inventory file:

```bash
cat > inventory.txt <<'EOF'
Full name: Alex Example
City: Example City
Emails: alex@example.com
Phone: +1-555-0100
Usernames: alex-example
Public profile URLs to check:
- https://<broker-domain>/profile/123
EOF
```

Replace every `<...>` value with the real value from the broker’s page or your own records. Keep the example row format:

```text
broker,category,profile_url,request_date,request_id,status,next_check
Acme Data,people-search,https://<broker-domain>/profile/123,2025-01-15,ACME-12345,submitted,2025-02-14
```

**Why:** A local log prevents duplicate requests and gives you evidence if a profile reappears. The inventory keeps the minimum facts needed for a deletion request; do not collect more than the broker asks for.

**How to check:** Confirm the files exist and the CSV header is correct.

```bash
find . -maxdepth 2 -type f -print
head -1 removal-log.csv
```

Expected output:

```text
./removal-log.csv
./inventory.txt
./tool-versions.txt
broker,category,profile_url,request_date,request_id,status,next_check
```

## Step 2. Submit broker deletion requests and capture evidence
![Illustration: Step 2. Submit broker deletion requests and capture evidence](https://ai-release.org/guides/img/kak-udalit-svoi-personalnye-dannye-iz-interneta-zaprosy-en-2.jpg?v=1794128028)


**What to do:** Create one reusable deletion-request template, render a broker-specific copy, submit it through the broker’s published channel, and log the request ID.

Create the template:

```bash
cd ~/privacy-removal
cat > deletion-request.txt <<'EOF'
To: <broker-privacy-contact>
Subject: Personal data deletion request - <full-name>

Broker: <broker-name>
Profile URL: <profile-url>
Requester: <full-name>
Contact email: <email>

Please delete the personal data associated with the profile above. If your organization requires a specific form or identity check, reply with the required channel and the request reference number.

Thank you,
<full-name>
EOF
```

Render an example request with Python’s standard library:

```python
python3 - <<'PY'
from pathlib import Path

fields = {
    "<broker-privacy-contact>": "privacy@acme-data.invalid",
    "<full-name>": "Alex Example",
    "<broker-name>": "Acme Data",
    "<profile-url>": "https://acme-data.invalid/profile/123",
    "<email>": "alex@example.com",
}

text = Path("deletion-request.txt").read_text()
for key, value in fields.items():
    text = text.replace(key, value)

Path("outbox/request-acme.txt").write_text(text)
print("wrote outbox/request-acme.txt")
PY
```

Expected output:

```text
wrote outbox/request-acme.txt
```

The `.invalid` domain is a reserved example domain. Replace it with the real broker contact and profile URL from the broker’s privacy page.

Submit the generated text through the broker’s opt-out form or privacy email. After submission, copy the confirmation into `inbox/` and add the request ID to the CSV:

```bash
printf 'Acme Data,people-search,https://<broker-domain>/profile/123,2025-01-15,ACME-12345,submitted,2025-02-14\n' >> removal-log.csv
```

| Evidence | Local path | What it proves |
|---|---|---|
| Exact request text | `outbox/request-acme.txt` | What you sent and when |
| Broker confirmation | `inbox/acme-confirmation.eml` | Request ID and broker response |
| Public profile check | `evidence/acme-profile-check.html` | Whether the page was still reachable |

**Why:** A rendered copy proves the exact wording and recipient. A request ID is the reference you use in follow-ups. The table keeps evidence separate from your working notes.

**How to check:** Confirm that no placeholder remains and that the log row is present.

```bash
grep -q '<' outbox/request-acme.txt && echo "ERROR: placeholder remains" || echo "OK: no placeholders"
grep 'ACME-12345' removal-log.csv
```

Expected output:

```text
OK: no placeholders
Acme Data,people-search,https://<broker-domain>/profile/123,2025-01-15,ACME-12345,submitted,2025-02-14
```

If you use an AI agent to draft replies or sort confirmations, apply the controls in [AI agent security: protecting your data during automation](https://ai-release.org/guides/bezopasnost-ii-agentov-kak-zaschitit-dannye-i-izbezhat.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

## Step 3. Verify removal and schedule rechecks
![Illustration: Step 3. Verify removal and schedule rechecks](https://ai-release.org/guides/img/kak-udalit-svoi-personalnye-dannye-iz-interneta-zaprosy-en-3.jpg?v=1794128034)


**What to do:** Check the public profile URL, save the HTTP result, update the CSV status, and set a recheck date.

```bash
cd ~/privacy-removal
curl -L -s -o evidence/acme-profile-check.html -w '%{http_code}\n' 'https://<broker-domain>/profile/123'
```

Example result:

```text
404
```

A `404` supports removal: the profile page is no longer reachable. A `200` means the page is still live. A `403` or `429` is inconclusive; open the URL manually in a private browser window and record what you see.

Update the log after verification:

```python
python3 - <<'PY'
import csv
from pathlib import Path

p = Path("removal-log.csv")
rows = list(csv.DictReader(p.open()))
for row in rows:
    if row["request_id"] == "ACME-12345":
        row["status"] = "removed"
        row["next_check"] = "2025-02-14"

with p.open("w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=rows[0].keys())
    writer.writeheader()
    writer.writerows(rows)

print("updated")
PY
```

Expected output:

```text
updated
```

Final checklist:

- [ ] Request text saved in `outbox/`
- [ ] Broker confirmation saved in `inbox/`
- [ ] Public profile checked and saved in `evidence/`
- [ ] CSV status updated
- [ ] Recheck date added to your calendar

**Why:** Removal is not complete when the form is submitted. You need a public-page check and a dated follow-up because profiles can be recreated or relisted.

**How to check:** Confirm the status changed and the evidence file is not empty.

```bash
grep 'ACME-12345' removal-log.csv
wc -c evidence/acme-profile-check.html
```

Expected output shape:

```text
Acme Data,people-search,https://<broker-domain>/profile/123,2025-01-15,ACME-12345,removed,2025-02-14
1234 evidence/acme-profile-check.html
```

The byte count will differ. A zero-byte file means the request produced no saved body; rerun `curl` without `-s` and inspect the error.

## Troubleshooting

**Problem. The verification command cannot resolve the broker host.**
- Error: `curl: (6) Could not resolve host: <broker-domain>`
- Cause: the placeholder was pasted literally, or the broker domain is misspelled.
- Solution: replace `<broker-domain>` with the exact host from the broker’s privacy page, then test DNS before rerunning the check:

```bash
getent hosts <real-broker-domain>
curl -I 'https://<real-broker-domain>/'
```

**Problem. The Python renderer cannot find the template.**
- Error: `python3: can't open file 'render_request.py': [Errno 2] No such file or directory`
- Cause: the command was run from a different directory, or the script was saved under another name.
- Solution: change into the workspace and list the files:

```bash
cd ~/privacy-removal
ls -la
python3 - <<'PY'
from pathlib import Path
print(Path("deletion-request.txt").exists())
PY
```

Expected output:

```text
True
```

**Problem. The placeholder check reports an error.**
- Error: `ERROR: placeholder remains`
- Cause: one or more `<...>` fields in `deletion-request.txt` were not replaced before submission.
- Solution: find the remaining placeholder and replace it, then rerender:

```bash
grep -n '<' outbox/request-acme.txt
```

## Summary and next steps
You now have a local evidence log, a tested request template, and a verification command. Next, replace the example broker with a real one, submit one request, and schedule the recheck date in your calendar.

## FAQ

**Do I have to pay a data broker to delete my data?**
Use the broker’s published free opt-out or privacy contact where one exists. If a broker offers a paid service, verify the price and terms on its own page before paying.

**How long does a data broker deletion request take?**
Deadlines vary by broker and jurisdiction. Check the broker’s privacy notice or confirmation email for the stated deadline; do not rely on a fixed number from another guide.

**Can I remove a people-search profile without creating an account?**
Many brokers provide a web form or privacy email that does not require a full account. If the form requires verification, use the minimum identity proof the broker documents and keep the confirmation.

**Are local tools enough to keep my data removed?**
Local tools give you a repeatable log and evidence, but they do not force a broker to act. You still need to submit each request through the broker’s channel and recheck the public profile on your scheduled date.
