Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Api Health Laravel Package

pbmedia/laravel-api-health

pbmedia/laravel-api-health lets you monitor Laravel API endpoints with configurable health checks, scheduled runs, and notifications when an endpoint is down or unhealthy.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and publish

composer require pbmedia/laravel-api-health
php artisan vendor:publish --tag="api-health-config"

PHP 8.2 is supported as of 5.4.0. Laravel's package auto-discovery registers the service provider and the Health facade (Pbmedia\ApiHealth\Facades\Health). The published config/api-health.php is the first file to read — it controls notification routing, thresholds, and the cache/store used to remember previous check results.

2. Register your first check

Checks are declared in a service provider's boot() method (a dedicated HealthServiceProvider keeps things tidy):

use Pbmedia\ApiHealth\Facades\Health;
use Illuminate\Support\Facades\Http;

Health::check('stripe', function () {
    return Http::timeout(5)
        ->get('https://api.stripe.com/v1/charges')
        ->successful();
});

The closure (or invokable class) returns a truthy value for "healthy". Anything falsy — or an exception — marks the check as failed and triggers the configured notifier.

3. Schedule it

The package ships an artisan command that evaluates all registered checks. Wire it into the scheduler:

// app/Console/Kernel.php (Laravel ≤10) or routes/console.php (Laravel 11+)
$schedule->command('api-health:check')->everyFiveMinutes();

4. Verify

Run the command manually first (php artisan api-health:check -v) before trusting the scheduler. That single invocation tells you whether checks resolve, whether the notifier is configured, and whether anything is silently swallowing exceptions.

First realistic use case: you depend on a third-party API (Stripe, Mailgun, an internal microservice) and want a Slack ping when it degrades, rather than discovering it from a customer ticket.


Implementation Patterns

Inline closures for simple probes, classes for anything reused

A closure is fine for Http::get(...)->successful(). As soon as a check has non-trivial setup (auth tokens, payload validation, multi-step assertions), extract it into a dedicated class and register the class name. This keeps the service provider readable and makes the check unit-testable in isolation.

Assert on semantics, not just status codes

->successful() is a weak signal. Prefer checks that validate a meaningful contract:

Health::check('payments-api', function () {
    $response = Http::timeout(5)->get(config('services.payments.url') . '/ping');

    return $response->successful()
        && $response->json('status') === 'ok';
});

A 200 that returns a maintenance page or an error envelope is still an outage.

Group and route notifications per team/service

Register checks with names that map to ownership (billing:stripe, ops:redis) and route notifications to the channel that owns that dependency. A single firehose channel gets muted within a week; per-team channels survive.

Debounce to avoid alert storms

A flapping dependency can generate dozens of notifications an hour, and a scheduler running every minute amplifies it. Set a failure threshold in the config (or track consecutive failures yourself in cache) so a notification only fires after N consecutive failures, and send a single "recovered" message on the way back up.

Keep checks off the request path

Never call a check inside a controller or middleware. Checks do network I/O with timeouts; running them per-request will tank latency and multiply outbound traffic. The scheduler command is the only sane execution context.

Pair with an internal status endpoint

If you want a human-facing view, expose a route that reads the last known results rather than re-running checks:

Route::get('/internal/health', fn () => Health::results());

Protect it behind auth or an IP allowlist.

Test checks with Http::fake()

Because a check is just a closure returning a boolean, you can test it without booting the scheduler:

Http::fake(['api.stripe.com/*' => Http::response(['status' => 'ok'], 200)]);
$this->assertTrue((new StripeCheck)());

Fake the failure path too — an untested failure branch is a check you can't trust.

Integration with existing observability

If you already run Sentry/Horizon/Oh Dear, resist duplicating. Use this package for the narrow slice it does well (third-party dependency probes with notifications) and let your APM handle latency and error-rate metrics.


Gotchas and Tips

Maintenance status is the single biggest consideration. 5.4.0 adds PHP 8.2 support, but that is a runtime-compatibility patch, not a signal of active development: no Laravel-version work accompanies it, and the package has effectively sat still since 2022. Framework compatibility for Laravel 10/11+ is still unverified and, if broken, won't be fixed upstream. Before adopting:

composer require pbmedia/laravel-api-health --dry-run

Check whether its illuminate/* constraints resolve against your framework version. If they don't, you'll need --with-all-dependencies and possibly a replace/fork — at which point evaluate whether maintaining a fork is worth it versus spatie/laravel-health or Laravel's built-in health route. PHP 8.2 support means the PHP side of the install won't block you; the Laravel side still might.

Zero dependents on Packagist plus a single compatibility-only release is consistent with a dormant package, not a hidden gem. Budget for the possibility that you are the maintainer now.

Explicit HTTP timeouts are mandatory. Guzzle's default is effectively unbounded relative to a scheduler tick. A hung check blocks the whole run and every subsequent check in the queue. Always ->timeout(5)->connectTimeout(2).

Exceptions escape silently unless you catch them. A check that throws (DNS failure, SSL error, JSON parse error on a non-JSON body) is a failure, but how the package surfaces it depends on its internals — some versions log and continue, some abort the run. Wrap risky checks in try/catch and return false explicitly so behaviour is deterministic.

Cache driver matters. State tracking (previous status, consecutive failure counts) lives in the cache. If CACHE_DRIVER=array or your cache is flushed regularly, debounce logic and "recovered" notifications behave unpredictably. Use a persistent store (redis, database) in production.

Config caching will bite you. After editing config/api-health.php, run php artisan config:cache — or forget it and wonder why your notification routing change did nothing. Conversely, during debugging, php artisan config:clear.

Don't run checks with withoutOverlapping() omitted. If a check hangs, the next scheduled tick starts a second instance. Add ->withoutOverlapping() to the scheduler entry.

Notification failures are silent. If your Slack webhook is misconfigured, the check runs, fails, and nothing happens — the monitoring tool itself becomes a blind spot. Send a deliberate test notification on deploy and assert it arrives.

Extension points are its best feature. The closure/class-based check design means you can monitor literally anything: queue depth, disk space, a database replica lag figure — not just HTTP endpoints. If you keep the package, lean on this rather than its defaults.

Migration note. If you're evaluating alternatives: spatie/laravel-health is actively maintained, has a comparable check-based model, and supports current Laravel releases. Laravel 11's built-in health route (via php artisan about and the Health endpoint) covers basic liveness. Given the dormant upstream, plan for one of these as the eventual destination.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource