Import a follower list from code
Add a list of email addresses as free followers from an external system or your own code. Subscribers → Bulk enroll → Add as: Followers is the admin screen for this; these are the two programmatic routes to the same code. Use it for a mailing list, a Patreon export’s free members, or a newsletter you are folding into the show — anywhere you have addresses and want each one to get a follower feed.
From another system
Call the REST endpoint with an application password for an administrator. Leave out tier_slug — a follower is not a tier:
curl -X POST https://your-site.com/wp-json/benecaster/v1/shows/42/subscribers/bulk-enroll \
-u 'admin-user:xxxx xxxx xxxx xxxx xxxx xxxx' \
-H 'Content-Type: application/json' \
-d '{"token_type":"follower","addresses":["ana@example.com","ben@example.com"]}'
The batch runs on the next WP-Cron tick; poll GET /shows/42/subscribers/bulk-enroll/status for the report. Up to 1,000 addresses per request.
In-process
From an add-on or a WP-CLI command in your own plugin, run it synchronously and read the report directly — see the code example.
An address that already has a token for the show is left exactly as it is — reported already_enrolled, not converted, not emailed. That includes paying subscribers: an import of your whole mailing list will not turn your paying members into followers. Do not try to “fix” a row by revoking and re-importing it; a revoked token still counts as having one.
Every new follower is sent a welcome email, even when the show’s welcome email is switched off — it is the only way a follower receives their feed URL (the plaintext token exists once, at generation). Warn whoever owns the list before you run it.
The 100-follower cap on an unlicensed install applies to imports too, and has no filter. Rows past it come back skipped with message: follower_cap_reached; handle that rather than looking for a way around it. On a connected show the cap does not apply.
Double opt-in is honoured. If a site returns true from benecaster_follower_double_optin, imported addresses are sent a confirmation email instead of a token, and the row reads created with message: confirmation_sent. $enrolled on benecaster_bulk_enrollment_complete counts them too — check $token_type (the action’s sixth argument) before treating $enrolled as new paying members.
token_type accepts only subscriber and follower; anything else is refused (400 over REST, InvalidArgumentException in-process).
Not at a keyboard and need someone added one at a time instead? See Build a custom follower signup UI.
Code
<?php
add_action( 'benecaster_boot', function ( \Benecaster\Container $container ): void {
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}
\WP_CLI::add_command( 'my-addon import-followers', function ( array $args, array $assoc ) use ( $container ): void {
$show_id = absint( $assoc['show'] ?? 0 );
$addresses = file( (string) ( $args[0] ?? '' ), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ) ?: [];
$report = $container
->make( \Benecaster\Membership\BulkEnrollmentProcessor::class )
->enroll( $addresses, $show_id, '', token_type: 'follower' );
foreach ( $report['rows'] as $row ) {
if ( 'follower_cap_reached' === ( $row['message'] ?? '' ) ) {
\WP_CLI::warning( "{$row['email']}: follower limit reached — connect the show to add more." );
}
}
\WP_CLI::success( sprintf( 'Added %d, already on the show %d, skipped %d, errors %d.',
$report['enrolled'], $report['already_enrolled'], $report['skipped'], $report['errors'] ) );
} );
} );