# Uptime API

4 operations under /api/v1. Errors are RFC 9457 problem+json with a stable `code` field. The complete schemas are in https://nebulactrl.com/api/v1/openapi.json.

## GET /environments/{environmentId}/uptime

Uptime of every service of an environment

Each service with its state, its availability over the last 30 UTC days and 30 daily points. Needs `projects:read`.

Authentication: session cookie or `Authorization: Bearer nct_…` token.

Parameters:
- `environmentId` (path, string, required)

Response 200: OK (EnvironmentUptimeOutputBody)
  - `items` (EnvironmentService[] | null, required)
Errors: 401 Unauthorized; 403 Forbidden; 404 Not Found; 422 Unprocessable Entity; 500 Internal Server Error

## GET /services/{serviceId}/uptime

Uptime of a service

Current state (up, degraded, down, maintenance, paused, unknown) with when it began, the last check, last error and latency; consecutiveFailures and failureThreshold show a failure streak that is not an outage yet; availability over 24 hours, 7, 30 and 90 days (up + degraded) / (checks - maintenance), null without data; a series of the range (60 minute cells for 1h, hourly points for 24h and 7d, UTC days for 30d and 90d; every bucket is present, with checks 0 where there was no data) and the 20 most recent outages. Checks come from the service's server every 30 seconds. Needs `projects:read`.

Authentication: session cookie or `Authorization: Bearer nct_…` token.

Parameters:
- `serviceId` (path, string, required)
- `range` (query, enum: 1h | 24h | 7d | 30d | 90d): Window of the series: 60 minute cells for 1h, hourly points for 24h and 7d, UTC days for 30d and 90d.

Response 200: OK (ServiceReport)
  - `availability` (AvailabilityView, required)
  - `consecutiveFailures` (integer (int64), required): Failed checks in a row right now. An outage opens when it reaches failureThreshold (during a deployment the count stays 0).
  - `failureThreshold` (integer (int64), required): The service's effective failure threshold (the default 3 without a monitor).
  - `granularity` (enum: minute | hour | day, required): Width of the series buckets: minutes for 1h, hours for 24h and 7d, UTC days for 30d and 90d.
  - `incidents` (UptimeIncidentView[] | null, required): The most recent 20, newest first.
  - `lastCheckAt` (string (date-time) | null, required)
  - `lastError` (string, required): What the last failing check reported; empty while it passes.
  - `lastOkAt` (string (date-time) | null, required)
  - `latencyMs` (integer (int64) | null, required): Latency of the last passing check that measured one.
  - `monitor` (MonitorView, required)
  - `range` (enum: 1h | 24h | 7d | 30d | 90d, required)
  - `series` (UptimePoint[] | null, required): Oldest first, ending with the running bucket; every bucket of the range is present, with checks 0 where there was no data. 1h has 60 minute cells, 24h 24 hours, 7d 168 hours, 30d 30 days, 90d 90 days.
  - `serviceId` (string, required)
  - `since` (string (date-time) | null, required): When the state was entered; null before the first check.
  - `state` (enum: up | degraded | down | maintenance | paused | unknown, required)
Errors: 401 Unauthorized; 403 Forbidden; 404 Not Found; 422 Unprocessable Entity; 500 Internal Server Error

## GET /services/{serviceId}/uptime-monitor

Get a service's uptime monitor settings

Whether the service is probed, whether outages alert, and how many failed or passing checks open and end an outage. A service without settings is monitored with the defaults (3 and 2). Needs `projects:read`.

Authentication: session cookie or `Authorization: Bearer nct_…` token.

Parameters:
- `serviceId` (path, string, required)

Response 200: OK (MonitorView)
  - `alerts` (boolean, required): Send uptime.down and uptime.up notifications for outages of this service. Outages are recorded either way.
  - `enabled` (boolean, required): Probe the service. When off, agents stop probing it and its state is paused.
  - `failureThreshold` (integer (int64), required): Consecutive failed checks (30 s apart) that open an outage.
  - `recoveryThreshold` (integer (int64), required): Consecutive passing checks that end it.
  - `reminderMinutes` (integer (int64), required): While an outage lasts, send uptime.down again every this many minutes (counted from the last alert). 0 = never. Needs alerts on; not sent during maintenance.
Errors: 401 Unauthorized; 403 Forbidden; 404 Not Found; 422 Unprocessable Entity; 500 Internal Server Error

## PUT /services/{serviceId}/uptime-monitor

Set a service's uptime monitor settings

Replaces the settings. Takes effect without a deployment: the server's agent stops or resumes probing the service within seconds. Switching monitoring off pauses the service and closes its open outage without a recovery notice. Needs the `admin` scope (workspace owner or admin). Audited as `uptime_monitor.update`.

Authentication: session cookie or `Authorization: Bearer nct_…` token.

Parameters:
- `serviceId` (path, string, required)

Request body (application/json, required): MonitorView
  - `alerts` (boolean, required): Send uptime.down and uptime.up notifications for outages of this service. Outages are recorded either way.
  - `enabled` (boolean, required): Probe the service. When off, agents stop probing it and its state is paused.
  - `failureThreshold` (integer (int64), required): Consecutive failed checks (30 s apart) that open an outage.
  - `recoveryThreshold` (integer (int64), required): Consecutive passing checks that end it.
  - `reminderMinutes` (integer (int64), required): While an outage lasts, send uptime.down again every this many minutes (counted from the last alert). 0 = never. Needs alerts on; not sent during maintenance.

Response 200: OK (MonitorView)
  - `alerts` (boolean, required): Send uptime.down and uptime.up notifications for outages of this service. Outages are recorded either way.
  - `enabled` (boolean, required): Probe the service. When off, agents stop probing it and its state is paused.
  - `failureThreshold` (integer (int64), required): Consecutive failed checks (30 s apart) that open an outage.
  - `recoveryThreshold` (integer (int64), required): Consecutive passing checks that end it.
  - `reminderMinutes` (integer (int64), required): While an outage lasts, send uptime.down again every this many minutes (counted from the last alert). 0 = never. Needs alerts on; not sent during maintenance.
Errors: 401 Unauthorized; 403 Forbidden; 404 Not Found; 422 Unprocessable Entity; 500 Internal Server Error
