Skip to main content

Module Hooks Reference

Module hooks fire when specific actions occur within Mumara Campaigns. This reference documents all available module hooks, their trigger conditions, and the data they provide. For an introduction to hooks, see the Hooks Overview.

Contact Hooks​

Hooks related to contact (subscriber) management.

AddContact​

Fires when a new contact is successfully added to a list.

add_hook('AddContact', 1, function($vars) {
// $vars contains:
// - subscriber: The Subscriber model object
// - fields: Array of custom field values

$subscriber = $vars['subscriber'];
$email = $subscriber->email;
$listId = $subscriber->list_id;
$fields = $vars['fields'];
});

EditContact​

Fires when an existing contact's information is updated.

add_hook('EditContact', 1, function($vars) {
// $vars contains:
// - subscriber: The updated Subscriber model
// - fields: Array of updated field values

$subscriber = $vars['subscriber'];
$updatedFields = $vars['fields'];
});

DeleteContact​

Fires when a contact is removed from the system.

add_hook('DeleteContact', 1, function($vars) {
// $vars is the Subscriber model object
$subscriberId = $vars->id;
$email = $vars->email;
$listId = $vars->list_id;
});

AutomationAddContact​

Fires when a contact is added through automation (web forms, API, imports).

add_hook('AutomationAddContact', 1, function($vars) {
// $vars contains:
// - subscriber_id: The new contact's ID
// - list_id: The contact list ID

$subscriberId = $vars['subscriber_id'];
$listId = $vars['list_id'];
});

AutomationEditContact​

Fires when a contact is edited through automation.

add_hook('AutomationEditContact', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact ID
// - list_id: List ID
// - requests: The request data
// - old_data: Previous contact data

$oldData = $vars['old_data'];
$newData = $vars['requests'];
});

TimelineEditContact​

Fires for timeline tracking when a contact is edited.

add_hook('TimelineEditContact', 1, function($vars) {
// $vars contains:
// - input: Request input data
// - subscriber_id: Contact ID
// - list_id: List ID
});

Contact List Hooks​

Hooks for contact list operations.

AddContactList​

Fires when a new contact list is created.

add_hook('AddContactList', 1, function($vars) {
// $vars contains:
// - list: Array of list data (from toArray())
// - custom_fields: Array of custom fields for the list

$listData = $vars['list'];
$listId = $listData['id'];
$listName = $listData['name'];
$customFields = $vars['custom_fields'];
});

EditContactList​

Fires when a contact list's settings are modified.

add_hook('EditContactList', 1, function($vars) {
// $vars contains:
// - list: Array of updated list data
// - custom_fields: Array of custom fields

$listData = $vars['list'];
});

DeleteContactList​

Fires when a contact list is deleted.

add_hook('DeleteContactList', 1, function($vars) {
// $vars is the ContactList model object
$listId = $vars->id;
$listName = $vars->name;
});

ImportList​

Fires when contact import is completed.

add_hook('ImportList', 1, function($vars) {
// $vars is the Import model object
$importId = $vars->id;
$listId = $vars->list_id;
$totalImported = $vars->total_imported;
});

ExportList​

Fires when a contact list export is completed.

add_hook('ExportList', 1, function($vars) {
// $vars is the list row data
$listId = $vars->id;
});

AutomationImportContacts​

Fires when contacts are imported through automation.

add_hook('AutomationImportContacts', 1, function($vars) {
// $vars contains:
// - list_id: Target list ID
// - user_id: User who initiated import
// - import_id: Import record ID
});

Custom Field Hooks​

Hooks for custom field management.

AddCustomField​

Fires when a new custom field is created.

add_hook('AddCustomField', 1, function($vars) {
// $vars is the CustomField model or array
$fieldId = $vars->id ?? $vars['id'];
$fieldName = $vars->name ?? $vars['name'];
$fieldType = $vars->type ?? $vars['type'];
});

EditCustomField​

Fires when a custom field is modified.

