Admin overview
The admin overview lives at https://booking.netwit.ca/admin. After you sign in, this is the first page you land on. It is meant to answer one question fast: is the platform healthy and is revenue growing?
Top-of-page KPIs
Four cards, computed live from GET /api/admin/stats:
| KPI | What it counts | Source |
|---|---|---|
| Tenants | All-time count of rows in tenants | SELECT COUNT(*) FROM tenants |
| Users | Owners + staff across all tenants | SELECT COUNT(*) FROM users |
| Bookings (30d) | Bookings created in the last 30 days; subtitle shows all-time total | created_at >= now-30d |
| GMV (30d) | Sum of successful payment amounts in the last 30 days; subtitle shows paying tenant count | payments WHERE status='succeeded' AND created_at >= now-30d |
plan = 'pro' × $29 (plus any Enterprise contracts tracked manually in the Plans and billing page). Read the Plans and billing guide for the exact formula.Response shape
{
"data": {
"totals": {
"tenants": 124,
"users": 312,
"customers": 4821,
"bookings": 9876,
"recentBookings30d": 1184,
"payingTenants30d": 47,
"gmv30d": 68420
},
"signupsByDay": [
{ "day": "2026-07-19", "c": 3 },
{ "day": "2026-07-20", "c": 5 },
{ "day": "2026-07-21", "c": 2 }
]
}
}Charts
The overview page renders three charts from the stats response:
- Tenant growth (7 days) — a bar chart of
signupsByDay. If you see a flat week, check whether the marketing site is up and the signup form is reachable. - Bookings over time (30 days) — derived client-side from
recentBookings30dand a same-period comparison. The current build only shows the 30d total; a per-day series is on the roadmap. - Revenue by plan (30 days) — bar chart bucketing
gmv30dby tenant plan. Free tenants contribute zero to GMV. Pro and Enterprise tenants are the only contributors.
Recent activity
Below the charts, the page lists the five most recent tenants with their plan, signup time, and a link to the full record. The Recent tenants panel pulls GET /api/admin/tenants?limit=5 and renders the same row shape used by the tenants list.
Two pieces of activity are not yet surfaced on the overview but are available elsewhere:
- Latest churn — there is no automatic "churn" event in the platform today. A tenant is "churned" when its
is_active = 0or its plan is manually downgraded from pro to free. Use the audit log filtered bytenant.plan_changedto find the latest ones. - Latest support tickets — BookFlow does not yet run an in-app ticketing system. Tickets arrive by email to
hello@netwit.caand are tracked in the shared support inbox, not in this overview.
Refresh cadence
The overview polls the API every 30 seconds while the tab is visible. There is no push or websocket in the current build — if you need a real-time number (e.g. during a launch, or while a tenant is upgrading), refresh the page manually.
API
/api/admin/statsPlatform-wide totals (tenants, users, customers, bookings, recentBookings30d, payingTenants30d, gmv30d) plus a 7-day signup series. Requires a super_admin JWT.
Sample call
curl https://booking-api.netwit.ca/api/admin/stats \
-H "Authorization: Bearer $ADMIN_TOKEN"Response
{
"data": {
"totals": {
"tenants": 124,
"users": 312,
"customers": 4821,
"bookings": 9876,
"recentBookings30d": 1184,
"payingTenants30d": 47,
"gmv30d": 68420
},
"signupsByDay": [
{ "day": "2026-07-19", "c": 3 }
]
}
}Field reference
totals.tenantsintegerAll-time count of rows in the tenants table. Includes suspended and deleted tenants.
totals.usersintegerAll-time count of rows in users (owners + staff). Does not include customer accounts.
totals.customersintegerAll-time count of rows in customers (the per-tenant customer profile table).
totals.bookingsintegerAll-time count of rows in bookings, regardless of status.
totals.recentBookings30dintegerBookings with created_at >= now-30d. Status-agnostic.
totals.payingTenants30dintegerCOUNT(DISTINCT tenant_id) of payments with status='succeeded' in the last 30 days.
totals.gmv30dintegerSum of amount (in minor units — cents) for successful payments in the last 30 days.
signupsByDayarrayOne row per day for the last 7 days: {`day: "YYYY-MM-DD", c: number`}. Sorted ascending by day. Days with zero signups are not included.
What this page does not do
- It does not show system health — that's the System health page.
- It does not show audit log entries — that's the Audit log page.
- It does not let you take action on a tenant. To suspend, restore, or change a plan, open the tenant's detail page.
Email hello@netwit.ca or call +1-604-206-8169. NetWit responds in 1 business day.