Receipts
Don't take my word for it.
Open the network tab.
Every privacy claim on this site is checkable in about two minutes, using a tool already built into your browser. This page tells you exactly what to look for, and what you will find. If any of it turns out to be false, that is a bug worth emailing us about — and worth telling other people about.
Every permission, and why
Five entries in the manifest: three permissions and two hosts. That is the whole list,
and you can confirm it on the store page before installing, or in
chrome://extensions afterwards.
The last two cards below are not permissions. They are the two requests the extension
makes to our own site, and both are described further down.
storage
Saves your deletion queue, your progress and your licence status in your own browser.
A long run has to survive a browser restart. Nothing here is sent anywhere — it is the same storage a browser uses to remember you dismissed a cookie banner.
alarms
Schedules a wake-up when X's rate limit window resets.
Deletion pauses roughly every 15 minutes to stay inside X's limits. Extension background workers are shut down when idle, so a timer would die; an alarm survives.
power
From version 0.4.4: asks your computer not to fall asleep while a deletion run is active.
A long run stops when the computer sleeps, and laptops left alone on battery sleep within minutes. The request covers idle sleep only: the screen can still turn off, and closing the lid still puts the computer to sleep. It is dropped when the run finishes, pauses or stops, and within a few minutes if the X tab is closed in the middle of a run.
x.com
Access to the X tab you already have open.
This is where the work happens. The extension reads your own posts and issues the delete requests from inside the page, using the session you are already signed in with.
licence check
A licence key check against api.gumroad.com, when you activate a key and then at most once a week.
Its full contents are printed below. It fires once when you activate, then at most once a week to confirm the key is still valid.
fix file
A small settings file read from tweetxdelete.com when you press Scan, and again every ten minutes during a long run.
X changes its internal endpoints without notice. This file lets us ship a fix in minutes instead of waiting days for a store review. It is a plain GET with no parameters: the request carries nothing about you, and the file contains data only, never code. The same file also holds a pause switch: if we ever find that deletion is unsafe because of a change on X, we can stop new and running deletions from our side. If we cannot be reached, the pause expires after a day so you are never locked out of a product you paid for.
error report
One anonymous line sent to tweetxdelete.com only when X returns an error the extension cannot recover from.
So we learn X broke something from the first user it hits, not from a refund request a week later. The line holds a fixed word for what broke, X's endpoint name, the HTTP status, the numeric error codes X returned, the key names in its reply with no values, and two short labels the extension writes itself. None of X's own text is sent, and no username, no user ID, no post IDs, no post text, no cookies. At most one line per error type per hour.
Nothing about you leaves your device
Deletion requests go to x.com — that is X talking to itself, through your own session. Beyond x.com there are exactly three requests the extension can make, and none of them carries anything about you or your account: the licence check below (only if you buy), a settings file it reads from tweetxdelete.com when you scan, and one anonymous error line it sends to tweetxdelete.com if X breaks something. Each is described on this page.
POST https://api.gumroad.com/v2/licenses/verify
product_id=MB0w5utE2opJkCQhW9H2iw==
license_key=<the key you typed>
increment_uses_count=true (on activation) or false (weekly recheck)
That is the entire payload. The product_id is a fixed label for this product, the same for every customer. No username, no user ID, no post IDs, no counts, no archive contents, no session cookie. The recheck repeats at most once a week, and if it fails because your internet is down, the extension keeps working — a paying customer losing access over a dropped connection would be a worse bug than a copied key.
There is a test in the codebase whose only job is to guard this boundary: if anyone ever adds a fourth field to that request body, the test fails and the build stops.
The fix file and the error line
X renames its internal endpoints without warning. Since version 0.4.0 the extension reads a small settings file from our site when you press Scan, so a fix can go out in minutes instead of waiting days for a store review. The request is a plain GET with no parameters; the file contains endpoint names and feature flags, never code. If X returns an error the extension cannot recover from, it sends one anonymous line so we hear about it from the first person it hits. This is the entire line:
GET https://tweetxdelete.com/engine/config.json (no body, no parameters)
POST https://tweetxdelete.com/api/telemetry (only after an unrecoverable X error)
v=1 (the line format, so old and new versions cannot be confused)
kind=delete_stale (one of eight fixed words, it says what broke)
operation=DeleteTweet (one of X's nine endpoint names, or empty)
status=404 (the HTTP code X returned, 0 to 599)
queryId=<X's public endpoint id> (read from X's own bundle, not from you)
codes=179 (the error codes in X's reply, five whole numbers at most)
reason=no_evidence (our own short word for why the run gave up)
shape=delete_tweet,errors (the key names in X's reply, never the values; long digit runs are masked)
note=retry=id stale_tries=2 (our own short label, restricted alphabet)
version=0.4.0, channel=ext, ts=<time>
None of X's own text is in there. What leaves the extension is X's error code numbers, the key names from its reply, and a few short words the extension writes itself. No username, no user ID, no post IDs, no post text, no counts, no cookies, no page content. A given combination of what broke, which endpoint and which HTTP code is sent at most once an hour, and no more than ten lines an hour in total; our server limits it a second time. The counter is written before the request leaves, so a failed report never turns into a retry. The request carries a header the extension sets. Nothing is stored on our side: the line is forwarded to a chat we read and dropped.
Check it yourself
- Open your X tab with the extension installed, then press F12 (or right-click → Inspect) and choose the Network tab.
- Start a small deletion run — set the limit to 3, so you are risking almost nothing.
- Watch the request list. Everything you see will be going to x.com. Filter by "Domain" if it helps.
- Look for a second domain. You will see one GET to tweetxdelete.com/engine/config.json when you scan, with no parameters. If you have activated a licence you will also find api.gumroad.com, and its request body is exactly the three fields printed above, nothing more. A POST to tweetxdelete.com/api/telemetry appears only if X returns an error the extension cannot get past. Its body is the short line printed above, it carries a header the extension sets, and the same error type will not appear again within the hour.
- Load an archive file and watch the network tab stay silent. The file is read in the page; it never becomes an upload.
What this page does not claim
Being honest about the edges matters more than the claims themselves. Deletion is permanent and we cannot recover anything for you. X can change its website at any time, which is what browser-side tools depend on, so the extension needs maintenance to keep working. And nothing anyone deletes can reach the screenshots other people already took.
What we do claim is narrow and testable: your posts, your archive and your session stay on your device. Only two things ever leave it. Your licence key, on its way to the payment provider, and a line of error codes and fixed words if X breaks something, with none of your own content in it.