add_hook('EditCustomField', 1, function($vars) {
// $vars is the CustomField model
$fieldId = $vars->id;
});

DeleteCustomField​

Fires when a custom field is removed.

add_hook('DeleteCustomField', 1, function($vars) {
// $vars is the CustomField model
$fieldId = $vars->id;
$fieldName = $vars->name;
});

Segment Hooks​

Hooks for segment operations.

AddSegment​

Fires when a new segment is created.

add_hook('AddSegment', 1, function($vars) {
// $vars is the Segment model
$segmentId = $vars->id;
$segmentName = $vars->name;
$listId = $vars->list_id;
});

EditSegment​

Fires when a segment is modified.

add_hook('EditSegment', 1, function($vars) {
// $vars is the Segment model
$segmentId = $vars->id;
});

DeleteSegment​

Fires when a segment is deleted.

add_hook('DeleteSegment', 1, function($vars) {
// $vars is the Segment model
$segmentId = $vars->id;
});

RecountSegment​

Fires when a segment's contact count is recalculated.

add_hook('RecountSegment', 1, function($vars) {
// $vars contains segment data with updated counts
});

ExportSegment​

Fires when a segment is exported.

add_hook('ExportSegment', 1, function($vars) {
// $vars contains segment export data
});

Broadcast Campaign Hooks​

Hooks for broadcast email campaigns.

AddBroadcast​

Fires when a new broadcast campaign is created.

add_hook('AddBroadcast', 1, function($vars) {
// $vars is the Campaign model
$campaignId = $vars->id;
$campaignName = $vars->name;
$userId = $vars->user_id;
});

EditBroadcast​

Fires when a broadcast campaign is modified.

add_hook('EditBroadcast', 1, function($vars) {
// $vars is the Campaign model
$campaignId = $vars->id;
});

DeleteBroadcast​

Fires when a broadcast campaign is deleted.

add_hook('DeleteBroadcast', 1, function($vars) {
// $vars is the Campaign model
$campaignId = $vars->id;
});

ScheduleBroadcast​

Fires when a broadcast is scheduled for future delivery.

add_hook('ScheduleBroadcast', 1, function($vars) {
// $vars contains campaign schedule data
$campaignId = $vars['campaign_id'] ?? $vars->campaign_id;
$scheduledAt = $vars['scheduled_at'] ?? $vars->scheduled_at;
});

RescheduleBroadcast​

Fires when a scheduled broadcast's time is changed.

add_hook('RescheduleBroadcast', 1, function($vars) {
// $vars contains old and new schedule information
});

StartBroadcast​

Fires when a broadcast campaign begins sending.

add_hook('StartBroadcast', 1, function($vars) {
// $vars is the CampaignSchedule model
$scheduleId = $vars->id;
$campaignId = $vars->campaign_id;
$totalRecipients = $vars->total_subscribers;
});

PauseBroadcast​

Fires when a broadcast is manually paused.

add_hook('PauseBroadcast', 1, function($vars) {
// $vars contains campaign data array
$campaignId = $vars['campaign_id'];
$scheduleId = $vars['schedule_id'];
});

ResumeBroadcast​

Fires when a paused broadcast is resumed.

add_hook('ResumeBroadcast', 1, function($vars) {
// $vars contains campaign data
$campaignId = $vars['campaign_id'];
});

SystemPauseBroadcast​

Fires when the system automatically pauses a broadcast (e.g., due to high bounce rate).

add_hook('SystemPauseBroadcast', 1, function($vars) {
// $vars contains campaign data with pause reason
$campaignId = $vars['campaign_id'];
$reason = $vars['reason'] ?? 'system_pause';
});

CompleteBroadcast​

Fires when a broadcast campaign finishes sending.

add_hook('CompleteBroadcast', 1, function($vars) {
// $vars contains schedule hook data
$scheduleId = $vars['schedule_id'];
$campaignId = $vars['campaign_id'];
$totalSent = $vars['total_sent'];
});

