openstatus/sdk-php

Official PHP SDK for Openstatus

Maintainers

Package info

github.com/openstatusHQ/sdk-php

pkg:composer/openstatus/sdk-php

Fund package maintenance!

openstatusHQ

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-05-28 20:28 UTC

This package is not auto-updated.

Last update: 2026-05-29 18:54:39 UTC


README

License: MIT PHP 8.4+

Official PHP SDK for Openstatus — the open-source status page with uptime monitoring.

Table of Contents

Features

Monitoring

  • HTTP Monitoring — monitor websites and APIs with customizable assertions.
  • TCP Monitoring — check database connections and other TCP services.
  • DNS Monitoring — verify DNS records and resolution.
  • Global Regions — monitor from 28 locations worldwide.

Status Page

  • Status Pages — create and manage public status pages with custom domains.
  • Page Components — add monitor-based or static components with grouping.
  • Subscribers — manage email subscriptions for status updates.
  • Status Reports — manage incident reports with update timelines.
  • Maintenance Windows — schedule and manage planned maintenance periods.

Notifications

  • 12 providers — Slack, Discord, Email, PagerDuty, Opsgenie, Telegram, and more.
  • Webhook Support — custom webhooks with headers for any integration.
  • Monitor Alerts — get notified when monitors go down or recover.

Developer Experience

  • Type-safe — strongly-typed request/response messages generated from Openstatus protobuf schemas (buf.build/openstatus/api).
  • PSR-18 transport — bring your own HTTP client, or use the bundled Guzzle implementation.
  • No proto toolchain needed — pre-generated PHP classes ship with the package; composer require is all you need.

Installation

Requires PHP 8.4 or later.

composer require openstatus/sdk-php

Quick Start

<?php

require __DIR__ . '/vendor/autoload.php';

use Openstatus\Monitor\V1\CreateHTTPMonitorRequest;
use Openstatus\Monitor\V1\HTTPMethod;
use Openstatus\Monitor\V1\HTTPMonitor;
use Openstatus\Monitor\V1\ListMonitorsRequest;
use Openstatus\Monitor\V1\NumberComparator;
use Openstatus\Monitor\V1\Periodicity;
use Openstatus\Monitor\V1\Region;
use Openstatus\Monitor\V1\StatusCodeAssertion;
use Openstatus\Sdk\ClientOptions;
use Openstatus\Sdk\OpenstatusClient;

$client = new OpenstatusClient(new ClientOptions(
    apiKey: getenv('OPENSTATUS_API_KEY') ?: null,
));

// Create a monitor
$response = $client->monitor->v1->monitorService->createHTTPMonitor(
    new CreateHTTPMonitorRequest([
        'monitor' => new HTTPMonitor([
            'name' => 'My API',
            'url' => 'https://api.example.com/health',
            'periodicity' => Periodicity::PERIODICITY_1M,
            'method' => HTTPMethod::HTTP_METHOD_GET,
            'regions' => [
                Region::REGION_FLY_AMS,
                Region::REGION_FLY_IAD,
                Region::REGION_FLY_SYD,
            ],
            'active' => true,
            'status_code_assertions' => [
                new StatusCodeAssertion([
                    'comparator' => NumberComparator::NUMBER_COMPARATOR_EQUAL,
                    'target' => 200,
                ]),
            ],
        ]),
    ]),
);

$monitor = $response->getMonitor();
printf("Monitor created: %s\n", $monitor?->getId() ?? 'unknown');

// List all monitors
$list = $client->monitor->v1->monitorService->listMonitors(new ListMonitorsRequest());
printf("Found %d monitors\n", $list->getTotalSize());

Authentication

All API requests require an API key. Get yours from the Openstatus dashboard.

Recommended: configure the client once

use Openstatus\Sdk\ClientOptions;
use Openstatus\Sdk\OpenstatusClient;

$client = new OpenstatusClient(new ClientOptions(
    apiKey: getenv('OPENSTATUS_API_KEY') ?: null,
));

// No need to pass headers on each call.
$client->monitor->v1->monitorService->listMonitors(new ListMonitorsRequest());

Alternative: per-call headers

