---
title: "The Health facade — Alerts for Laravel | Roundly"
description: "The whole Health facade in one place: the check registry, the for($owner) handle, the silences() sub-accessor and the scheduler verbs."
url: https://roundly-consulting.com/open-source/docs/alerts-for-laravel/facade
language: en
---

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

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

# The Health facade

RoundlyConsulting\\Alerts\\Facades\\Health is the recommended entry point, and its Health alias is auto-discovered. Its surface has four parts: the check registry, a handle scoped to one owner, the maintenance-window sub-accessor and the verbs that span every owner:

```php
use RoundlyConsulting\Alerts\Checks\DatabaseCheck;
use RoundlyConsulting\Alerts\Facades\Health;

// The check registry
Health::check(DatabaseCheck::make('mysql'));
Health::checks([DiskUsageCheck::class, MemoryUsageCheck::class]);
Health::define('orders-flowing', fn () => Order::where('created_at', '>=', now()->subHour())->exists());
Health::all();                               // Collection<string, Check>
Health::find('disk_usage_check');            // ?Check

// Everything scoped to one owner
Health::for($team)->monitor(DatabaseCheck::class)->everyFiveMinutes()->save();
Health::for($team)->schedule($data);         // from a ScheduleHealthCheckData
Health::for($team)->reconfigure($row, $changes); // change a schedule in place
Health::for($team)->run(DatabaseCheck::class);
Health::for($team)->run('orders-flowing');   // by key, e.g. an inline check
Health::for($team)->report(['critical']);
Health::for($team)->status();
Health::for($team)->monitors();
Health::for($team)->unmonitor(DatabaseCheck::class);

// Maintenance windows
Health::silences()->mute('db', until: now()->addHour(), for: $team, reason: 'upgrade');
Health::silences()->unmute('db', for: $team);
Health::silences()->isMuted('db');
Health::silences()->active($team);
Health::silences()->snapshot();              // every silence in force, one query
Health::silences()->prune();                 // what alerts:prune-silences calls

// Across every owner
Health::report();
Health::report(since: now()->subDay(), scheduledOnly: true);
Health::status();
Health::runDue();                            // what alerts:perform-health-checks calls
Health::prune(14);                           // what alerts:prune-runs calls
Health::routes();                            // the opt-in JSON endpoint
```

## Flat methods

| Method | Returns | What it does |
| --- | --- | --- |
| `check(string\|object $check)` | HealthManager | Register one check class or instance. Anything that does not extend Check throws InvalidHealthCheck. |
| `checks(array $checks)` | HealthManager | Register several checks at once. |
| `define(string $key, Closure $callback)` | PendingCheck | Define an inline closure check (see Inline closure checks). |
| `all()` | Collection<string, Check> | Every registered check, keyed by its key. |
| `find(string $key)` | ?Check | One registered check, or null. |
| `for(Model $owner)` | NotifiableHealth | The handle scoped to one owner (next table). |
| `report(?array $tags = null, ?CarbonInterface $since = null, bool $scheduledOnly = false)` | HealthReport | Report across every monitored check — scheduled monitors and the on-demand rows run() creates — optionally filtered by tags. since: limits uptime and p95 to the runs since then; scheduledOnly: true leaves the on-demand rows out. Built in a fixed number of queries. |
| `status(?array $tags = null)` | Status | The overall() roll-up of that report. |
| `silences()` | Silences | The maintenance-window sub-accessor (table below). |
| `runDue()` | int | Queue the configured job for every scheduled check due since the previous call (or now, on a first call); returns how many were queued. |
| `prune(?int $days = null)` | int | Delete run history older than $days (default history.retention\_days); returns how many runs were deleted. Below 1 day throws InvalidRetention. |
| `routes(?string $uri = null)` | Route | Register the opt-in JSON status endpoint. |

## Health::for($owner)