DeleteScheduledBroadcast​

Fires when a scheduled broadcast is cancelled/deleted.

add_hook('DeleteScheduledBroadcast', 1, function($vars) {
// $vars is the CampaignSchedule model
$scheduleId = $vars->id;
$campaignId = $vars->campaign_id;
});

PrepareCampaign​

Fires when a campaign is being prepared for sending.

add_hook('PrepareCampaign', 1, function($vars) {
// $vars contains preparation data
});

Drip Campaign Hooks​

Hooks for drip (autoresponder) campaigns.

AddDrip​

Fires when a new drip campaign is created.

add_hook('AddDrip', 1, function($vars) {
// $vars is the Autoresponder model
$dripId = $vars->id;
$dripName = $vars->name;
});

EditDrip​

Fires when a drip campaign is modified.

add_hook('EditDrip', 1, function($vars) {
// $vars is the Autoresponder model
$dripId = $vars->id;
});

DeleteDrip​

Fires when a drip campaign is deleted.

add_hook('DeleteDrip', 1, function($vars) {
// $vars is the Drip model/data
$dripId = $vars->id ?? $vars['id'];
});

AddDripGroup​

Fires when a new drip group is created.

add_hook('AddDripGroup', 1, function($vars) {
// $vars is the Autoresponder model
$groupId = $vars->id;
});

EditDripGroup​

Fires when a drip group is modified.

add_hook('EditDripGroup', 1, function($vars) {
// $vars is the Group model
$groupId = $vars->id;
});

DeleteDripGroup​

Fires when a drip group is deleted.

add_hook('DeleteDripGroup', 1, function($vars) {
// $vars is the Group model/data
});

StartDripGroup​

Fires when a contact enters a drip campaign.

add_hook('StartDripGroup', 1, function($vars) {
// $vars contains drip and subscriber data
});

StopDripGroup​

Fires when a contact exits a drip campaign.

add_hook('StopDripGroup', 1, function($vars) {
// $vars contains drip and subscriber data
});

Trigger Hooks​

Hooks for automation triggers.

AddTrigger​

Fires when a new trigger is created.

add_hook('AddTrigger', 1, function($vars) {
// $vars is the Trigger model
$triggerId = $vars->id;
$triggerName = $vars->name;
$listId = $vars->list_id;
});

EditTrigger​

Fires when a trigger is modified.

add_hook('EditTrigger', 1, function($vars) {
// $vars is the updated Trigger model
$triggerId = $vars->id;
});

DeleteTrigger​

Fires when a trigger is deleted.

add_hook('DeleteTrigger', 1, function($vars) {
// $vars is the Trigger model
$triggerId = $vars->id;
});

ResortTriggers​

Fires when trigger execution order is changed.

add_hook('ResortTriggers', 1, function($vars) {
// $vars is an array of trigger IDs in new order
$triggerIds = $vars;
});

Split Test Hooks​

Hooks for A/B split test campaigns.

AddSplitTest​

Fires when a new split test is created.

add_hook('AddSplitTest', 1, function($vars) {
// $vars is the SplitTest model
$splitTestId = $vars->id;
});

EditSplitTest​

Fires when a split test is modified.

add_hook('EditSplitTest', 1, function($vars) {
// $vars is the SplitTest data
});

DeleteSplitTest​

Fires when a split test is deleted.

add_hook('DeleteSplitTest', 1, function($vars) {
// $vars is the SplitTest model
});

Content Tag Hooks​

AddSpinTag​

Fires when a spin tag is created.

add_hook('AddSpinTag', 1, function($vars) {
// $vars is the SpinTag model
$spinTagId = $vars->id;
$tagName = $vars->name;
});

EditSpingTag​

Fires when a spin tag is edited.

note

The hook name has a typo ("Sping" instead of "Spin"). Use EditSpingTag exactly as shown.

add_hook('EditSpingTag', 1, function($vars) {
// $vars is the SpinTag model
});

DeleteSpinTag​

Fires when a spin tag is deleted.

