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

Uptime Robot Api Laravel Package

montross50/uptime-robot-api

Laravel package that wraps the Uptime Robot monitoring API, giving your PHP application a simple way to query and manage uptime monitors. Install via Composer, add your API key, and start integrating uptime data into your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up

composer require montross50/uptime-robot-api

On Laravel 5.5+ the service provider and UptimeRobot facade are auto-discovered. On older apps (or if discovery is disabled) register manually in config/app.php:

'providers' => [
    Montross50\UptimeRobotApi\UptimeRobotApiServiceProvider::class,
],
'aliases' => [
    'UptimeRobot' => Montross50\UptimeRobotApi\Facades\UptimeRobot::class,
],

Publish the config and set your key:

php artisan vendor:publish --provider="Montross50\UptimeRobotApi\UptimeRobotApiServiceProvider"

Open config/uptimerobot.php to confirm the exact env variable name it reads (commonly UPTIMEROBOT_API_KEY) and add it to .env. Grab the key from UptimeRobot → My Settings → API Settings; note whether it is a main key (full read/write) or a read-only / monitor-specific key, since that determines which calls will work.

Where to look first

The README is thin, so treat src/ as the documentation:

  1. The service provider — shows what is bound in the container and whether the client is a singleton.
  2. The client class (whatever the facade resolves to) — this is the real API surface. Method names map loosely to UptimeRobot endpoints (getMonitors, newMonitor, editMonitor, deleteMonitor, pauseMonitor, resumeMonitor, getAlertContacts, etc.). Verify signatures here before writing code against them.
  3. config/uptimerobot.php — base URL, API key, and any timeout/HTTP options. Check the base URL: this package predates UptimeRobot's API v3, so it almost certainly targets the v2 endpoint path.

First use case

The quickest win is an Artisan command that dumps monitor state, so you can confirm auth and response shape before building anything:

// app/Console/Commands/UptimeSnapshot.php
public function handle()
{
    $response = \UptimeRobot::getMonitors();

    // v2 returns HTTP 200 even on failure — inspect the payload.
    if (($response['stat'] ?? null) !== 'ok') {
        $this->error('API error: '.json_encode($response['error'] ?? $response));
        return 1;
    }

    foreach ($response['monitors'] as $monitor) {
        $this->line(sprintf(
            '[%s] %s — %s',
            $monitor['id'],
            $monitor['friendly_name'],
            $monitor['status'] // 2 = up, 8/9 = down, 0 = paused
        ));
    }

    return 0;
}

If that runs, you have everything you need to build the real integration.

Implementation Patterns

Wrap it — don't call the facade everywhere. Put the package behind your own class/interface from day one. The package is unmaintained, and a one-file adapter means you can swap to Saloon, Http:: or a hand-rolled Guzzle wrapper later without touching call sites.

interface MonitoringService
{
    public function monitors(): array;
    public function createMonitor(array $attributes): int;
    public function pause(int $monitorId): void;
}

final class UptimeRobotMonitoringService implements MonitoringService
{
    public function __construct(private \UptimeRobot $client) {}

    public function monitors(): array
    {
        // normalize the v2 payload into your own DTO/array shape here
    }
}

Bind the interface in a service provider; that's also your test seam.

Auto-provision monitors from domain events. The highest-leverage pattern: when a tenant, site or service is created in your app, create the matching monitor and persist the returned ID.

// listener for ServiceCreated
$response = UptimeRobot::newMonitor([
    'friendly_name' => $service->name,
    'url'           => $service->health_url,
    'type'          => 1,   // HTTP(s)
    'interval'      => 300,
]);

$service->update(['uptimerobot_monitor_id' => $response['monitor']['id']]);

Do this in a queued listener — never inline in the HTTP request that creates the record. Guard against duplicates (idempotency key or a monitor_id null check) because retries are inevitable.

Maintenance windows around deploys. Pause/resume monitors from a scheduled command or from your deploy script (via an Artisan command the deploy calls):

Schedule::command('monitors:pause', ['--tag' => 'api'])->dailyAt('02:00');
Schedule::command('monitors:resume', ['--tag' => 'api'])->dailyAt('02:30');

Always pair a pause with a resume in a finally block or a scheduled sweep — a paused monitor that never resumes is silently useless.

Status dashboards: cache the fan-in. Don't hit UptimeRobot from a web request. A scheduled command polls every 60s, writes a normalized snapshot to cache (or a monitor_statuses table), and your controller/Livewire/Inertia view reads from there. This gives you history for free and keeps you inside rate limits.

Cache::put('uptime:snapshot', $normalized, now()->addMinutes(2));

Reconcile alert contacts declaratively. Keep contacts in a config array, then diff against getAlertContacts() and create/update the differences. Same pattern as provisioning — config as source of truth, package as the writer.

Testing. Two options: (a) bind a stub of your own MonitoringService interface — the clean route; (b) if you must test through the package, the transport is Guzzle, so register a MockHandler on the client's HTTP stack — inspect the client constructor to see whether a Guzzle client can be injected. Do not hit the live API in CI.

Gotchas and Tips

Treat the package as frozen. Last release was September 2020, with 2 stars and zero dependents — you are effectively the maintainer. Pin the version exactly, commit the lockfile, and read every line of the client before trusting it in production. Budget for the possibility of forking it into your monorepo.

Install friction is likely. A 2020 package will constrain PHP and Guzzle versions that may conflict with a modern Laravel. If composer require fails, --ignore-platform-reqs is a warning sign, not a fix — a fork with relaxed constraints is usually cleaner than fighting the resolver.

API version risk is the big one. The package targets UptimeRobot API v2. UptimeRobot has since introduced v3; if v2 endpoints are retired or changed, this package breaks with no upstream fix. Confirm the base URL in config, and keep your adapter thin so the migration is a single-file change.

HTTP 200 does not mean success. UptimeRobot returns {"stat":"fail","error":{...}} with a 200 status. The package likely surfaces the raw decoded body rather than throwing, so every call needs a stat === 'ok' check. Centralize that in your adapter; do not scatter it.

Pagination and default limits. getMonitors caps results per call (v2 defaults to 50, offset/limit params). Loop with offset until you've drained the set, or accounts with many monitors will silently appear complete when they aren't.

Timeouts and logging. The client may not set a Guzzle timeout — add one (via config if exposed, otherwise in your fork) or a slow UptimeRobot response becomes a hung worker. Likewise, add a logging middleware around the Guzzle handler; the package probably logs nothing, and you'll want request/response traces the first time a monitor fails to create.

Status codes are magic numbers. 0 paused, 2 up, 8 seems down, 9 down — the package won't give you enums or constants. Define them yourself once and map to your domain vocabulary.

Extension points are limited but real. The provider binds the client in the container, so you can $this->app->bind() your own subclass or decorator, and the facade resolves through the container. That's your hook for caching, retries, and logging without editing vendor code. For multi-account setups (multiple API keys), a singleton binding won't work — instantiate the client class directly with a per-account key, or fork to accept a key parameter.

Honest verdict. The package saves you maybe 100–200 lines of Guzzle boilerplate over a small, well-documented REST API. Given zero dependents, a 2020 release, and API-version drift, a thin Http::withHeaders(...)->baseUrl(...) wrapper of your own is comparable work, fully typed, testable with Http::fake(), and won't strand you. Adopt this package only if you've read the client and confirmed it talks to a live endpoint — otherwise, wrap the API yourself.

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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core