Every service method accepts an optional second argument: an array of headers merged into the request. Useful for tracing IDs or one-off overrides.

$client->monitor->v1->monitorService->listMonitors(
    new ListMonitorsRequest(),
    ['x-trace-id' => 'trace-abc'],
);

Environment Variables

Variable Description Default
OPENSTATUS_API_KEY Your Openstatus API key Required for authenticated calls
OPENSTATUS_API_URL Custom API endpoint https://api.openstatus.dev

If apiKey is not passed in ClientOptions, the SDK falls back to OPENSTATUS_API_KEY. Same for baseUrl / OPENSTATUS_API_URL.

SDK Reference

All examples below assume:

$client = new OpenstatusClient(new ClientOptions(
    apiKey: getenv('OPENSTATUS_API_KEY') ?: null,
));
$service = $client->monitor->v1->monitorService;

Monitor Service

Manage HTTP, TCP, and DNS monitors.

createHTTPMonitor(request)

Create an HTTP/HTTPS monitor.

use Openstatus\Monitor\V1\CreateHTTPMonitorRequest;
use Openstatus\Monitor\V1\HTTPMethod;
use Openstatus\Monitor\V1\HTTPMonitor;
use Openstatus\Monitor\V1\Periodicity;
use Openstatus\Monitor\V1\Region;

$response = $service->createHTTPMonitor(new CreateHTTPMonitorRequest([
    'monitor' => new HTTPMonitor([
        'name' => 'My Website',
        'url' => 'https://example.com',
        'periodicity' => Periodicity::PERIODICITY_1M,
        'method' => HTTPMethod::HTTP_METHOD_GET,
        'regions' => [Region::REGION_FLY_AMS, Region::REGION_FLY_IAD],
        'active' => true,
    ]),
]));

updateHTTPMonitor(request)

Update an existing HTTP monitor.

use Openstatus\Monitor\V1\UpdateHTTPMonitorRequest;

$service->updateHTTPMonitor(new UpdateHTTPMonitorRequest([
    'id' => 'mon_123',
    'monitor' => new HTTPMonitor([
        'name' => 'Renamed monitor',
        'url' => 'https://example.com',
        'periodicity' => Periodicity::PERIODICITY_5M,
        'active' => true,
    ]),
]));

createTCPMonitor(request) / updateTCPMonitor(request)

Monitor TCP services.

use Openstatus\Monitor\V1\CreateTCPMonitorRequest;
use Openstatus\Monitor\V1\TCPMonitor;

$service->createTCPMonitor(new CreateTCPMonitorRequest([
    'monitor' => new TCPMonitor([
        'name' => 'Postgres prod',
        'url' => 'db.example.com:5432',
        'periodicity' => Periodicity::PERIODICITY_1M,
        'regions' => [Region::REGION_FLY_AMS],
        'active' => true,
    ]),
]));

createDNSMonitor(request) / updateDNSMonitor(request)

Monitor DNS records.

use Openstatus\Monitor\V1\CreateDNSMonitorRequest;
use Openstatus\Monitor\V1\DNSMonitor;
use Openstatus\Monitor\V1\DNSRecordType;

$service->createDNSMonitor(new CreateDNSMonitorRequest([
    'monitor' => new DNSMonitor([
        'name' => 'apex A record',
        'url' => 'example.com',
        'record_type' => DNSRecordType::DNS_RECORD_TYPE_A,
        'periodicity' => Periodicity::PERIODICITY_5M,
        'regions' => [Region::REGION_FLY_IAD],
        'active' => true,
    ]),
]));

getMonitor(request)

Fetch a single monitor (returns a MonitorConfig discriminated by type).

use Openstatus\Monitor\V1\GetMonitorRequest;

$response = $service->getMonitor(new GetMonitorRequest(['id' => 'mon_123']));
$config = $response->getMonitor();
if ($config?->getHttp() !== null) {
    echo $config->getHttp()->getUrl();
}

listMonitors(request)

List all monitors in the workspace, grouped by type.

use Openstatus\Monitor\V1\ListMonitorsRequest;

$response = $service->listMonitors(new ListMonitorsRequest(['limit' => 100, 'offset' => 0]));
foreach ($response->getHttpMonitors() as $monitor) {
    echo $monitor->getName() . "\n";
}

triggerMonitor(request)

Manually run a monitor immediately. Rate-limited by the synthetic-checks quota.

use Openstatus\Monitor\V1\TriggerMonitorRequest;

$service->triggerMonitor(new TriggerMonitorRequest(['id' => 'mon_123']));

deleteMonitor(request)

use Openstatus\Monitor\V1\DeleteMonitorRequest;

$service->deleteMonitor(new DeleteMonitorRequest(['id' => 'mon_123']));

getMonitorStatus(request)

Per-region status snapshot.

use Openstatus\Monitor\V1\GetMonitorStatusRequest;
use Openstatus\Monitor\V1\MonitorStatus;
use Openstatus\Monitor\V1\Region;

$response = $service->getMonitorStatus(new GetMonitorStatusRequest(['id' => 'mon_123']));
foreach ($response->getRegions() as $region) {
    printf(
        "%s: %s\n",
        Region::name($region->getRegion()),
        MonitorStatus::name($region->getStatus()),
    );
}

getMonitorSummary(request)

Aggregated latency percentiles and request counts.

use Openstatus\Monitor\V1\GetMonitorSummaryRequest;
use Openstatus\Monitor\V1\TimeRange;

$summary = $service->getMonitorSummary(new GetMonitorSummaryRequest([
    'id' => 'mon_123',
    'time_range' => TimeRange::TIME_RANGE_7D,
]));
printf("p95: %dms\n", (int) $summary->getP95());

listMonitorHTTPResponseLogs(request)

Recent HTTP response log entries with pagination.

use Openstatus\Monitor\V1\ListMonitorHTTPResponseLogsRequest;

$response = $service->listMonitorHTTPResponseLogs(new ListMonitorHTTPResponseLogsRequest([
    'id' => 'mon_123',
    'limit' => 50,
]));
$pagination = $response->getPagination();
foreach ($response->getLogs() as $log) {
    printf("%dms %s\n", $log->getLatency(), $log->hasStatusCode() ? (string) $log->getStatusCode() : '');
}
if ($pagination?->getHasMore()) {
    // pass $pagination->getNextOffset() into the next request
}

getMonitorHTTPResponseLog(request)

Single log entry with full headers and body assertions.

use Openstatus\Monitor\V1\GetMonitorHTTPResponseLogRequest;

$response = $service->getMonitorHTTPResponseLog(new GetMonitorHTTPResponseLogRequest([
    'id' => 'mon_123',
    'log_id' => 'log_abc',
]));
$detail = $response->getLog();
if ($detail !== null) {
    foreach ($detail->getHeaders() as $key => $value) {
        printf("%s: %s\n", $key, $value);
    }
}

Health Service

check(request)

Returns the API's serving status. No authentication required — useful as a liveness check.

use Openstatus\Health\V1\CheckRequest;
use Openstatus\Health\V1\CheckResponse\ServingStatus;

$response = $client->health->v1->healthService->check(new CheckRequest());
echo ServingStatus::name($response->getStatus());

Status Report Service

Manage incident reports with a lifecycle: investigating → identified → monitoring → resolved.

createStatusReport(request)

use Openstatus\Status_report\V1\CreateStatusReportRequest;
use Openstatus\Status_report\V1\StatusReport;
use Openstatus\Status_report\V1\StatusReportStatus;

$service = $client->statusReport->v1->statusReportService;
$response = $service->createStatusReport(new CreateStatusReportRequest([
    'report' => new StatusReport([
        'title' => 'Elevated error rate',
        'status' => StatusReportStatus::STATUS_REPORT_STATUS_INVESTIGATING,
        'status_page_ids' => ['page_123'],
    ]),
]));

getStatusReport(request) / listStatusReports(request) / updateStatusReport(request) / deleteStatusReport(request)

use Openstatus\Status_report\V1\GetStatusReportRequest;
use Openstatus\Status_report\V1\ListStatusReportsRequest;
use Openstatus\Status_report\V1\UpdateStatusReportRequest;
use Openstatus\Status_report\V1\DeleteStatusReportRequest;