add_hook('DeleteSpinTag', 1, function($vars) {
// $vars is the SpinTag model
});

AddDynamicContentTag​

Fires when a dynamic content tag is created.

add_hook('AddDynamicContentTag', 1, function($vars) {
// $vars is the DynamicContentTag model
});

EditDynamicContentTag​

Fires when a dynamic content tag is edited.

add_hook('EditDynamicContentTag', 1, function($vars) {
// $vars is the DynamicContentTag model
});

DeleteDynamicContentTag​

Fires when a dynamic content tag is deleted.

add_hook('DeleteDynamicContentTag', 1, function($vars) {
// $vars is the DynamicContentTag model
});

Bounce Handling Hooks​

AddBounceAddress​

Fires when a bounce handling email address is added.

add_hook('AddBounceAddress', 1, function($vars) {
// $vars is the Bounce model
$bounceId = $vars->id;
$email = $vars->email;
});

EditBounceAddress​

Fires when a bounce address is edited.

add_hook('EditBounceAddress', 1, function($vars) {
// $vars is the Bounce data
});

DeleteBounceAddress​

Fires when a bounce address is deleted.

add_hook('DeleteBounceAddress', 1, function($vars) {
// $vars is the Bounce model
});

AddBounceRule​

Fires when a bounce rule is created.

add_hook('AddBounceRule', 1, function($vars) {
// $vars is the BounceReason model
$ruleId = $vars->id;
$pattern = $vars->pattern;
});

EditBounceRule​

Fires when a bounce rule is edited.

add_hook('EditBounceRule', 1, function($vars) {
// $vars is the BounceReason model
});

DeleteBounceRule​

Fires when a bounce rule is deleted.

add_hook('DeleteBounceRule', 1, function($vars) {
// $vars is the BounceReason model
});

ResortBounceRule​

Fires when bounce rule order is changed.

add_hook('ResortBounceRule', 1, function($vars) {
// $vars is an array of rule IDs
$ruleIds = $vars;
});

Sending Domain Hooks​

AddSendingDomain​

Fires when a new sending domain is added.

add_hook('AddSendingDomain', 1, function($vars) {
// $vars is the Domain model
$domainId = $vars->id;
$domainName = $vars->domain;
});

DeleteSendingDomain​

Fires when a sending domain is removed.

add_hook('DeleteSendingDomain', 1, function($vars) {
// $vars is the Domain model
});

SendingDomainVerified​

Fires when a sending domain passes all verification.

add_hook('SendingDomainVerified', 1, function($vars) {
// $vars contains domain verification data
});

DNS Verification Hooks​

// SPF record verified
add_hook('SendingDomainSpfPassed', 1, function($vars) {
// $vars is the domain data
});

// MX record verified
add_hook('SendingDomainMXPassed', 1, function($vars) {
// $vars is the domain data
});

// DKIM record verified
add_hook('SendingDomainDKIMPassed', 1, function($vars) {
// $vars is the domain data
});

// DKIM generated
add_hook('SendingDomainDKIMGenerted', 1, function($vars) {
// $vars is the domain detail
// Note: Hook name has typo "Generted"
});

// Tracking domain verified
add_hook('SendingDomainTrackingPassed', 1, function($vars) {
// $vars is the domain data
});

// DNS verification failed
add_hook('SendingDomainDnsFailed', 1, function($vars) {
// $vars is the domain data with error info
});

Domain Status Hooks​

// Domain signing enabled
add_hook('SendingDomainSignOn', 1, function($vars) {
// $vars is the DomainMasking model
});

// Domain signing disabled
add_hook('SendingDomainSignOff', 1, function($vars) {
// $vars is the DomainMasking model
});

// Domain suspended
add_hook('SendingDomainSuspend', 1, function($vars) {
// $vars is the Domain model
});

// Domain unsuspended
add_hook('SendingDomainUnSuspend', 1, function($vars) {
// $vars is the Domain model
});

