# Monitors

URL: https://zerodev.ca/docs/vail/monitors

> Add services to your status page and choose how each one is checked.



Services live in the `groups` array of `settings.json`. Each group is a heading on the page with its services listed under it.

```json
"groups": [
  {
    "name": "Websites",
    "services": [
      { "name": "Website", "description": "Main site", "type": "http", "target": "https://example.com" },
      { "name": "API", "description": "Public API", "type": "http", "target": "https://api.example.com/health" }
    ]
  },
  {
    "name": "Game Servers",
    "services": [
      { "name": "Survival", "description": "Minecraft Java", "type": "minecraft", "target": "play.example.com" }
    ]
  }
]
```

## When Checks Run

Vail checks every service when someone opens the page, then reuses the results for 15 seconds. There is no background job, so nothing runs while nobody is looking, and Vail does not keep a history.

## Service Options

| Option        | Required                    | What it does                                           |
| ------------- | --------------------------- | ------------------------------------------------------ |
| `name`        | Yes                         | The service name.                                      |
| `description` | Yes                         | A line under the name.                                 |
| `type`        | Yes                         | `http`, `tcp`, `minecraft`, `srv` or `manual`.         |
| `target`      | For every type but `manual` | The URL, hostname or IP to check.                      |
| `port`        | For `tcp`                   | The port to connect to.                                |
| `srvRecord`   | No                          | The SRV record to look up for `srv`.                   |
| `timeoutMs`   | No                          | How long to wait, in milliseconds. Defaults to `5000`. |
| `status`      | For `manual`                | `operational`, `degraded`, `outage` or `maintenance`.  |

A service missing its `target`, or its `port` for `tcp`, is not checked and shows as Operational. Double-check new entries after adding them.

## http

Sends a request to `target` and times the answer.

| Answer                              | Status      |
| ----------------------------------- | ----------- |
| 200 to 399                          | Operational |
| 400 to 499                          | Degraded    |
| 500 or more, no answer or a timeout | Outage      |

```json
{ "name": "API", "description": "Public API", "type": "http", "target": "https://api.example.com/health", "timeoutMs": 4000 }
```

Point it at a health route if you have one, so a slow homepage does not count against you.

## tcp

Opens a connection to `target` on `port`. Use it for a VPS, database, SSH or any other open port. It is Operational if the connection opens and Outage if not.

```json
{ "name": "Database", "description": "PostgreSQL", "type": "tcp", "target": "db.example.com", "port": 5432 }
```

## minecraft

Finds a Minecraft Java server the same way the game does:

1. With a `port`, connects to `target` on that port.
2. Otherwise looks up `_minecraft._tcp.<target>` and connects to the host and port it points to.
3. If there is no record, tries the parent domain, so `play.example.com` also checks `_minecraft._tcp.example.com`.
4. Falls back to port `25565`.

```json
{ "name": "Survival", "description": "Minecraft Java", "type": "minecraft", "target": "play.example.com" }
```

## srv

Looks up an SRV record and connects to the first host and port it lists. Uses `srvRecord`, or `target` if you leave it out.

```json
{ "name": "Voice", "description": "Voice server", "type": "srv", "target": "voice.example.com", "srvRecord": "_ts3._udp.voice.example.com" }
```

## manual

Not checked. Shows the `status` you set. Use it for services Vail cannot reach, such as a payment provider, or to mark something as under maintenance.

```json
{ "name": "Payments", "description": "Checkout provider", "type": "manual", "status": "maintenance" }
```

A manual service set to `maintenance` changes the summary banner to **Active System Maintenance**.