$service->getStatusReport(new GetStatusReportRequest(['id' => 'rep_123']));
$service->listStatusReports(new ListStatusReportsRequest());
$service->updateStatusReport(new UpdateStatusReportRequest(['id' => 'rep_123', 'report' => $updated]));
$service->deleteStatusReport(new DeleteStatusReportRequest(['id' => 'rep_123']));

addStatusReportUpdate(request)

use Openstatus\Status_report\V1\AddStatusReportUpdateRequest;
use Openstatus\Status_report\V1\StatusReportUpdate;

$service->addStatusReportUpdate(new AddStatusReportUpdateRequest([
    'report_id' => 'rep_123',
    'update' => new StatusReportUpdate([
        'status' => StatusReportStatus::STATUS_REPORT_STATUS_IDENTIFIED,
        'message' => 'Root cause identified, fix deploying.',
    ]),
]));

Status Page Service

Manage public status pages with components, component groups, and subscribers.

createStatusPage(request)

use Openstatus\Status_page\V1\CreateStatusPageRequest;
use Openstatus\Status_page\V1\PageTheme;
use Openstatus\Status_page\V1\StatusPage;

$service = $client->statusPage->v1->statusPageService;
$service->createStatusPage(new CreateStatusPageRequest([
    'page' => new StatusPage([
        'title' => 'Acme Status',
        'slug' => 'acme',
        'theme' => PageTheme::PAGE_THEME_LIGHT,
    ]),
]));

getStatusPage(request) / listStatusPages(request) / updateStatusPage(request) / deleteStatusPage(request)

$service->getStatusPage(new GetStatusPageRequest(['id' => 'page_123']));
$service->listStatusPages(new ListStatusPagesRequest());
$service->updateStatusPage(new UpdateStatusPageRequest(['id' => 'page_123', 'page' => $updatedPage]));
$service->deleteStatusPage(new DeleteStatusPageRequest(['id' => 'page_123']));

getStatusPageContent(request) / getOverallStatus(request)

$content = $service->getStatusPageContent(new GetStatusPageContentRequest(['slug' => 'acme']));
$status = $service->getOverallStatus(new GetOverallStatusRequest(['id' => 'page_123']));

Components

Add a monitor-backed component or a static component, update it, remove it.

use Openstatus\Status_page\V1\AddMonitorComponentRequest;
use Openstatus\Status_page\V1\AddStaticComponentRequest;
use Openstatus\Status_page\V1\RemoveComponentRequest;
use Openstatus\Status_page\V1\UpdateComponentRequest;

$service->addMonitorComponent(new AddMonitorComponentRequest([
    'page_id' => 'page_123',
    'monitor_id' => 'mon_456',
    'name' => 'API',
]));
$service->addStaticComponent(new AddStaticComponentRequest([
    'page_id' => 'page_123',
    'name' => 'Marketing site',
]));
$service->updateComponent(new UpdateComponentRequest(['id' => 'comp_1', 'name' => 'Renamed']));
$service->removeComponent(new RemoveComponentRequest(['id' => 'comp_1']));

Component groups

use Openstatus\Status_page\V1\CreateComponentGroupRequest;
use Openstatus\Status_page\V1\DeleteComponentGroupRequest;
use Openstatus\Status_page\V1\UpdateComponentGroupRequest;

$service->createComponentGroup(new CreateComponentGroupRequest(['page_id' => 'page_123', 'name' => 'Edge']));
$service->updateComponentGroup(new UpdateComponentGroupRequest(['id' => 'grp_1', 'name' => 'Edge servers']));
$service->deleteComponentGroup(new DeleteComponentGroupRequest(['id' => 'grp_1']));

Subscribers

use Openstatus\Status_page\V1\CreatePageSubscriptionRequest;
use Openstatus\Status_page\V1\ListSubscribersRequest;
use Openstatus\Status_page\V1\SubscribeToPageRequest;
use Openstatus\Status_page\V1\UnsubscribeFromPageRequest;

