> ## Documentation Index
> Fetch the complete documentation index at: https://pulse-41cf5b0d.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API Endpoints for Monitor Management

> Create, read, update, delete, and trigger monitors via the PulseGuard REST API. Requires a valid API key.

The Monitors API gives you complete lifecycle control over every monitor in your account. Use it to automate monitor provisioning in CI/CD pipelines, sync monitor configuration from infrastructure-as-code, tail live check results, or force immediate health checks during deployments. All endpoints require a valid Bearer token. Endpoints that create, update, or delete resources additionally enforce the `write` scope and return `403` if it is absent.

***

## List all monitors

Retrieve every monitor belonging to your account, ordered by creation date descending.

**`GET /api/cli/monitors`**

### Request headers

| Header          | Value              |
| --------------- | ------------------ |
| `Authorization` | `Bearer <api_key>` |

### curl example

```bash theme={null}
curl https://app.pulseguard.io/api/cli/monitors \
  -H "Authorization: Bearer pg_live_your_api_key"
```

### Response

```json theme={null}
{
  "monitors": [
    {
      "id": "clx1234abc",
      "name": "Production API",
      "url": "https://api.example.com/health",
      "type": "HTTP",
      "status": "UP",
      "interval": 60,
      "timeout": 10,
      "lastCheck": "2024-01-15T10:30:00.000Z",
      "nextCheck": "2024-01-15T10:31:00.000Z",
      "alertThreshold": 1,
      "checkRegions": null,
      "method": "GET"
    }
  ]
}
```

<Expandable title="Response fields">
  <ResponseField name="monitors" type="array" required>
    Array of monitor objects.
  </ResponseField>

  <ResponseField name="monitors[].id" type="string" required>
    Unique identifier for the monitor.
  </ResponseField>

  <ResponseField name="monitors[].name" type="string" required>
    Human-readable name you gave the monitor.
  </ResponseField>

  <ResponseField name="monitors[].url" type="string" required>
    The URL being monitored.
  </ResponseField>

  <ResponseField name="monitors[].type" type="string" required>
    Monitor type. Currently `HTTP`.
  </ResponseField>

  <ResponseField name="monitors[].status" type="string" required>
    Current status: `UP`, `DOWN`, or `PENDING`.
  </ResponseField>

  <ResponseField name="monitors[].interval" type="integer" required>
    Check interval in seconds.
  </ResponseField>

  <ResponseField name="monitors[].timeout" type="integer" required>
    Request timeout in seconds.
  </ResponseField>

  <ResponseField name="monitors[].lastCheck" type="string">
    ISO 8601 timestamp of the last completed check. `null` if the monitor has never been checked.
  </ResponseField>

  <ResponseField name="monitors[].nextCheck" type="string">
    ISO 8601 timestamp of the next scheduled check.
  </ResponseField>

  <ResponseField name="monitors[].alertThreshold" type="integer" required>
    Number of consecutive failures before an alert fires.
  </ResponseField>

  <ResponseField name="monitors[].checkRegions" type="string | null">
    JSON-encoded array of region codes, or `null` to use the default region.
  </ResponseField>

  <ResponseField name="monitors[].method" type="string" required>
    HTTP method used for checks (e.g. `GET`, `POST`).
  </ResponseField>
</Expandable>

***

## Create a monitor

Create a new HTTP monitor. Requires the `write` scope.

**`POST /api/cli/monitors`**

### Request headers

| Header          | Value                                     |
| --------------- | ----------------------------------------- |
| `Authorization` | `Bearer <api_key>` (write scope required) |
| `Content-Type`  | `application/json`                        |

### Request body

<ParamField body="name" type="string" required>
  Display name for the monitor. Cannot be blank.
</ParamField>

<ParamField body="url" type="string" required>
  The full URL to monitor, including the scheme (e.g. `https://api.example.com/health`). Cannot be blank.
</ParamField>

<ParamField body="type" type="string" default="HTTP">
  Monitor type. Currently only `HTTP` is supported.
</ParamField>

<ParamField body="interval" type="integer" default="60">
  How often to run the check, in seconds.
</ParamField>

<ParamField body="timeout" type="integer" default="10">
  Maximum time to wait for a response, in seconds. A check that exceeds this limit is recorded as `TIMEOUT`.
</ParamField>

<ParamField body="method" type="string" default="GET">
  HTTP method to use: `GET`, `POST`, `PUT`, `PATCH`, or `HEAD`.
</ParamField>

<ParamField body="headers" type="object">
  Custom request headers sent with each check. Provide as a key-value object, e.g. `{"X-Api-Version": "2"}`. Stored as JSON.
</ParamField>

<ParamField body="body" type="string">
  Request body to send with `POST`, `PUT`, or `PATCH` checks.
</ParamField>

<ParamField body="expectation" type="object">
  Assertion rules that must pass for a check to be considered `UP`. Stored as JSON. Example: `{"statusCode": 200, "bodyContains": "ok"}`.
</ParamField>

<ParamField body="alertThreshold" type="integer" default="1">
  Number of consecutive failures required before an alert is triggered.
</ParamField>

