> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devhelm.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitors Guide

> Step-by-step guide to creating and configuring HTTP, TCP, DNS, ICMP, MCP, and Heartbeat monitors

This guide walks you through creating monitors for each supported type. For conceptual background, see [Monitoring overview](/monitoring/overview).

## HTTP monitors

The most common monitor type. Checks a URL and evaluates response status, body, headers, and timing.

<CodeGroup>
  ```bash CLI theme={null}
  devhelm monitors create \
    --name "API Health" \
    --type HTTP \
    --url https://api.example.com/health \
    --frequency 60 \
    --regions us-east,eu-west
  ```

  ```yaml devhelm.yml theme={null}
  monitors:
    - name: API Health
      type: HTTP
      config:
        url: https://api.example.com/health
        method: GET
        verifyTls: true
      frequencySeconds: 60
      regions:
        - us-east
        - eu-west
  ```

  ```typescript TypeScript SDK theme={null}
  const monitor = await client.monitors.create({
    name: "API Health",
    type: "HTTP",
    config: {
      url: "https://api.example.com/health",
      method: "GET",
      verifyTls: true,
    },
    frequencySeconds: 60,
    regions: ["us-east", "eu-west"],
  });
  ```
</CodeGroup>

### HTTP config options

| Field           | Description                                      | Default      |
| --------------- | ------------------------------------------------ | ------------ |
| `url`           | Target URL                                       | *(required)* |
| `method`        | HTTP method: GET, POST, PUT, PATCH, DELETE, HEAD | `GET`        |
| `customHeaders` | Additional headers as key-value pairs            | —            |
| `requestBody`   | Body content for POST/PUT/PATCH                  | —            |
| `contentType`   | Content-Type header value                        | —            |
| `verifyTls`     | Validate TLS certificates                        | `true`       |

### Adding assertions

Assertions define pass/fail criteria beyond "did the request succeed":

```yaml theme={null}
monitors:
  - name: API Health
    type: HTTP
    config:
      url: https://api.example.com/health
      method: GET
    frequencySeconds: 60
    regions:
      - us-east
    assertions:
      - config:
          type: status_code
          expected: "200"
          operator: equals
        severity: fail
      - config:
          type: response_time
          thresholdMs: 2000
        severity: fail
      - config:
          type: response_time_warn
          warnMs: 500
        severity: warn
      - config:
          type: ssl_expiry
          minDaysRemaining: 14
        severity: fail
```

### Authenticated requests

For endpoints that require authentication, store credentials in the Vault and reference them:

```yaml theme={null}
monitors:
  - name: Private API
    type: HTTP
    config:
      url: https://api.example.com/private/health
      method: GET
    auth:
      type: bearer
      secret: API_TOKEN
    frequencySeconds: 60
    regions:
      - us-east
```

Supported auth types: `bearer`, `basic`, `header`, `api_key`.

## TCP monitors

Check that a host is accepting connections on a specific port.

<CodeGroup>
  ```bash CLI theme={null}
  devhelm monitors create \
    --name "Database Port" \
    --type TCP \
    --url db.example.com \
    --port 5432 \
    --frequency 60 \
    --regions us-east
  ```

  ```yaml devhelm.yml theme={null}
  monitors:
    - name: Database Port
      type: TCP
      config:
        host: db.example.com
        port: 5432
        timeoutMs: 5000
      frequencySeconds: 60
      regions:
        - us-east
  ```
</CodeGroup>

## DNS monitors

Verify domain name resolution and record values.

```yaml theme={null}
monitors:
  - name: DNS Resolution
    type: DNS
    config:
      hostname: example.com
      recordTypes:
        - A
        - AAAA
    frequencySeconds: 300
    regions:
      - us-east
    assertions:
      - config:
          type: dns_resolves
        severity: fail
      - config:
          type: dns_expected_ips
          ips:
            - "93.184.216.34"
        severity: fail
```

DNS config supports custom nameservers and timeouts:

| Field            | Description                                          |
| ---------------- | ---------------------------------------------------- |
| `hostname`       | Domain to resolve                                    |
| `recordTypes`    | A, AAAA, CNAME, MX, NS, TXT, SRV, SOA, CAA, PTR      |
| `nameservers`    | Custom nameservers (uses system defaults if omitted) |
| `timeoutMs`      | Per-query timeout                                    |
| `totalTimeoutMs` | Total timeout for all queries                        |

## ICMP monitors

Ping a host to check reachability and measure latency.

```yaml theme={null}
monitors:
  - name: Server Ping
    type: ICMP
    config:
      host: server.example.com
      packetCount: 5
      timeoutMs: 3000
    frequencySeconds: 60
    regions:
      - us-east
    assertions:
      - config:
          type: icmp_reachable
        severity: fail
      - config:
          type: icmp_packet_loss
          maxPercent: 10
        severity: warn
```

## MCP Server monitors

Check that an MCP (Model Context Protocol) server starts and responds correctly. Useful for monitoring AI tool servers.

```yaml theme={null}
monitors:
  - name: My MCP Server
    type: MCP_SERVER
    config:
      command: npx
      args:
        - "@my-org/mcp-server"
      env:
        API_KEY: ${MCP_API_KEY}
    frequencySeconds: 300
    regions:
      - us-east
    assertions:
      - config:
          type: mcp_connects
        severity: fail
      - config:
          type: mcp_tool_available
          toolName: search
        severity: fail
```

## Heartbeat monitors

Passive monitors — your service pings DevHelm instead of DevHelm checking your service. Ideal for cron jobs, background workers, and batch processes.

```yaml theme={null}
monitors:
  - name: Nightly Backup
    type: HEARTBEAT
    config:
      expectedInterval: 86400
      gracePeriod: 3600
    frequencySeconds: 86400
```

After creating a heartbeat monitor, you'll receive a ping endpoint URL. Send a request to it from your job:

```bash theme={null}
curl -X POST https://api.devhelm.io/api/v1/heartbeat/<token>
```

<Warning>
  Heartbeat monitors cannot have probe regions — they rely on incoming pings from your infrastructure.
</Warning>

## Customizing incident policies

Override the default incident policy per monitor:

```yaml theme={null}
monitors:
  - name: API Health
    type: HTTP
    config:
      url: https://api.example.com/health
      method: GET
    frequencySeconds: 60
    regions:
      - us-east
      - eu-west
      - ap-south
    incidentPolicy:
      triggerRules:
        - type: consecutive_failures
          count: 3
          scope: per_region
          severity: down
        - type: response_time
          count: 3
          scope: per_region
          thresholdMs: 5000
          aggregationType: p95
          severity: degraded
      confirmation:
        type: multi_region
        minRegionsFailing: 2
        maxWaitSeconds: 120
      recovery:
        consecutiveSuccesses: 3
        minRegionsPassing: 2
        cooldownMinutes: 10
```

## Next steps

<CardGroup cols={2}>
  <Card title="Alerting guide" icon="bell" href="/guides/alerting">
    Route monitor incidents to your team.
  </Card>

  <Card title="Monitoring as Code" icon="file-code" href="/guides/monitoring-as-code">
    Manage monitors in YAML and deploy from CI.
  </Card>
</CardGroup>
