---
title: "Events — Lifecycle for Laravel | Roundly"
description: "Every event, when it fires and its payload — listen for LifecycleTransitioned, not Eloquent’s updated, and keep side effects after commit."
url: https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/events
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Lifecycle for Laravel](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel.md)

# Events

| Event | When | Payload |
| --- | --- | --- |
| `LifecycleTransitioning` | Inside the transaction, before the write (a throwing listener aborts). | `subject, lifecycle, transition, from, to, actor, system` |
| `LifecycleTransitioned` | After commit, once per state change: kinds transition, expiry, scheduled, rollback, adopted. | `subject, subjectType, subjectId, lifecycle, kind, transition, from, to, actor, system, historyId, version` |
| `LifecycleTransitionDenied` | After the refused attempt rolled back (even when your own transaction then rolls back). | `subjectType, subjectId, lifecycle, transition, actor, denials` |
| `LifecycleExpired` | After commit, with the expiry’s LifecycleTransitioned. | `subject, lifecycle, from, to, historyId, expiresAt` |
| `LifecycleExpiring` | After commit, once per warning lead. | `subject, lifecycle, state, expiresAt, lead, scheduleId` |
| `LifecycleRolledBack` | After commit, once per rollback call. | `subject, lifecycle, from, to, revertedIds, rollbackIds, actor` |
| `LifecycleFrozen / LifecycleUnfrozen` | After commit. | `subject, lifecycle, until, reason, actor` |
| `LifecycleAdopted` | After commit. | `subject, lifecycle, recordedState, actualState, historyId` |
| `ScheduledTransitionFailed` | After commit. | `scheduleId, subjectType, subjectId, lifecycle, transition, denials, attempts, final` |

Listen for LifecycleTransitioned rather than Eloquent’s updated: the state write is a direct compare-and-swap, so model events do not fire for it. It covers every state change — transitions, expiries, scheduled runs, rollback steps and adoptions — but not creation, where your model’s created event and the initial history row are the signal:

```php
use Illuminate\Support\Facades\Event;
use RoundlyConsulting\Lifecycle\Enums\TransitionKind;
use RoundlyConsulting\Lifecycle\Events\LifecycleTransitioned;

Event::listen(function (LifecycleTransitioned $event): void {
    if ($event->subject instanceof Listing && $event->to === ListingStatus::Active) {
        SearchIndex::add($event->subject);
    }

    if ($event->kind === TransitionKind::Rollback) {
        AuditLog::record("Rolled back to {$event->to->value}", $event->historyId);
    }
});
```

- LifecycleTransitioning runs inside the transaction; a throwing listener aborts and rolls everything back, but denials belong in guards. A deadlock retry runs it again.
- LifecycleTransitionDenied is deliberately not after-commit — it fires even when your own outer transaction then rolls back because of the denial.
- After-commit events inside your own transaction are held until your outermost transaction commits, and discarded if it rolls back.
- Payloads never contain the transition payload. Read the history row (historyId) when you need the stored, validated context.
- Queued listeners should re-fetch the subject by subjectType / subjectId.
- Idempotent replays and Lifecycles::fake() fire nothing.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel.md)
