Read the Analytics Dashboard tier breakdown and tier movement
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/tier-breakdown and GET /analytics/tier-movement take show_id, date_from, date_to, an optional tier_slug and an optional scope (show, the default, or all; see Read every Analytics Dashboard route for All my shows), with the same errors as the growth route. The breakdown’s period is the date range itself, and its prior period is the same number of days immediately before. On Benecaster’s admin page the add-on publishes its own REST base as window.benecasterAnalyticsDashboard.apiUrl, which works under every permalink setting.
- Not Benecaster’s own
GET benecaster/v1/shows/{id}/analytics/tiers, which is fixed at 30 days, has no prior period and misses tier moves. active_pctis already a percentage (7.9means 7.9%), rounded to one decimal, andnullwhen the prior period’s count is 0 or unknown.- Change either answer for every caller with the
benecaster_analytics_tier_breakdownandbenecaster_analytics_tier_movementfilters.
Code
const base = window.benecasterAnalyticsDashboard.apiUrl; // the add-on's own REST base
const q = 'show_id=12&date_from=2026-10-01&date_to=2026-10-30';
const headers = { 'X-WP-Nonce': window.benecasterAdmin.nonce };
const breakdown = await ( await fetch( base + 'analytics/tier-breakdown?' + q, { headers } ) ).json();
const movement = await ( await fetch( base + 'analytics/tier-movement?' + q, { headers } ) ).json();
// breakdown.total.change → { active: 18, active_pct: 7.9 }
// movement.moves[0] → { from_tier: 'free', to_tier: 'basic', direction: 'upgraded', count: 8 }
Hooks Used
Need this built rather than just documented? See our services →