// Bounce handling enabled
add_hook('SendingDomainBounceOn', 1, function($vars) {
// $vars is the Domain model
});

// Bounce handling disabled
add_hook('SendingDomainBounceOff', 1, function($vars) {
// $vars is the Domain model
});

// Domain status changed
add_hook('changeDomainStatus', 1, function($vars) {
// $vars contains domain status change data
});

Sending Node / SMTP Hooks​

AddSendingNode​

Fires when a new sending node is added.

add_hook('AddSendingNode', 1, function($vars) {
// $vars is the SMTP model
$nodeId = $vars->id;
$host = $vars->host;
});

EditSendingNode​

Fires when a sending node is edited.

add_hook('EditSendingNode', 1, function($vars) {
// $vars is the SMTP model
});

DeleteSendingNode​

Fires when a sending node is deleted.

add_hook('DeleteSendingNode', 1, function($vars) {
// $vars is the SMTP model
});

addSMTP​

Fires when SMTP configuration is added.

add_hook('addSMTP', 1, function($vars) {
// $vars contains SMTP configuration data
});

delSMTP​

Fires when SMTP configuration is deleted.

add_hook('delSMTP', 1, function($vars) {
// $vars contains SMTP data
});

AutomationSmtpResumed​

Fires when an SMTP is automatically resumed after being paused.

add_hook('AutomationSmtpResumed', 1, function($vars) {
// $vars contains SMTP resume data
});

Web Form Hooks​

AddWebForm​

Fires when a new web form is created.

add_hook('AddWebForm', 1, function($vars) {
// $vars is the WebForm model
$formId = $vars->id;
$formName = $vars->name;
$listId = $vars->list_id;
});

EditWebForm​

Fires when a web form is edited.

add_hook('EditWebForm', 1, function($vars) {
// $vars is the WebForm model
});

DeleteWebForm​

Fires when a web form is deleted.

add_hook('DeleteWebForm', 1, function($vars) {
// $vars is the WebForm model
});

Feedback Loop Hooks​

AddFeebackLoop​

Fires when a feedback loop is configured.

note

The hook name has a typo ("Feeback" instead of "Feedback"). Use AddFeebackLoop exactly as shown.

add_hook('AddFeebackLoop', 1, function($vars) {
// $vars contains feedback loop configuration
});

EditFeebackLoop​

Fires when a feedback loop is edited.

add_hook('EditFeebackLoop', 1, function($vars) {
// $vars contains updated configuration
});

DeleteFeebackLoop​

Fires when a feedback loop is deleted.

add_hook('DeleteFeebackLoop', 1, function($vars) {
// $vars contains feedback loop data
});

Email Processing Hooks​

EmailSentPostProcess​

Fires after an email is successfully sent.

add_hook('EmailSentPostProcess', 1, function($vars) {
// $vars is the campaign log ID (integer)
$logId = $vars;
});

EmailDeliveredPostProcess​

Fires when delivery confirmation is received.

add_hook('EmailDeliveredPostProcess', 1, function($vars) {
// $vars is the campaign log ID or delivery data
$logId = $vars;
});

EmailOpenedPostProcess​

Fires when an email open is tracked.

add_hook('EmailOpenedPostProcess', 1, function($vars) {
// $vars is the EmailOpened model
});

EmailClickedPostProcess​

Fires when an email link click is tracked.

add_hook('EmailClickedPostProcess', 1, function($vars) {
// $vars is the EmailClicked model
});

EmailBouncedPostProcess​

Fires when a bounce is processed.

add_hook('EmailBouncedPostProcess', 1, function($vars) {
// $vars is the EmailBounced model
});

EmailOpened​

Fires when an email is opened.

add_hook('EmailOpened', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact who opened
// - schedule_id: Campaign schedule ID
// - broadcast_id: Campaign ID

$subscriberId = $vars['subscriber_id'];
$scheduleId = $vars['schedule_id'];
});

LinkClicked​

Fires when a link is clicked in an email.