Every health operation scoped to one owner model. The handle is a security boundary: a scheduled row that belongs to another owner is refused with InvalidHealthCheck.

| Method | Returns | What it does |
| --- | --- | --- |
| `run(string\|Check\|HealthCheck $check)` | CheckResult | Run now with the full alert, notify and history side effects. A registered key, class or instance runs through the owner’s scheduled row, else an on-demand row that is never scheduled; a row must belong to the owner, else InvalidHealthCheck. |
| `report(?array $tags = null, ?CarbonInterface $since = null, bool $scheduledOnly = false)` | HealthReport | This owner’s report, with the same tag, window and scheduled-only options. |
| `status(?array $tags = null)` | Status | This owner’s roll-up. |
| `monitor(string $check)` | PendingScheduledCheck | Fluent schedule for a Check class or registered key (an inline check’s key starts from its define() options); save() validates the cron and returns the HealthCheck row. |
| `schedule(ScheduleHealthCheckData $data)` | HealthCheck | Schedule from a DTO. For a check that declares uniqueBy(), an upsert on the schedule’s identity (see Scheduling identity & reconfigure). |
| `reconfigure(HealthCheck $row, ReconfigureHealthCheckData $changes)` | HealthCheck | Change one of this owner’s schedules in place: null settings stay, meta merges key by key. Another owner’s row throws InvalidHealthCheck; moving onto another live schedule’s identity throws ScheduleConflict. |
| `unmonitor(string\|Check\|HealthCheck $check)` | int | Soft-delete this owner’s rows for a check — scheduled and on-demand — or one own row, closing any alert still open on them; another owner’s row throws InvalidHealthCheck. |
| `monitors()` | Collection<int, HealthCheck> | This owner’s schedules, oldest first — on-demand rows are not listed. |

The UsesHealthChecks trait’s monitorCheck(), monitor() and createHealthCheck() are shortcuts over Health::for($this), so they behave exactly like the facade calls — and Health::fake() records them too (see Owner models).

## Health::silences()

Maintenance windows. A key is a check key, a tag or \* for everything; for: scopes a silence to one owner (see Maintenance windows & muting):

| Method | Returns | What it does |
| --- | --- | --- |
| `mute(string $key, ?CarbonInterface $until = null, ?Model $for = null, ?string $reason = null)` | AlertSilence | Mute a check key, a tag or \*, optionally until a moment and/or for one owner. Muting the same key and scope again updates that silence’s reason and end — extending or shortening it — and returns it. |
| `unmute(string $key, ?Model $for = null)` | int | Lift the global silences on the key, or only those scoped to $for; returns how many were lifted. |
| `isMuted(string $key, ?Model $for = null)` | bool | Whether a silence on exactly this key is in force now. Always false when silence is off in the config. |
| `active(?Model $for = null)` | Collection<int, AlertSilence> | Silences in force now: all of them, or the global ones plus those scoped to $for. |
| `snapshot(?CarbonInterface $at = null)` | SilenceSnapshot | Every silence in force at $at (default now), loaded in one query; ask it covers($row) or isEmpty(). Empty while silence is off. |
| `covers(HealthCheck $row)` | bool | Whether a silence in force now mutes the row, by the run pipeline’s own rule (one query). |
| `prune(?int $days = null)` | int | Delete silences that ended more than $days ago (default silence-retention); returns how many were deleted. Below 1 day throws InvalidRetention. |

## Builders

- Health::for($owner)->monitor($check) returns a PendingScheduledCheck — frequency presets, throttle, thresholds, tags, routing, escalation and meta, then save() (see Scheduling checks). For an inline check’s key it starts from the options declared on define().
- Health::define($key, $closure) returns a PendingCheck for an inline check’s name, notification and options (see Inline closure checks).

In tests, Health::fake() swaps the whole surface for a recording fake (see Testing). If you prefer an explicit dependency or single-purpose classes, see DI and actions.

## 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/alerts-for-laravel.md)