$service->subscribeToPage(new SubscribeToPageRequest(['page_id' => 'page_123', 'email' => 'user@example.com']));
$service->createPageSubscription(new CreatePageSubscriptionRequest(['page_id' => 'page_123', 'email' => 'admin@example.com']));
$service->listSubscribers(new ListSubscribersRequest(['page_id' => 'page_123']));
$service->unsubscribeFromPage(new UnsubscribeFromPageRequest(['token' => 'unsub_token']));

Maintenance Service

Schedule planned maintenance windows. Subscribers can be notified automatically.

use Openstatus\Maintenance\V1\CreateMaintenanceRequest;
use Openstatus\Maintenance\V1\DeleteMaintenanceRequest;
use Openstatus\Maintenance\V1\GetMaintenanceRequest;
use Openstatus\Maintenance\V1\ListMaintenancesRequest;
use Openstatus\Maintenance\V1\Maintenance;
use Openstatus\Maintenance\V1\UpdateMaintenanceRequest;

$service = $client->maintenance->v1->maintenanceService;

$service->createMaintenance(new CreateMaintenanceRequest([
    'maintenance' => new Maintenance([
        'title' => 'Database migration',
        'page_id' => 'page_123',
        'from_timestamp' => 1730000000000,
        'to_timestamp' => 1730003600000,
    ]),
]));
$service->getMaintenance(new GetMaintenanceRequest(['id' => 'mnt_1']));
$service->listMaintenances(new ListMaintenancesRequest(['page_id' => 'page_123']));
$service->updateMaintenance(new UpdateMaintenanceRequest(['id' => 'mnt_1', 'maintenance' => $updated]));
$service->deleteMaintenance(new DeleteMaintenanceRequest(['id' => 'mnt_1']));

Notification Service

Configure notification channels and check usage limits.

use Openstatus\Notification\V1\CreateNotificationRequest;
use Openstatus\Notification\V1\Notification;
use Openstatus\Notification\V1\NotificationProvider;
use Openstatus\Notification\V1\NotificationData;
use Openstatus\Notification\V1\SlackData;

$service = $client->notification->v1->notificationService;

$service->createNotification(new CreateNotificationRequest([
    'notification' => new Notification([
        'name' => 'Eng channel',
        'provider' => NotificationProvider::NOTIFICATION_PROVIDER_SLACK,
        'data' => new NotificationData([
            'slack' => new SlackData(['webhook_url' => 'https://hooks.slack.com/...']),
        ]),
    ]),
]));

Other methods:

use Openstatus\Notification\V1\CheckNotificationLimitRequest;
use Openstatus\Notification\V1\DeleteNotificationRequest;
use Openstatus\Notification\V1\GetNotificationRequest;
use Openstatus\Notification\V1\ListNotificationsRequest;
use Openstatus\Notification\V1\SendTestNotificationRequest;
use Openstatus\Notification\V1\UpdateNotificationRequest;

$service->getNotification(new GetNotificationRequest(['id' => 'notif_1']));
$service->listNotifications(new ListNotificationsRequest());
$service->updateNotification(new UpdateNotificationRequest(['id' => 'notif_1', 'notification' => $updated]));
$service->deleteNotification(new DeleteNotificationRequest(['id' => 'notif_1']));
$service->sendTestNotification(new SendTestNotificationRequest(['id' => 'notif_1']));
$service->checkNotificationLimit(new CheckNotificationLimitRequest());

Reference

Monitor Options

Field Type Notes
name string Required, max 256 chars.
url string Required, max 2048 chars.
periodicity Periodicity (enum int) Required. See Enums.
method HTTPMethod (enum int) HTTP monitors only. Defaults to HTTP_METHOD_GET.
regions Region[] (enum int list) Required. See Regions.
active bool Defaults to false.
timeout int (ms) 0–120000. Defaults to 45000.
degraded_at int (ms) Optional latency threshold for "degraded" status.
retry int 0–10. Defaults to 3.
follow_redirects bool Defaults to true.
body string Request body (HTTP).
headers Headers[] Custom request headers (HTTP).
status_code_assertions StatusCodeAssertion[] See Assertions.
body_assertions BodyAssertion[] See Assertions.
header_assertions HeaderAssertion[] See Assertions.
description string Optional description.
public bool Whether the monitor is publicly visible.

Assertions

Assertions are evaluated against each check response. All matching assertions must pass for a check to be successful.

use Openstatus\Monitor\V1\BodyAssertion;
use Openstatus\Monitor\V1\HeaderAssertion;
use Openstatus\Monitor\V1\NumberComparator;
use Openstatus\Monitor\V1\StatusCodeAssertion;
use Openstatus\Monitor\V1\StringComparator;

$statusCode = new StatusCodeAssertion([
    'comparator' => NumberComparator::NUMBER_COMPARATOR_EQUAL,
    'target' => 200,
]);

$body = new BodyAssertion([
    'comparator' => StringComparator::STRING_COMPARATOR_CONTAINS,
    'target' => 'ok',
]);

$header = new HeaderAssertion([
    'key' => 'content-type',
    'comparator' => StringComparator::STRING_COMPARATOR_EQUAL,
    'target' => 'application/json',
]);

Regions

28 regions are available via the Region enum:

REGION_FLY_AMS  Amsterdam        REGION_FLY_FRA  Frankfurt
REGION_FLY_ARN  Stockholm        REGION_FLY_GDL  Guadalajara
REGION_FLY_ATL  Atlanta          REGION_FLY_GIG  Rio de Janeiro
REGION_FLY_BOG  Bogotá           REGION_FLY_GRU  São Paulo
REGION_FLY_BOM  Mumbai           REGION_FLY_HKG  Hong Kong
REGION_FLY_BOS  Boston           REGION_FLY_IAD  Ashburn
REGION_FLY_CDG  Paris            REGION_FLY_JNB  Johannesburg
REGION_FLY_DEN  Denver           REGION_FLY_LAX  Los Angeles
REGION_FLY_DFW  Dallas           REGION_FLY_LHR  London
REGION_FLY_EWR  New Jersey       REGION_FLY_MAA  Chennai
                                 REGION_FLY_MAD  Madrid
                                 REGION_FLY_MIA  Miami
                                 REGION_FLY_NRT  Tokyo
                                 REGION_FLY_ORD  Chicago
                                 REGION_FLY_OTP  Bucharest
                                 REGION_FLY_PHX  Phoenix
                                 REGION_FLY_QRO  Querétaro
                                 REGION_FLY_SCL  Santiago
                                 REGION_FLY_SEA  Seattle
                                 REGION_FLY_SIN  Singapore
                                 REGION_FLY_SJC  San Jose
                                 REGION_FLY_SYD  Sydney
                                 REGION_FLY_WAW  Warsaw
                                 REGION_FLY_YUL  Montréal
                                 REGION_FLY_YYZ  Toronto

Enums

All enums emitted by the protobuf compiler are plain classes with const int values. The generated value getters return int; use the static name() helper to convert to a string.

use Openstatus\Monitor\V1\HTTPMethod;
use Openstatus\Monitor\V1\Periodicity;

HTTPMethod::HTTP_METHOD_GET;          // int 1
HTTPMethod::name(HTTPMethod::HTTP_METHOD_GET); // "HTTP_METHOD_GET"
Periodicity::PERIODICITY_1M;          // int 2

Notable enums you'll encounter:

  • Openstatus\Monitor\V1\HTTPMethod
  • Openstatus\Monitor\V1\Periodicity
  • Openstatus\Monitor\V1\Region
  • Openstatus\Monitor\V1\MonitorStatus
  • Openstatus\Monitor\V1\NumberComparator
  • Openstatus\Monitor\V1\StringComparator
  • Openstatus\Monitor\V1\TimeRange
  • Openstatus\Monitor\V1\HTTPResponseLogRequestStatus
  • Openstatus\Monitor\V1\HTTPResponseLogTrigger
  • Openstatus\Health\V1\CheckResponse\ServingStatus
  • Openstatus\Status_report\V1\StatusReportStatus
  • Openstatus\Status_page\V1\OverallStatus
  • Openstatus\Status_page\V1\PageAccessType
  • Openstatus\Status_page\V1\PageTheme
  • Openstatus\Status_page\V1\PageComponentType
  • Openstatus\Notification\V1\NotificationProvider
  • Openstatus\Notification\V1\OpsgenieRegion