add_hook('LinkClicked', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact who clicked
// - list_id: Contact list ID
// - schedule_id: Campaign schedule ID
// - broadcast_id: Campaign ID
// - url: The clicked URL

$url = $vars['url'];
$subscriberId = $vars['subscriber_id'];
});

AutomationOpenEmail​

Fires for automation tracking when an email is opened.

add_hook('AutomationOpenEmail', 1, function($vars) {
// $vars contains open tracking data
});

Fires for automation tracking when a link is clicked.

add_hook('AutomationClickLink', 1, function($vars) {
// $vars contains click tracking data
});

Timeline Hooks​

Hooks for timeline event tracking.

TimelineSentBroadcast​

Fires for timeline when a broadcast email is sent.

add_hook('TimelineSentBroadcast', 1, function($vars) {
// $vars contains:
// - subscriber_id: Recipient contact ID
// - schedule_id: Campaign schedule ID
// - subject_line: Email subject

$subscriberId = $vars['subscriber_id'];
$subjectLine = $vars['subject_line'];
});

TimelineSentDrip​

Fires for timeline when a drip email is sent.

add_hook('TimelineSentDrip', 1, function($vars) {
// $vars contains:
// - subscriber_id: Recipient contact ID
// - schedule_id: Campaign schedule ID
// - broadcast_id: Drip campaign ID
});

TimelineSentTrigger​

Fires for timeline when a trigger email is sent.

add_hook('TimelineSentTrigger', 1, function($vars) {
// $vars contains:
// - subscriber_id: Recipient contact ID
// - schedule_id: Campaign schedule ID
});

TimelineBounceEmail​

Fires for timeline when an email bounces.

add_hook('TimelineBounceEmail', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact ID
// - schedule_id: Campaign schedule ID
// - broadcast_id: Campaign ID
});

TimelineSpamEmail​

Fires for timeline when a spam complaint is received.

add_hook('TimelineSpamEmail', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact ID
// - schedule_id: Campaign schedule ID
// - broadcast_id: Campaign ID
});

TimelineUnsubEmail​

Fires for timeline when a contact unsubscribes.

add_hook('TimelineUnsubEmail', 1, function($vars) {
// $vars contains:
// - subscriber_id: Contact ID
// - list_id: List ID
// - schedule_id: Campaign schedule ID
// - broadcast_id: Campaign ID
});

TimelineSettings​

Fires when timeline settings are changed.

add_hook('TimelineSettings', 1, function($vars) {
// $vars contains:
// - timeline_files_path: Path setting
// - timeline_path: Path setting
// - timeline_status: Status setting
// - timeline_value: Event queue value
});

User Management Hooks​

DeleteUser​

Fires when a user account is deleted.

add_hook('DeleteUser', 1, function($vars) {
// $vars is the User model
$userId = $vars->id;
$username = $vars->username;
$email = $vars->email;
});

SuspendUser​

Fires when a user account is suspended.

add_hook('SuspendUser', 1, function($vars) {
// $vars contains user suspension data
});

UnsuspendUser​

Fires when a user account is reactivated.

add_hook('UnsuspendUser', 1, function($vars) {
// $vars contains user data
});

AutomationAddUser​

Fires when a user is added through automation.

add_hook('AutomationAddUser', 1, function($vars) {
// $vars contains:
// - user_id: New user ID
});

Package Hooks​

AutomationAddPackage​

Fires when a package is added through automation.

add_hook('AutomationAddPackage', 1, function($vars) {
// $vars contains:
// - package_id: Package ID
// - automation_limit: Automation limit
// - action_limit: Action limit
// - automation_actions_limit: Actions limit
});

AutomationUpdatePackage​

Fires when a package is updated through automation.

add_hook('AutomationUpdatePackage', 1, function($vars) {
// $vars contains same structure as AddPackage
});

System Hooks​

AfterCron​

Fires after the main cron job completes.

add_hook('AfterCron', 1, function($vars) {
// $vars is empty string ''
// Use for post-cron cleanup or tasks
});