<ParamField body="checkRegions" type="array">
  List of region codes to run checks from, e.g. `["us-east-1", "eu-west-1"]`. Leave empty to use the default region.
</ParamField>

<ParamField body="runbookUrl" type="string">
  URL of the runbook or incident-response guide for this monitor. Included in alert notifications and webhook payloads.
</ParamField>

### curl example

```bash theme={null}
curl -X POST https://app.pulseguard.io/api/cli/monitors \
  -H "Authorization: Bearer pg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API",
    "url": "https://api.example.com/health",
    "interval": 60,
    "timeout": 10,
    "method": "GET",
    "alertThreshold": 2,
    "runbookUrl": "https://docs.example.com/runbooks/api"
  }'
```

### Response `201 Created`

```json theme={null}
{
  "monitor": {
    "id": "clx1234abc",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP",
    "status": "PENDING",
    "createdAt": "2024-01-15T10:00:00.000Z"
  }
}
```

<Note>
  A newly created monitor has `status: "PENDING"` until the first check completes. Use the [trigger endpoint](#trigger-an-immediate-check) to run the first check immediately.
</Note>

***

## Get a monitor

Retrieve full details of a single monitor, including its 10 most recent check events.

**`GET /api/cli/monitors/:id`**

### curl example

```bash theme={null}
curl https://app.pulseguard.io/api/cli/monitors/clx1234abc \
  -H "Authorization: Bearer pg_live_your_api_key"
```

### Response

```json theme={null}
{
  "monitor": {
    "id": "clx1234abc",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP",
    "status": "UP",
    "interval": 60,
    "timeout": 10,
    "method": "GET",
    "headers": null,
    "body": null,
    "expectation": null,
    "alertThreshold": 1,
    "checkRegions": null,
    "runbookUrl": "https://docs.example.com/runbooks/api",
    "lastCheck": "2024-01-15T10:30:00.000Z",
    "nextCheck": "2024-01-15T10:31:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z",
    "events": [
      {
        "status": "UP",
        "latency": 245,
        "errorReason": null,
        "timestamp": "2024-01-15T10:30:00.000Z",
        "region": "us-east-1"
      }
    ]
  }
}
```

Returns `404` if the monitor ID does not exist or belongs to a different account.

***

## Update a monitor

Update one or more fields on an existing monitor. Only fields you include in the request body are changed — omitted fields remain unchanged. Requires the `write` scope.

**`PUT /api/cli/monitors/:id`**

### Request headers

| Header          | Value                                     |
| --------------- | ----------------------------------------- |
| `Authorization` | `Bearer <api_key>` (write scope required) |
| `Content-Type`  | `application/json`                        |

### Request body

All fields are optional. Provide only the fields you want to update.

<ParamField body="name" type="string">
  New display name.
</ParamField>

<ParamField body="url" type="string">
  New URL to monitor.
</ParamField>

<ParamField body="interval" type="integer">
  New check interval in seconds.
</ParamField>

<ParamField body="timeout" type="integer">
  New request timeout in seconds.
</ParamField>

<ParamField body="method" type="string">
  New HTTP method.
</ParamField>

<ParamField body="alertThreshold" type="integer">
  New consecutive-failure threshold for alerts.
</ParamField>

<ParamField body="runbookUrl" type="string">
  New runbook URL.
</ParamField>

<ParamField body="headers" type="object">
  Replacement custom headers object. Overwrites any previously stored headers.
</ParamField>

<ParamField body="expectation" type="object">
  Replacement assertion rules. Overwrites any previously stored expectation.
</ParamField>

<ParamField body="checkRegions" type="array">
  Replacement list of region codes.
</ParamField>

### curl example

```bash theme={null}
curl -X PUT https://app.pulseguard.io/api/cli/monitors/clx1234abc \
  -H "Authorization: Bearer pg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "interval": 30,
    "alertThreshold": 3
  }'
```

### Response

```json theme={null}
{
  "monitor": {
    "id": "clx1234abc",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP",
    "status": "UP",
    "updatedAt": "2024-01-15T11:00:00.000Z"
  }
}
```

***

## Delete a monitor

Permanently delete a monitor and all its associated events. This action cannot be undone. Requires the `write` scope.

**`DELETE /api/cli/monitors/:id`**

### curl example

```bash theme={null}
curl -X DELETE https://app.pulseguard.io/api/cli/monitors/clx1234abc \
  -H "Authorization: Bearer pg_live_your_api_key"
```

### Response

```json theme={null}
{
  "success": true
}
```

<Warning>
  Deleting a monitor permanently removes all historical check events and incidents associated with it. Export any data you need before deleting.
</Warning>

***

## Trigger an immediate check

Force an HTTP health check on a monitor right now, bypassing the normal schedule. The check runs synchronously and returns the result in the response. The result is also persisted as a regular monitor event. Any valid Bearer token can trigger this endpoint; providing a URL override additionally requires the `write` scope.

**`POST /api/cli/monitors/:id/trigger`**

### Request headers

| Header          | Value                                           |
| --------------- | ----------------------------------------------- |
| `Authorization` | `Bearer <api_key>`                              |
| `Content-Type`  | `application/json` (only if using URL override) |

### Optional request body

<ParamField body="url" type="string">
  Override the monitor's configured URL for this single check. Useful for testing a new endpoint before updating the monitor. Requires the `write` scope.
</ParamField>

### curl example

```bash theme={null}
# Standard trigger — no body required
curl -X POST https://app.pulseguard.io/api/cli/monitors/clx1234abc/trigger \
  -H "Authorization: Bearer pg_live_your_api_key"
```

```bash theme={null}
# With a URL override (write scope required)
curl -X POST https://app.pulseguard.io/api/cli/monitors/clx1234abc/trigger \
  -H "Authorization: Bearer pg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.example.com/health/v2"}'
```

### Response

```json theme={null}
{
  "monitorId": "clx1234abc",
  "name": "Production API",
  "url": "https://api.example.com/health",
  "status": "UP",
  "latency": 182,
  "httpStatus": 200,
  "errorReason": null,
  "checkedAt": "2024-01-15T10:30:00.000Z"
}
```

<Expandable title="Response fields">
  <ResponseField name="monitorId" type="string" required>
    ID of the monitor that was checked.
  </ResponseField>

  <ResponseField name="name" type="string" required>
    Display name of the monitor.
  </ResponseField>

  <ResponseField name="url" type="string" required>
    The URL that was actually checked (may differ from the monitor's configured URL if an override was provided).
  </ResponseField>

  <ResponseField name="status" type="string" required>
    Result of the check: `UP` or `DOWN`.
  </ResponseField>

  <ResponseField name="latency" type="integer" required>
    Round-trip time in milliseconds.
  </ResponseField>

  <ResponseField name="httpStatus" type="integer">
    HTTP status code returned by the target. `null` if the request did not complete.
  </ResponseField>

  <ResponseField name="errorReason" type="string | null" required>
    Machine-readable failure reason if `status` is `DOWN`. Possible values: `TIMEOUT`, `DNS_ERROR`, `CONNECTION_REFUSED`, `HTTP_<code>` (e.g. `HTTP_503`), `UNKNOWN_ERROR`. `null` when `status` is `UP`.
  </ResponseField>

  <ResponseField name="checkedAt" type="string" required>
    ISO 8601 timestamp of when the check was performed.
  </ResponseField>
</Expandable>

<Note>
  The trigger endpoint only supports `HTTP` monitors. Attempting to trigger a monitor of another type returns `422 Unprocessable Entity`.
</Note>

***

## List monitor events

Retrieve the check history for a monitor in chronological order. Supports incremental polling with the `since` parameter — ideal for building live log tails.

**`GET /api/cli/monitors/:id/events`**

### Query parameters

<ParamField query="limit" type="integer" default="50">
  Maximum number of events to return. The server caps this at `500`.
</ParamField>

<ParamField query="since" type="string">
  ISO 8601 timestamp. When provided, only events recorded after this timestamp are returned. Use the `timestamp` of the last event you received to poll incrementally.
</ParamField>

### curl example

```bash theme={null}
# Fetch the 50 most recent events
curl "https://app.pulseguard.io/api/cli/monitors/clx1234abc/events" \
  -H "Authorization: Bearer pg_live_your_api_key"

# Poll for events since the last one you received
curl "https://app.pulseguard.io/api/cli/monitors/clx1234abc/events?since=2024-01-15T10:30:00.000Z" \
  -H "Authorization: Bearer pg_live_your_api_key"
```

### Response

```json theme={null}
{
  "monitorId": "clx1234abc",
  "name": "Production API",
  "events": [
    {
      "id": "evt_abc123",
      "status": "UP",
      "latency": 245,
      "errorReason": null,
      "timestamp": "2024-01-15T10:30:00.000Z",
      "region": "us-east-1"
    },
    {
      "id": "evt_def456",
      "status": "DOWN",
      "latency": 10002,
      "errorReason": "TIMEOUT",
      "timestamp": "2024-01-15T10:29:00.000Z",
      "region": "us-east-1"
    }
  ]
}
```

<Expandable title="Response fields">
  <ResponseField name="monitorId" type="string" required>
    ID of the monitor.
  </ResponseField>

  <ResponseField name="name" type="string" required>
    Display name of the monitor.
  </ResponseField>

  <ResponseField name="events" type="array" required>
    Events in chronological (oldest-first) order.
  </ResponseField>

  <ResponseField name="events[].id" type="string" required>
    Unique event identifier.
  </ResponseField>

  <ResponseField name="events[].status" type="string" required>
    `UP` or `DOWN`.
  </ResponseField>

  <ResponseField name="events[].latency" type="integer" required>
    Round-trip time in milliseconds.
  </ResponseField>

  <ResponseField name="events[].errorReason" type="string | null" required>
    Failure reason for `DOWN` events. `null` for `UP` events.
  </ResponseField>

  <ResponseField name="events[].timestamp" type="string" required>
    ISO 8601 timestamp of the check.
  </ResponseField>

  <ResponseField name="events[].region" type="string" required>
    Region code that performed the check (e.g. `us-east-1`, `cli-trigger`).
  </ResponseField>
</Expandable>
