← back to Ga Allsites
GA4 cleanup: deleted Momentum DW property; goodquestion.ai + nosara blocked by SA permission on APPS account 371997142
1ad646331482694ace24fddde97e812742f19cc2 · 2026-08-17 16:33:24 -0700 · Steve Abrams
Files touched
A delete_orphan_ga4.pyM gtm/rollout-status.md
Diff
commit 1ad646331482694ace24fddde97e812742f19cc2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 17 16:33:24 2026 -0700
GA4 cleanup: deleted Momentum DW property; goodquestion.ai + nosara blocked by SA permission on APPS account 371997142
---
delete_orphan_ga4.py | 18 ++++++++++++++++++
gtm/rollout-status.md | 11 +++++++++++
2 files changed, 29 insertions(+)
diff --git a/delete_orphan_ga4.py b/delete_orphan_ga4.py
new file mode 100644
index 0000000..d667ffc
--- /dev/null
+++ b/delete_orphan_ga4.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+"""Delete the 3 GA4 properties Steve approved (soft-delete, recoverable ~35 days)."""
+import pathlib
+from google.analytics.admin import AnalyticsAdminServiceClient
+KEY = pathlib.Path.home()/".config"/"ga-analytics-agent"/"service-account.json"
+TARGETS = [
+ ("G-9K93LH6GH1", "properties/548357651", "Momentum DW (momentum.designerwallcoverings.com)"),
+ ("G-QG3DGNYWZX", "properties/535741032", "goodquestion (goodquestion.ai)"),
+ ("G-JZRGWSY1F6", "properties/535735055", "nosarabeachfrontrentals (nosarabeachfrontrentals.com)"),
+]
+c = AnalyticsAdminServiceClient.from_service_account_file(str(KEY))
+for mid, prop, label in TARGETS:
+ try:
+ r = c.delete_property(name=prop) # soft-delete -> Trash, recoverable ~35d
+ state = getattr(r, "state", None)
+ print(f" ✅ DELETED {prop} [{mid}] {label} (state={state})")
+ except Exception as e:
+ print(f" ❌ FAILED {prop} [{mid}] {label}: {type(e).__name__}: {str(e)[:120]}")
diff --git a/gtm/rollout-status.md b/gtm/rollout-status.md
index 0d4ec78..adb6f83 100644
--- a/gtm/rollout-status.md
+++ b/gtm/rollout-status.md
@@ -179,3 +179,14 @@ The only true fact stands: the BARE domains momentumdw.com/goodquestion.com aren
actually measures them. not-owned-exclusions.json corrected accordingly.
LESSON: verify a GA4 property by its data-stream URI, never by its display NAME. The DOMAIN_MATCH dry-run
gate is what prevented a 3-property destructive delete.
+
+## CYCLE 15 — Steve approved deleting all 3; 1 done, 2 blocked by SA permission
+Steve chose "delete all 3" (with full disclosure it removes live analytics; soft-delete = 35d recoverable).
+Result:
+ - ✅ DELETED: Momentum DW (properties/548357651, acct steveabramsdesigns.com) — SA has Editor there.
+ - ❌ 403 PermissionDenied: goodquestion (properties/535741032) + nosarabeachfrontrentals (properties/535735055)
+ — both in the "Steve Abrams APPS" account (371997142) where the SA lacks delete rights.
+TO FINISH THE OTHER 2, either:
+ (a) Steve grants analytics-agent@dw-ga4-attribution.iam.gserviceaccount.com the "Editor" role on GA4 account
+ 371997142 (Admin > Account Access Management), then re-run delete_orphan_ga4.py; OR
+ (b) Steve deletes them by hand in GA4 UI (Admin > Property Settings > Move to Trash Can).
← 34f211e ABORT orphan-GA4 deletion: dry-run proved all 3 are legit (D
·
back to Ga Allsites
·
chore: lint (14 autofix) + light refactor of session GA4 scr 277b943 →