Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rc-clean

A small CLI that removes test / TestFlight / simulator customers from your RevenueCat projects without ever touching a real paying user. Sandbox and TestFlight builds create anonymous RevenueCat customers that pollute your New-Customer charts and cohort analytics; this tool finds and deletes exactly those, and leaves everyone else alone.

The one rule it trusts

A customer is test only if you can prove they are not a real App Store buyer. rc-clean pairs each RevenueCat customer's last-seen app version against Apple's App Store submissions and TestFlight build inventory:

  • The app has never been released → any customer must be TestFlight/sim.
  • The customer's last-seen version was never READY_FOR_SALE — including TF-only marketing versions (from ASC builds) and versions still in review / prepare → test.
  • Sandbox-only purchasers (no real App Store purchase) → test.
  • Non-purchasers first seen before the earliest public release → test.
  • Anyone with a real (non-sandbox) purchase is never deleted, full stop.

Because it re-checks Apple's live release states and TF builds on every run, it self-corrects as builds get approved. It uses Apple's public first-release date when available, then App Store Connect's releaseDate, and finally the earliest live build upload when the date fields are empty.

Install

git clone https://github.com/jackwallner/rc-clean.git
cd rc-clean
pip install pyjwt requests

Configure

1. Your app map — copy the example and fill in your projects:

mkdir -p ~/.rc-clean
cp apps.example.json ~/.rc-clean/apps.json
{
  "com.you.app": {
    "rc":   "<revenuecat-project-id>",
    "asc":  "<app-store-connect-app-id>",
    "name": "Your App",
    "allow_versions": []
  }
}

The RevenueCat project id is the short hash in your dashboard URL; the ASC app id is the numeric id in your App Store Connect app URL. rc-clean auto-detects which app you mean by walking up from the current directory to the nearest project.yml / Xcode project and matching its bundle id — so just run it from inside an app repo.

allow_versions is an optional list of marketing versions to keep regardless of App Store or TestFlight status. Values are canonicalized, so 1.3.0 and 1.3 match the same version. Use it only for deliberate per-app exceptions.

2. App Store Connect API key — a shell-style file at ~/.rc-clean/asc_credentials exporting an App Store Connect API key with app access:

export ASC_API_KEY_ID="XXXXXXXXXX"
export ASC_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export ASC_KEY_PATH="$HOME/.appstoreconnect/AuthKey_XXXXXXXXXX.p8"

3. RevenueCat auth — the tool uses a RevenueCat dashboard session token (the public REST API can't list or delete customers). Log in at app.revenuecat.com, open DevTools, and run:

fetch('/v1/developers/login/refresh-token', {
  method: 'POST',
  headers: { 'X-Requested-With': 'XMLHttpRequest' },
  credentials: 'include'
}).then(r => r.json()).then(d => copy(d.authentication_token))

Then seed it (stored at ~/.revenuecat/auth_token, chmod 600, and self-refreshing thereafter):

./rc-clean-test-users --reseed <paste-token>

Use

cd ~/my-app-repo
./rc-clean-test-users            # dry run: list what WOULD be deleted
./rc-clean-test-users --delete   # actually delete
./rc-clean-test-users --all-apps # every app in your config (dry run unless --delete)

Dry run is the default; nothing is deleted until you pass --delete.

Example

=== My App  (RC a1b2c3d4)  bundle com.you.app ===
released versions: NONE — app not public
scanning 12 customers...
  real (kept): 0   purchasers (kept): 0   TEST: 12
  test by version: (no detail)×5, 1.0.0×7
  (dry run — pass --delete to remove these 12)

Configuration reference

What Default Override
App map ~/.rc-clean/apps.json $RC_CLEAN_APPS
ASC creds ~/.rc-clean/asc_credentials $RC_CLEAN_ASC_CREDS
RC token ~/.revenuecat/auth_token $RC_CLEAN_TOKEN

Notes

  • RevenueCat deletion is asynchronous; a deleted customer 404s within minutes but may still appear in the enumeration index briefly. Re-running is safe and idempotent.
  • Ghost/anonymous rows whose detail endpoint 404s are reported as stale and skipped. They are already absent from the customer detail endpoint.

License

MIT — see LICENSE.

About

CLI to delete RevenueCat test/TestFlight/simulator customers without ever touching a real paying user

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages