Read the Analytics Dashboard migration funnel
GET benecaster-analytics/v1/analytics/migration-funnel lists every migration batch the Migration Wizard reports for the shows in view, with its imported, still to finish, signed up and lapsed counts, as of now. It takes show_id and an optional scope (show, the default, or all), with the same permission and 403 as the other Analytics Dashboard routes (see Read every Analytics Dashboard route for All my shows); there is no date range, and any date_from, date_to or tier_slug is ignored. The add-on reads each show through the Migration Wizard’s benecaster_migration_get_funnel() (see Read a show’s migration funnel from PHP, including on cron) and never its tables, so the figures are the Migration tab’s. On Benecaster’s admin page the add-on publishes its own REST base as window.benecasterAnalyticsDashboard.apiUrl, which works under every permalink setting.
availableis install-wide only: whether the Migration Wizard is running on the site. A show it is not switched on for and a show that never migrated both contribute no batches, and nothing in the answer tells them apart, by the Migration Wizard’s design: never build a message on the difference.pendingis the Migration Wizard’s still to finish, derived and floored at zero there, so the four counts need not add up; never recompute it.completedis signed up, free tiers included, not paying;droppedis lapsed, people whose deadline passed.records_free_tiers: falseis a batch from before the Migration Wizard recorded which tiers were free; its deadline is never enforced, so its still to finish never falls. Read it, neverstatus, which is an open set passed on as stored.source_platformandstatuscome back exactly as stored: escape them for where you write them, and guard a leading=,+,-or@in a CSV cell.- With
scope=alleach show where the add-on is active is read on its own;show_namesays whose batch it is. Batches are newest import first across the shows. - Change the funnel for every caller with the
benecaster_analytics_migration_funnelfilter. Its$argsareshow_ids; a non-array return is ignored.
Code
const url = window.benecasterAnalyticsDashboard.apiUrl + 'analytics/migration-funnel?show_id=12';
const funnel = await ( await fetch( url, { headers: { 'X-WP-Nonce': window.benecasterAdmin.nonce } } ) ).json();
if ( ! funnel.available || funnel.batches.length === 0 ) {
// Nothing to show: no Migration Wizard, or no migration on these shows. Do not say which.
}
// funnel.batches[0] → { show_id: 12, show_name: 'Night Shift', id: 4, source_platform: 'patreon', import_date: '2026-09-01T10:00:00+00:00',
// imported: 40, completed: 12, dropped: 3, pending: 25, grace_period_days: 30, grace_ends_at: '2026-10-01T10:00:00+00:00',
// status: 'active', records_free_tiers: true }
// funnel.totals → { imported: 40, completed: 12, dropped: 3, pending: 25 }
Hooks Used
Need this built rather than just documented? See our services →