Action Hooks Reference
All action hooks provided by Benecaster. Each hook name links to its reference page with full parameter docs, usage notes, and code examples.
Hooks are not a paid feature — we don’t charge for them and none of them is gated behind a purchase. Hooks marked Premium sit on code paths that only run on a licensed install, so on an unlicensed site they simply never fire; there is nothing for them to act on. Everything else fires on any install.
Show Lifecycle
| Hook | Description |
|---|---|
benecaster_show_created |
Fires after a new show is saved for the first time |
benecaster_show_updated |
Fires after an existing show is updated |
benecaster_show_trashed |
Fires after a show is moved to trash; slot recovery happens immediately — the trashed show no longer counts toward the site’s show limit |
benecaster_show_deleted |
Fires before a show is permanently deleted |
Episode Lifecycle
| Hook | Description |
|---|---|
benecaster_episode_created |
Fires after a new episode is saved for the first time |
benecaster_episode_updated |
Fires after an existing episode is updated (post-table fields only) |
benecaster_episode_meta_updated |
Fires after episode meta is saved; includes before/after diff of changed keys |
benecaster_episode_references_updated |
Fires after a reference entry is created, updated, or deleted on an episode |
benecaster_episode_field_values_updated |
Fires after custom field values are saved on an episode |
benecaster_episode_published |
Fires when an episode’s post status transitions to publish |
benecaster_episode_unpublished |
Fires when an episode’s post status leaves publish |
benecaster_episode_deleted |
Fires before an episode is permanently deleted |
benecaster_episode_note_added |
Fires after a production note is added to an episode via benecaster_add_episode_note() |
Subscription Lifecycle
| Hook | Description |
|---|---|
benecaster_subscription_activated |
Fires when a subscriber becomes active on any bridge |
benecaster_subscription_cancelled |
Fires when any bridge reports a subscription has been cancelled |
benecaster_subscription_tier_changed |
Fires when a subscriber moves from one tier to another |
benecaster_subscription_renewed |
Fires on each successful recurring payment after the initial subscription |
benecaster_subscription_payment_failed |
Fires when a subscriber’s payment fails after the grace period elapses |
Token Lifecycle
| Hook | Description |
|---|---|
benecaster_token_generated |
Fires immediately after a new subscriber token is created |
benecaster_token_accessed |
Fires on every valid feed request after the token is verified |
benecaster_token_reset |
Fires after a subscriber’s token is reset and a new one is active |
benecaster_token_reset_send_email |
Fires when admin selects “Reset and send email” in the token reset dialog; hook here to dispatch the reset email |
benecaster_token_revoked |
Fires when a subscriber’s token is explicitly revoked |
benecaster_token_invalid |
Fires when a feed request presents a token that fails validation |
benecaster_subscriber_no_active_membership |
Fires when a valid token is presented but the subscriber has no active mapped membership tiers |
Feed
| Hook | Description |
|---|---|
benecaster_feed_before_render |
Fires after HTTP headers are sent but before feed XML is output |
benecaster_feed_after_render |
Fires immediately after feed XML is echoed to output |
Feed Cache
(Premium hooks — fire only on paid plans)
| Hook | Description |
|---|---|
benecaster_clear_feed_cache |
Call this action to trigger a feed cache clear (global, show-scoped, or tier-scoped) |
benecaster_feed_cache_cleared |
Fires after any feed cache clear completes, regardless of what triggered it |
Custom Fields
| Hook | Description |
|---|---|
benecaster_field_value_saved |
Fires after a custom field value is written to the database |
Setup and Configuration
| Hook | Description |
|---|---|
benecaster_setup_wizard_completed |
Fires once when the setup wizard is completed |
benecaster_bridge_connected |
Fires each time an admin saves a bridge selection |
benecaster_redirect_expiry_run |
Fires after expired <itunes:new-feed-url> redirect tags are removed |
Bridge and Tier Events
| Hook | Description |
|---|---|
benecaster_tier_unmapped |
Fires when a tier detected by the bridge has no Benecaster tier mapping; fires from both real-time tier-save events and the daily sync fallback |
benecaster_bridge_switched |
Fires after the Bridge Switch Wizard completes; new tier mappings saved and active bridge updated |
benecaster_tier_map_updated |
Fires after PUT /bridge/tier-map saves a batch of tier mappings; fires from the grid view, list view, and bridge switch wizard |
benecaster_bridge_new_levels_detected |
Fires when the tier mapping screen finds at least one membership level not in the stored seen-set; built-in admin notice reacts automatically |
SSP / PowerPress Import Events
| Hook | Description |
|---|---|
benecaster_ssp_import_after |
Fires after all SSP episodes have been processed for a show; includes runs with zero new drafts |
benecaster_ssp_episode_imported |
Fires after each individual SSP draft episode is created; $ssp_post provides the original post |
benecaster_powerpress_import_after |
Fires after all PowerPress episodes have been processed for a show; fires after benecaster_ssp_import_after in combined jobs |
benecaster_powerpress_episode_imported |
Fires after each individual PowerPress draft episode is created; $pp_post provides the original post |
Analytics and Data Management
| Hook | Description |
|---|---|
benecaster_shadow_records_purged |
Fires after each nightly shadow record purge run; fires even when $count === 0; threshold controlled by benecaster_shadow_record_expiry_days |
Subscriber Engagement
| Hook | Description |
|---|---|
benecaster_token_first_accessed |
Fires the first time a subscriber’s podcast app polls a valid feed token — confirms the app is configured and working |
benecaster_subscriber_feed_inactive |
Fires once per inactivity event when an active subscriber stops polling past the configured threshold |
benecaster_subscriber_feed_reactivated |
Fires when a previously inactive subscriber polls their feed again |
Templates — Show Page
| Hook | Description |
|---|---|
benecaster_before_show_render |
Fires before the show page wrapper renders; receives $show_id (int) |
benecaster_after_show_render |
Fires after the show page wrapper closes; receives $show_id (int) |
benecaster_before_show_header |
Fires before the show header (title, artwork, description) renders |
benecaster_after_show_header |
Fires after the show header closes |
benecaster_before_show_subscribe_links |
Fires before the subscribe links block renders |
benecaster_after_show_subscribe_links |
Fires after the subscribe links block closes |
benecaster_before_show_tiers |
Fires before the tier listing renders |
benecaster_after_show_tiers |
Fires after the tier listing closes |
benecaster_before_show_episode_list |
Fires before the embedded episode list renders |
benecaster_after_show_episode_list |
Fires after the embedded episode list closes |
benecaster_before_show_stats |
Fires before the public stats block renders (hidden by default — enable via benecaster_show_stats_visible filter) |
benecaster_after_show_stats |
Fires after the public stats block closes |
benecaster_show_stats_items |
Fires inside the stats block; echo additional <li> items to add custom stats |
Templates — Locked State
| Hook | Description |
|---|---|
benecaster_before_locked_message |
Fires before the locked state message renders in the player or content area; receives $episode_id (int), $show_id (int) |
benecaster_after_locked_message |
Fires after the locked state message closes; receives $episode_id (int), $show_id (int) |
benecaster_before_upgrade_prompt |
Fires before the upgrade prompt renders (shown to logged-in subscribers at wrong tier); receives $episode_id (int), $show_id (int), $required_tier (string), $user_tier (string) |
benecaster_after_upgrade_prompt |
Fires after the upgrade prompt closes; same args as above |
benecaster_before_login_prompt |
Fires before the login prompt renders (shown to logged-out visitors); receives $episode_id (int), $show_id (int) |
benecaster_after_login_prompt |
Fires after the login prompt closes; receives $episode_id (int), $show_id (int) |
Templates — Episode Archive
| Hook | Description |
|---|---|
benecaster_before_episode_archive |
Fires before the archive wrapper renders |
benecaster_after_episode_archive |
Fires after the archive wrapper closes |
benecaster_before_archive_header |
Fires before the archive header (title + description) renders |
benecaster_after_archive_header |
Fires after the archive header closes |
benecaster_before_archive_filters |
Fires before the episode filter bar renders |
benecaster_after_archive_filters |
Fires after the episode filter bar closes |
benecaster_before_archive_pagination |
Fires before pagination renders |
benecaster_after_archive_pagination |
Fires after pagination closes |
benecaster_before_archive_no_results |
Fires before the empty-state message renders |
benecaster_after_archive_no_results |
Fires after the empty-state message closes |
benecaster_before_episode_card |
Fires before each episode card renders; receives (int $episode_id, bool $can_access) |
benecaster_after_episode_card |
Fires after each episode card closes; receives (int $episode_id, bool $can_access) |
benecaster_before_episode_card_artwork |
Fires before the artwork section of an episode card |
benecaster_after_episode_card_artwork |
Fires after the artwork section of an episode card |
benecaster_before_episode_card_title |
Fires before the title section of an episode card |
benecaster_after_episode_card_title |
Fires after the title section of an episode card |
benecaster_before_episode_card_meta |
Fires before the meta section of an episode card (episode number, duration, pub date) |
benecaster_after_episode_card_meta |
Fires after the meta section of an episode card |
benecaster_before_episode_card_excerpt |
Fires before the excerpt section of an episode card |
benecaster_after_episode_card_excerpt |
Fires after the excerpt section of an episode card |
benecaster_before_episode_card_player |
Fires before the player section of an episode card |
benecaster_after_episode_card_player |
Fires after the player section of an episode card |
benecaster_before_episode_card_locked |
Fires before the locked state section of an episode card |
benecaster_after_episode_card_locked |
Fires after the locked state section of an episode card |
Admin Subscriber Actions
| Hook | Description |
|---|---|
benecaster_subscriber_access_revoked |
Fires when an admin manually revokes a subscriber’s access via the dashboard |
benecaster_subscriber_tier_overridden |
Fires when an admin manually overrides a subscriber’s tier via the dashboard |
benecaster_admin_tier_change_notify |
Fires when admin enables “Send notification” during a tier change; hook here to send a tier change notification email |
benecaster_admin_revoke_notify |
Fires when admin enables “Send notification” during access revocation; hook here to send a revocation notification email |
Email Events
| Hook | Description |
|---|---|
benecaster_before_email_send |
Fires before any Benecaster email is dispatched; use for logging (type-specific variant: benecaster_before_email_send_{type}) |
benecaster_after_email_send |
Fires after any Benecaster email is sent (type-specific variant: benecaster_after_email_send_{type}) |
benecaster_email_send_failed |
Fires when an email send failure is detected |
benecaster_email_unsubscribed |
Fires after a subscriber’s email opt-out is recorded |
benecaster_email_resubscribed |
Fires when a subscriber re-opts in to emails after previously opting out |
benecaster_email_queue_job_complete |
Fires when all rows in a job group reach terminal status (sent or failed); use to update migration or broadcast status records |
Subscriber Account (Front End)
| Hook | Description |
|---|---|
benecaster_before_account |
Fires before the account shortcode wrapper renders; receives $user_id (int) |
benecaster_after_account |
Fires after the account shortcode wrapper closes; receives $user_id (int) |
benecaster_before_account_subscription |
Fires before the subscription section renders; receives $show_id (int), $user_id (int) |
benecaster_after_account_subscription |
Fires after the subscription section closes; receives $show_id (int), $user_id (int) |
benecaster_before_account_feed_url |
Fires before the feed URL section renders; receives $show_id (int), $user_id (int) |
benecaster_after_account_feed_url |
Fires after the feed URL section closes; receives $show_id (int), $user_id (int) |
benecaster_before_account_token_reset |
Fires before the token reset section renders; receives $show_id (int), $user_id (int) |
benecaster_after_account_token_reset |
Fires after the token reset section closes; receives $show_id (int), $user_id (int) |
benecaster_before_account_app_links |
Fires before the app links section renders; receives $show_id (int), $user_id (int) |
benecaster_after_account_app_links |
Fires after the app links section closes; receives $show_id (int), $user_id (int) |
benecaster_before_account_qr_code |
Fires before the QR code section renders; receives $show_id (int), $user_id (int) |
benecaster_after_account_qr_code |
Fires after the QR code section closes; receives $show_id (int), $user_id (int) |
benecaster_account_sections |
Fires at the end of each subscription card inside [benecaster_account]; add-ons echo additional HTML sections; receives $show_id (int), $user_id (int) |
License Events
(All hooks in this section are Premium — fire only on paid plans or when license validation runs)
| Hook | Description |
|---|---|
benecaster_license_validated |
Fires when the daily validation cron receives a valid response from the license server |
benecaster_license_invalid |
Fires when validation returns an explicit rejection (status: "invalid") from a reachable server |
benecaster_license_expiring |
Fires when a license is within 30 days of its expiry date |
benecaster_validation_failure |
Fires every day the license server is unreachable; passes the cumulative consecutive failure day count |
benecaster_license_hard_limit_reached |
Fires after 30 consecutive days of server-unreachable failures; premium features are restricted until the next successful validation |
benecaster_license_free_threshold_warning |
Fires when a site’s paying subscriber count reaches 80% of its plan’s limit, at most once per calendar month. A notice cadence, not a plan-change signal |
Seven licence-enforcement action names do not exist in Benecaster and never fire:
benecaster_license_overage_month_1,_month_2,_cleared,benecaster_license_free_bump_confirmed,benecaster_license_downgrade_locked,benecaster_license_auto_upgrade_firedandbenecaster_license_downgrade_lock_expired. They are named here because a callback attached to one of them simply never runs — nothing errors — so a licence hook that seems dead is worth checking against this page. The premises they describe are not how licensing works: overage is counted on a rolling window held by the licence server, which the plugin cannot see, and there is no downgrade lock.
Data Export
| Hook | Description |
|---|---|
benecaster_before_export |
Fires before XLSX file generation begins for the “Your Data” export |
benecaster_after_export |
Fires after the export XLSX is written to a temporary file, before the download response is sent |
Shortcode Extension
| Hook | Description |
|---|---|
benecaster_subscribe_tier_content |
Fires inside each tier card in [benecaster_subscribe]; add-ons echo custom HTML below the tier name and price |