Skip to main content

Read or extend the Analytics Dashboard growth series

Premium Intermediate

The Analytics Dashboard add-on’s REST namespace is benecaster-analytics/v1, separate from Benecaster’s own benecaster/v1 analytics routes. Its routes need manage_options and a wp_rest nonce in X-WP-Nonce, and answer 403 benecaster_analytics_not_active for a show where the add-on is not switched on.

GET /analytics/growth takes show_id (required), date_from and date_to (inclusive UTC Y-m-d; a date_to after today is read as today), an optional tier_slug, an optional interval (day, week, month; without it, up to 92 days is per day, up to 731 per week, longer per month) and an optional scope (show, the default, or all for every show where the add-on is active; see Read every Analytics Dashboard route for All my shows). An unusable range is 400 benecaster_analytics_invalid_range, with data.reason invalid_date, starts_in_future, ends_before_start or too_long (over 3,660 days). On Benecaster’s admin page the add-on publishes its own REST base as window.benecasterAnalyticsDashboard.apiUrl, which works under every permalink setting:

const url = window.benecasterAnalyticsDashboard.apiUrl
    + 'analytics/growth?show_id=12&date_from=2026-10-01&date_to=2026-10-27';
const growth = await ( await fetch( url, { headers: { 'X-WP-Nonce': window.benecasterAdmin.nonce } } ) ).json();

To change what every panel, export and digest sees, filter the series, as below.

  • A point’s net always equals the change in its active, so a callback that removes counts from a point should change net and active together, or the chart’s lines and the tier table will disagree.
  • active is null for a day before the show’s first snapshot, not 0.
  • A member Member Sync linked with their real start (synced_dated) is in active from that start up to the day the sync ran. That day is read from the synced event’s own recorded_at, which Reset Token never moves. A row written before Benecaster database 1.103.0 has no recorded_at and falls back to the member’s token issued_at; when that token has been reset since, or the member was erased, the sync day cannot be known. The member is then still in new but not added to active before the sync, and notes.synced_not_backfilled counts them. On a site whose Benecaster database predates 1.103.0, every dated sync uses the token.

Code

<?php
add_filter( 'benecaster_analytics_growth_series', function ( array $data, array $args ): array {
    // Hide a staff-only tier from the chart.
    $data['tiers'] = array_values( array_filter( $data['tiers'], fn( $s ) => 'staff' !== $s['tier_slug'] ) );
    return $data;
}, 10, 2 );

View on GitHub →

Hooks Used

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