AfterMaintenanceCron​

Fires after the maintenance cron job completes.

add_hook('AfterMaintenanceCron', 1, function($vars) {
// $vars is empty array []
});

CreateNotification​

Fires when a system notification is created.

add_hook('CreateNotification', 1, function($vars) {
// $vars contains notification data ($hdata)
$title = $vars['title'] ?? '';
$message = $vars['message'] ?? '';
$userId = $vars['user_id'] ?? '';
});

taskComplete​

Fires when a background task completes.

add_hook('taskComplete', 1, function($vars) {
// $vars contains:
// - msg: Completion message

$message = $vars['msg'];
});

UpdateVersion​

Fires when the application version is updated.

add_hook('UpdateVersion', 1, function($vars) {
// $vars contains version info
});

AutomationSettings​

Fires when automation settings are changed.

add_hook('AutomationSettings', 1, function($vars) {
// $vars contains settings data
});

updateUserTransactionFile​

Fires when user transaction file needs updating.

add_hook('updateUserTransactionFile', 1, function($vars) {
// $vars is the user ID
$userId = $vars;
});

Plan & Usage Page Hooks​

The user-facing Plan & Usage page (/plan) uses three filter-style hooks to let addons contribute tabs and sections. Unlike action hooks, listeners return a value that is collected (via hook_get_all) and merged into the rendered page.

The page is assembled by App\Classes\PlanRegistry::build($user), which:

  1. Registers its core tabs + sections
  2. Fires plan_tabs, plan_sections, plan_hide and merges the results
  3. Evaluates visible / available closures on each entry
  4. Sorts by order and renders

For a full walkthrough see the Plan & Usage page extension examples.

plan_tabs​

Fires while assembling the tab list for the Plan & Usage page. Return an array of tab descriptors to add.

add_hook('plan_tabs', 1, function ($args) {
// $args['user'] — the User model the page is being rendered for
return [
[
'id' => 'automations', // unique tab id
'label' => 'Automations', // nav label
'icon' => 'fa fa-retweet', // icon class (FA or LA)
'order' => 55, // sort order
'view' => 'automations::plan.tab', // blade view rendered
'visible' => fn($user) => true, // bool | closure — hide entirely
'available' => fn($user) => true, // bool | closure — locked/CTA state
'locked_message' => 'Contact admin to enable.',
],
];
});

Descriptor keys

KeyTypePurpose
idstringStable identifier — also the URL segment at /plan/{id}
labelstringVisible label in the left rail
iconstringfa fa-* or la la-* class
orderintAscending sort (core uses 10/20/30/40/50/60)
viewstringBlade path (supports addon namespaces like automations::)
visiblebool | callableWhen false, the tab is not rendered at all
availablebool | callableWhen false, the tab renders a "locked / contact admin" state
locked_messagestringShown in the locked state

plan_sections​

Fires while assembling sections within the Infrastructure tab (and any other tab that exposes sections). Return a map keyed by tab id to an array of section descriptors.

add_hook('plan_sections', 1, function ($args) {
return [
'infrastructure' => [
[
'id' => 'dedicated_ips',
'label' => 'Dedicated IPs',
'icon' => 'la la-cubes',
'order' => 40,
'view' => 'dedicatedips::plan.sections.dedicated-ips',
'visible' => true,
'available' => true,
],
],
];
});

Section descriptors use the same keys as tab descriptors — they just render inside a tab's body instead of as standalone pages.

plan_hide​

Fires while assembling the page. Return a directive describing tabs or sections to remove from the final output — used by addons that want to replace a core entry (e.g. a dedicated-IP addon hides the SMTP Accounts section because sending runs through dedicated IPs instead).

add_hook('plan_hide', 1, function ($args) {
return [
'tabs' => ['some_tab_id'], // remove whole tab
'sections' => [
'infrastructure' => ['smtp_accounts'], // remove section within tab
],
];
});

Either key is optional.