Skip to main content

Read the Analytics Dashboard cohort retention matrix

Premium Intermediate

GET benecaster-analytics/v1/analytics/cohort groups subscribers by the UTC calendar month they first joined, and counts how many of each month were still subscribed at the end of the join month and of each month after. It takes show_id, date_from, date_to and an optional scope (show, the default, or all), with the same permission and errors as the other Analytics Dashboard routes (see Read or extend the Analytics Dashboard growth series and Read every Analytics Dashboard route for All my shows); a tier_slug is accepted and ignored. Cohorts are whole months: every month the range touches, so a range starting on the 15th counts that month’s joins from the 1st (cohort_from says where it began). On Benecaster’s admin page the add-on publishes its own REST base as window.benecasterAnalyticsDashboard.apiUrl, which works under every permalink setting.

  • retained[0] is the end of the join month and each later entry a month later; the last entry of every row ends on date_to, not on the month’s last day. Later cohorts have shorter rows. retained_pct is a percentage of size, one decimal, and null for a cohort of 0.
  • A join is a joined event, or a synced event with source = 'bridge_sync' on the member’s real start. A follower who starts paying has a second joined row and stays in the cohort of their first. churned ends a subscription and reactivated brings it back; licence_grace rows are the podcaster’s licence, not the subscriber, and change nothing.
  • The matrix is approximate, and notes says by how much: synced_undated (members linked with no start date, never in a cohort), join_not_on_record (a subscriber whose history in the range does not start with a join: pruned by a retention period, or older than the log), and erased_joins / erased_churns (rows an erasure unlinked from their subscriber, which cannot be paired). Say so beside any matrix you draw.
  • Change the matrix for every caller with the benecaster_analytics_cohort filter. Its $args are show_ids, date_from, date_to and tier_slug (always null); a non-array return is ignored.

Code

const url = window.benecasterAnalyticsDashboard.apiUrl
    + 'analytics/cohort?show_id=12&date_from=2026-05-01&date_to=2026-10-28';
const matrix = await ( await fetch( url, { headers: { 'X-WP-Nonce': window.benecasterAdmin.nonce } } ) ).json();
// matrix.columns → 6
// matrix.cohorts[0] → { month: '2026-05', size: 40, retained: [ 38, 35, 33, 31, 30, 30 ], retained_pct: [ 95, 87.5, 82.5, 77.5, 75, 75 ] }

View on GitHub →

Hooks Used

Need this built rather than just documented? See our services →