Blesta events explained, the WHMCS hooks equivalent

If you’ve used WHMCS, you know hooks: small pieces of code that run when something happens, like an invoice being paid. Blesta events do the same job. A plugin tells Blesta which events it cares about, and Blesta calls the plugin’s code each time one fires. This guide explains how Blesta events work, how they compare to WHMCS hooks, shows a working example from a real plugin and lists the events hosts use most.

How Blesta events reach your plugin: an action happens, the event fires, Blesta finds the plugin and runs its method

Blesta Events vs WHMCS Hooks

The idea is the same; the packaging is different. In WHMCS you drop a hook file into includes/hooks/ and it runs. With Blesta events, the handlers live inside a plugin. That’s a little more setup for a one-off tweak, but it means your code has an install button, can be disabled without deleting files, and survives Blesta updates because it lives in its own folder. If you’re coming from our WHMCS hooks guide, think of a small Blesta plugin as a hook file with a settings page.

Blesta events vs WHMCS hooks comparison table

How Blesta Events Work

  1. Your plugin’s main class has a getEvents() method that returns a list of event names and the method to call for each.
  2. When one of those events happens, Blesta loads your plugin and calls that method.
  3. Your method receives an event object with the details, such as the client ID or invoice ID, and does its work.

That’s the whole model. You don’t edit Blesta’s core files, and you don’t need to know where in Blesta’s code the event is triggered. You only need the event’s name and the parameters it passes, which Blesta’s documentation lists for each one.

Before and After Blesta Events

Most Blesta events come in pairs. A Before event runs before a change is saved, and an After event runs once it’s done. For example, Services.suspendBefore fires just before a service is suspended and Services.suspendAfter fires right after.

Blesta events Before and After example with Services.suspendBefore and Services.suspendAfter

For notifications and syncing, you almost always want the After version, because by then the change has really happened. Before handlers can return values that Blesta uses in the method that’s about to run, which is useful for adjusting data, but it’s easy to get wrong, so read the notes for that event first.

One more thing to watch: Blesta 4.3 renamed its events. Old names without Before or After, such as Services.suspend or Invoices.setClosed, are now deprecated and map to the After versions. Many older tutorials still use the old names, so if you copy code from one, update the event names as you go.

A Working Example

This plugin listens for a client being deleted and cleans up its own data for that client. It’s close to what our Caddie for Blesta plugin does so a deleted client’s monitors and short links don’t linger:

class MyPlgnPlugin extends Plugin
{
    public function getEvents()
    {
        return [
            [
                'event' => 'Clients.deleteAfter',
                'callback' => ['this', 'clientDeleted']
            ]
        ];
    }

    public function clientDeleted($event)
    {
        $params = $event->getParams();
        $client_id = (int) ($params['client_id'] ?? 0);

        // Remove this plugin's records for the deleted client
        Loader::loadModels($this, ['MyPlgn.MyPlgnData']);
        $this->MyPlgnData->deleteForClient($client_id);
    }
}

The 'this' in the callback means “the instance of this plugin that exists when the event fires”. Blesta’s plugin events documentation recommends using 'this' or a static method.

Blesta events are registered when the plugin is installed. If you add a new event in a later release, test the upgrade path on a copy that already has the old version installed, and make sure existing installs pick up the new event without needing a reinstall.

Blesta Events Hosts Use Most

Blesta’s event handler reference lists them all. These are the ones that come up again and again:

EventFires whenTypical use
Clients.createAfterA new client is createdAdd them to a mailing list or CRM
Clients.deleteAfterA client is deletedClean up your plugin’s data for them
Services.addAfterA service is addedAlert your team about a new order
Services.suspendAfterA service is suspendedPost to Slack, pause related tools
Services.unsuspendAfterA service is unsuspendedTurn those tools back on
Services.cancelAfterA service is canceledTrigger an exit survey
Invoices.addAfterAn invoice is createdSync to accounting software
Invoices.setClosedAfterAn invoice is closed (paid in full)Thank-you email, unlock a feature
Appcontroller.preActionBefore almost any page loadsCheck a condition, redirect
Appcontroller.structureThe page layout is builtAdd a chat widget or tracking script

