Signed up, never logged in, still free — likely never came back.
Show sample emails
Conversion Funnel
Signups — Last 14 Days
Top Countries
App Version Distribution
OS Distribution
Active Users by Day
Page Views
Daily Events
Top Features
Errors
Hardware Breakdown
GPU Vendor
GPU Model
CPU Model
RAM Distribution
Reliability & Adoption
The headline "every problem" view — crashes, hangs, update failures, version adoption, and which
settings users keep vs revert. Honors the time range above. Empty panels usually mean low telemetry
coverage (see the coverage tile).
Error & Crash Feed
Problem
Code
Count
Installs
Top ver.
First seen
Last seen
Loading…
Update Funnel — who can't update
Failures by step
Freezes & Hangs
By app version
By context
Version Adoption
Most-Used Settings — apply vs revert
Saved views:
Email
Tier
Status
Country
Devices
Joined
Plan Mix — Active Subscriptions
Loading…
MRR Contribution by Plan
Loading…
Subscription Lifecycle
Saved views:
Quick filters:
Time
Admin
Action
Target
Summary
IP
Loading…
Scheduled Audit Digests
Saved view
Cadence
Recipient
Last sent
Next fire
Loading…
Digest preview
Loading preview…
Preview only — no email is sent. The rendered HTML is exactly what the digest would deliver.
Audit entry
Time:
Admin:
Target:
IP:
Entry ID:
Details (JSON)
Other actions on this target user
Status
From
Subject
Received
Actions
Click Refresh to load inbox
(loading…)
From:
To:
Received:
Body
Attachments
Send a transactional email using the universal PULSE layout (the worker wraps the structured fields into the brand template).
Recipients are comma-separated. The worker enforces rate limits and writes an audit row for every send.
CTA text (optional)
CTA URL (https://…)
Footer note (optional, small text below CTA)
Templates
Attachments
Show rendered preview
Live kill-switches and rollout gates. Flip a flag here and clients pick it up on next app boot (or within 60 s on the worker side) — no rebuild, no redeploy. Flags marked DANGEROUS blast the whole fleet, so they require a typed-confirmation step before saving. Hover the badge to see the exact impact of flipping each one. Use View change history to see who last touched a flag.
New flag
Key (lowercase snake_case)
Description (optional)
Value (JSON: true, false, "string", etc.)
Key
Value
Description
Updated by
Updated at
Actions
Loading...
Beta Unlock Windows
Schedule a window during which every free-tier user gets Pro (or Lifetime) features. Lets you run community beta tests of new Pro features without manually flipping each user. Propagation: a window that ends reverts free users within ~60s; a window that starts applies within ~5 min for already-running sessions and instantly on the next app launch (each launch re-validates).
⚡ Active beta window
Window
Tier override
Reason
Created by
Actions
No windows yet — click "+ New window" to schedule one.
Schedule a beta unlock window
Starts at (local time)
Ends at (local time)
Tier override
Reason (admin label)
Push a banner or blocking modal into the running desktop app. Clients poll /v1/announcements/active every 60 s, so a new announcement appears for users within a minute of Publish. Draft stores it without showing (start date is set to 2099). Audience filters by current tier; each user can dismiss once.
New announcement
Severity
Picks the colour + icon. Critical renders as a blocking modal — use only for outages or required-action.
Audience
Filters by effective tier at delivery time. Lapsed-Pro becomes Free automatically — no double-targeting.
→ targets … users
Dismissible (X button)
On = user clicks X and never sees it again (per-user). Off = stays until ends_at or deletion. Off is best for outages only.
Info
Neutral grey strip. Default for changelogs, tips, FYI.
Success
Green strip. "Maintenance over", "purchase landed", wins.
Red blocking modal. Outage, breach, mandatory update.
Title (1-200 chars)
0 / 200
Shown in bold at the top of the banner / modal. Keep under 80 chars — long titles wrap awkwardly in the desktop app.
Body (1-4000 chars, plain text)
0 / 4000
Plain text only. URLs are auto-linked. Line breaks preserved. No HTML, no markdown.
Live preview — this is how the desktop banner will render
Starts at (optional — defaults to now)
Blank = appears immediately on publish. Set a future date to schedule. Local timezone, stored as UTC.
Ends at (optional — open-ended if blank)
Blank = stays up forever (until you delete it). Set a far-future date if "Save as draft" — drafts use a 2099-01-01 start internally.
CTA text (optional)
"CTA" = call-to-action button label. Leave blank for an info-only banner with no button.
CTA URL (must start with http:// or https://)
Opens in the user's default browser when clicked. Use absolute URLs only. Internal app links not supported.
Status
Title
Severity
Audience
Starts
Ends
Actions
Loading...
Live worker / Supabase / KV / rate-limit metrics. Read-only —
GET /admin/health.
Em-dashes mean the metric isn't measured server-side (Sentry / Cloudflare Analytics has it).
Auto-refresh 60s
Fleet-wide advisory controls served to every client from
GET /v1/system/status (edge-cached ~30s — flips propagate fleet-wide in ≤30s).
Clients fail open: if the status endpoint is unreachable they treat everything as all-clear,
so an outage here can never brick the app. Admin routes and the status probe itself are
structurally exempt from every kill switch — you cannot lock yourself out.
Live status — /v1/system/status
Loading…
Hard outage (503 everything)
The big-hammer lever: every non-admin endpoint (web + desktop app) returns HTTP 503 until you turn it off.
Admin routes and this panel stay reachable so you can flip it back. Use for short windows only. This is
distinct from the advisory maintenance below (which only shows a message and never blocks).
Enable maintenance mode?
All non-admin endpoints will return HTTP 503 to every user (web + desktop app) until you turn it off.
Admin endpoints and the admin panel itself stay accessible so you can flip it back. Use this for
short maintenance windows only — keep it under a few minutes.
Maintenance (advisory)
Advisory maintenance messaging per surface. The desktop app and the website read it from the status
endpoint and show your message; nothing is hard-blocked (the hard 503 switch above does that).
An Until time auto-expires the window client-side and server-side.
Desktop app…
Message (shown in the app)
0 / 300
Until (optional)
Entered in your local timezone, stored as UTC ISO-8601. Leave blank for open-ended (manual off).
Website…
Message (shown on the website)
0 / 300
Until (optional)
Entered in your local timezone, stored as UTC ISO-8601. Leave blank for open-ended (manual off).
Kill switches
Disable a feature (or the whole API) fleet-wide. Feature ids mirror the desktop gates
(TIER_FEATURES); api 503s every /v1/* route except the status
probe; downloads is advisory — the app's update flow skips download/install while it is set.
Each save writes the full switch map and is step-up MFA gated + audit logged.
Loading…
Recent system actions
Latest system.maintenance.set / system.killswitch.set audit entries (client-side filter of the audit log).
Loading…
Activate maintenance?
I understand every client will show this maintenance state within ~30 seconds.
Kill the public API?
Every /v1/* endpoint will return 503 for every user (desktop + website)
until you turn it back off. /v1/system/status, the admin panel and this page
stay reachable so you can revert. Type KILL API to confirm.
Grant roles to admin users. The full catalogue (users + roles + permissions) is fetched once on tab open — every chip add/remove is local; the worker is only contacted when you click Save on a row. Granting super_admin requires explicit confirmation. You cannot modify your own roles (the server-side trigger blocks it).
Available roles
User
Roles
Effective permissions
Actions
Click the Roles & Permissions tab to load.
Only see yourself here? Other users appear in this list after they sign in on the website (that creates their account row). You can't change your own roles — ask another admin, or seed the first one with the bootstrap script below.
To grant a role: on another user's row, pick a role from the
+ Add role…
dropdown, then click
Save
on that row. New admins follow:
1. user signs in via the website
→
2. you grant a role here.
The very first super_admin is bootstrapped via pulse/supabase/scripts/bootstrap-first-admin.sql.
Sandbox for any catalogue-allowlisted /admin/* endpoint. Uses your current session token; the same auth checks (ADMIN_EMAILS + RBAC where active) apply. Read-only by default — POST/PATCH/DELETE require an extra confirm click so a stray click can't ship a destructive call.
Two-factor authentication for your admin account. Once enrolled, destructive actions
(tier change, refund, cancel subscription, suspend, delete) require a fresh 6-digit code
from your authenticator app (Google Authenticator, Authy, 1Password, …).
Status:Loading…
1. In your authenticator app (Google Authenticator, Authy, 1Password…),
scan the QR code below — or tap "Enter a setup key" and paste the manual key.
Manual entry key
Time-based · SHA-1 · 6 digits · 30-second period
2. Enter the current 6-digit code to finish:
Failed sign-ins
Failed authentication attempts from auth.audit_log_entries. A sudden spike can indicate credential stuffing.
Window
Loading failed-login data…
Hourly trend — last 7 days
Filter by email
Time
Event
IP
Loading…
Confirm with two-factor
This action needs a fresh code. Enter the current 6-digit code from your authenticator app.