Working with int64 fields

int64 fields (timestamps, percentiles, latencies measured in nanoseconds) return int|string from getters because protoc-gen-php falls back to strings on 32-bit platforms to avoid silent overflow.

On 64-bit PHP — the default on macOS and Linux — the value is always an int. If you need to be safe across both platforms:

$timestamp = (int) $log->getTimestamp();   // ms since epoch
$p95Ms = (int) $summary->getP95();

The setter accepts either, so passing an int directly works.

Error Handling

All Connect RPC errors raise Openstatus\Sdk\Exception\OpenstatusException (or a subclass). The exception carries the Connect error code, HTTP status, parsed details array, and raw response body.

use Openstatus\Sdk\Exception\AuthenticationException;
use Openstatus\Sdk\Exception\InvalidArgumentException;
use Openstatus\Sdk\Exception\NotFoundException;
use Openstatus\Sdk\Exception\OpenstatusException;
use Openstatus\Sdk\Exception\RateLimitException;
use Openstatus\Sdk\Exception\ServiceUnavailableException;

try {
    $client->monitor->v1->monitorService->createHTTPMonitor($req);
} catch (AuthenticationException $e) {
    // 401 / connectCode "unauthenticated"
} catch (NotFoundException $e) {
    // 404 / "not_found"
} catch (InvalidArgumentException $e) {
    // 400 / "invalid_argument" — inspect $e->details() for field violations
    foreach ($e->details() as $detail) {
        printf("%s: %s\n", $detail->type, $detail->value);
    }
} catch (RateLimitException $e) {
    // 429 / "resource_exhausted"
} catch (ServiceUnavailableException $e) {
    // 5xx, network errors, or non-Connect responses
} catch (OpenstatusException $e) {
    // anything else
    printf("code=%s http=%d body=%s\n", $e->connectCode(), $e->httpStatus(), $e->rawBody());
}
Connect code Exception
unauthenticated Openstatus\Sdk\Exception\AuthenticationException
not_found Openstatus\Sdk\Exception\NotFoundException
invalid_argument Openstatus\Sdk\Exception\InvalidArgumentException
permission_denied Openstatus\Sdk\Exception\PermissionDeniedException
resource_exhausted Openstatus\Sdk\Exception\RateLimitException
unavailable Openstatus\Sdk\Exception\ServiceUnavailableException
anything else Openstatus\Sdk\Exception\OpenstatusException

Framework integration

Symfony

Register the client as a service in config/services.yaml:

services:
    Openstatus\Sdk\ClientOptions:
        arguments:
            $apiKey: '%env(OPENSTATUS_API_KEY)%'

    Openstatus\Sdk\OpenstatusClient:
        arguments:
            $options: '@Openstatus\Sdk\ClientOptions'

Inject into any controller or service:

public function __construct(private OpenstatusClient $openstatus) {}

Laravel

In a service provider's register() method:

$this->app->singleton(\Openstatus\Sdk\OpenstatusClient::class, function (): \Openstatus\Sdk\OpenstatusClient {
    return new \Openstatus\Sdk\OpenstatusClient(new \Openstatus\Sdk\ClientOptions(
        apiKey: env('OPENSTATUS_API_KEY'),
    ));
});

Resolve from the container:

$client = app(\Openstatus\Sdk\OpenstatusClient::class);

Custom PSR-18 client

Bring your own HTTP client (Symfony HttpClient, Saloon, Mock, etc.). Anything implementing Psr\Http\Client\ClientInterface works.

$client = new OpenstatusClient(new ClientOptions(
    apiKey: getenv('OPENSTATUS_API_KEY') ?: null,
    httpClient: $myPsr18Client,
));

Pair with a custom PSR-3 logger to log every request/response at DEBUG:

$client = new OpenstatusClient(new ClientOptions(
    apiKey: getenv('OPENSTATUS_API_KEY') ?: null,
    logger: $monolog,
));

Related

License

MIT — see LICENSE.