Use Appcontroller.preAction sparingly. It runs on nearly every request, so anything slow there slows down all of Blesta.

Not sure what an event passes in? On your dev copy, write the parameters to a log file the first time the handler runs and read them there. Five minutes of logging beats an hour of guessing, and it shows you exactly which keys hold the client ID, service ID or invoice ID before you write any real logic. Remove the logging, or turn it down, before the plugin goes live.

Adding Code to Every Page

A common request is “add this script to every page”: a live chat widget, an analytics tag or a cookie banner. In WHMCS you might use a hook that outputs to the head or footer. With Blesta events, use Appcontroller.structure. Your handler returns markup under the keys head, body_start or body_end, and Blesta places it there in the page. Because it lives in a plugin rather than a theme file, the script stays put when you update Blesta or switch client themes.

Events or Cron Tasks?

Blesta events are for reacting right when something happens. If your code should run on a schedule, like checking websites every five minutes or sending a weekly report, use a plugin cron task instead. It runs through Blesta’s own cron job. Our Blesta plugin development guide covers both.

Many plugins use both together. An event handler records that something needs doing, and a cron task does the slow part a minute later. That keeps buttons fast for staff and clients while still getting the work done.

Ideas You Can Build in an Afternoon

Not sure where to start? These small projects each need only one or two handlers and make a real difference to a hosting business:

  • New order alerts: post to a Slack or Discord channel whenever a service is added, with the package name and client, so your team can welcome big customers personally.
  • Cancellation survey: when a service is canceled, send a short email asking why. The answers are some of the most useful feedback you’ll ever get.
  • Accounting sync: push new invoices and payments to your accounting software so you stop typing them in twice.
  • Mailing list signup: add new clients to your newsletter list, if they opted in on the order form.
  • Suspension notes: add a note to the client’s account when a service is suspended, so support staff see why at a glance.

Each of these is a good first project because it’s easy to test and nothing breaks if it fails, as long as you catch errors: the order, invoice or cancellation still goes through.

Tips for Reliable Event Handlers

  • Keep them fast. The person clicking the button waits for your handler to finish. Call slow external APIs with short timeouts, or queue the work for a cron task.
  • Don’t let errors stop Blesta. Catch exceptions inside your handler so a failed Slack post doesn’t break invoicing.
  • Check the company. On multi-company installs, make sure the event belongs to a company where your plugin is active.
  • Refetch on add events. Blesta’s docs note that some fields may be missing from the parameters on add events, so load the record fresh if you need every detail.
  • Log what you do. A one-line log entry per handler makes it far easier to answer “did that run?” later.

Testing Blesta Events

Test Blesta events on a dev copy, never on your live install. Create a test client, add a service, suspend it, unsuspend it, pay an invoice and delete the client, and check your handler did the right thing at each step. If nothing seems to happen, confirm the plugin is installed and enabled, check the event name for typos (names are case-sensitive), and look in the PHP error log for exceptions your handler threw.

Frequently Asked Questions

Does Blesta have hooks like WHMCS?

Yes, Blesta calls them events. They do the same job, but the handlers live inside a plugin instead of a standalone hooks file.

Can I change data in an event?

Some Blesta events let you change values, usually the Before ones. Check each event’s notes in the Blesta docs before relying on it.

Can I convert my WHMCS hooks to Blesta events?

Usually, yes. Find the matching Blesta event for each hook, move the logic into a small plugin, and swap WHMCS database calls for Blesta models. Our WHMCS to Blesta guide covers the rest of the move.

Do events run for actions taken by the cron job?

Yes. A suspension is the same action whether a staff member clicks the button or the nightly automation does it, so your handler runs either way. That’s useful, but it also means a slow handler can slow down the cron run on a busy day.

Can you write event handlers for us?

Yes. Tell us what should happen and when, and browse our Blesta plugins and guides.

Posted by in Blog on October 17, 2026 |
About Rob Keck
Rob Keck is the founder of K & K Web Services in Ladoga, Indiana. He earned a Bachelor's in IT in 1996 and has been building and hosting websites for Indiana businesses since 2005. He holds WordPress, cloud computing, DevOps and cybersecurity certifications.