# HTTP and HTTPS monitors

An HTTP or HTTPS monitor sends a request to a URL and checks the response. The check passes when the status code is one you expect and, if you set one, the body contains a keyword. An HTTPS monitor also checks the TLS certificate of the server.

## Add an HTTP or HTTPS monitor

1. In the sidebar, select **Monitors**.
2. Select **Create monitor**.
3. Under **Type**, select **HTTPS** or **HTTP**.
4. In **Target**, enter the URL without the scheme, for example `example.com/health`.
5. In **Max redirects**, enter how many redirects Spectate follows, 0 to 10.
6. Select **Create and start**.

The other settings are on the **Settings** tab of the monitor. Select **Save changes** after you change them.

## Target format

The type of the monitor sets the scheme. An HTTPS monitor requests `https://` and the target, and an HTTP monitor requests `http://` and the target. Spectate stores the target without the scheme, for example `example.com/health`.

If you paste a URL with a scheme into **Target**, the dashboard removes the scheme. To change the scheme, change **Type**.

In the [public API](/api-reference/monitors) and the [MCP server](/developers/mcp), the scheme in `uri` is optional:

| `protocol` | `uri` | Result |
|---|---|---|
| `https` | `example.com/health` | Spectate stores `example.com/health` and checks `https://example.com/health`. |
| `https` | `https://example.com/health` | The same monitor. Spectate removes the scheme. |
| `https` | `http://example.com/health` | Error `422`. The scheme must match `protocol`. |

The response has the stored target in `uri`, and the full URL in `url`.

## What a check does

1. The Spectate checker looks up the host name and opens a new connection. It never reuses a connection, so each check measures DNS, connect and TLS time.
2. It sends the request with the method, headers and authentication of the monitor. The request has no body.
3. It follows redirects, up to **Max redirects**.
4. It compares the status code with **Expected status**.
5. If the status code is expected and the monitor has a **Keyword**, it looks for the keyword in the body.

The check fails if any of these is true:

- The host name does not resolve, or resolves to a private or reserved address.
- The connection fails or the TLS handshake fails.
- The certificate is not valid, and **Allow insecure requests** is off. This applies to HTTPS only.
- The check takes longer than **Timeout**.
- The status code is not expected.
- The keyword check fails.

One failed check does not make the monitor down. Spectate checks again about 5 seconds later, and only a second failure makes the monitor down. See [Locations and checks](/monitors/locations-and-checks).

## Expected status codes

**Expected status** (`expected_http_status_code` in the API) lists the status codes that count as up. Separate codes with commas. A `*` matches any digit.

| Value | Counts as up |
|---|---|
| Empty (default) | 200 to 399 |
| `200` | Only 200 |
| `2**` | 200 to 299 |
| `2**,301` | 200 to 299, and 301 |
| `401` | Only 401, for example for a page behind a login |
| `*` | Any status code |

`2*` is the same as `2**`. The value can have up to 200 characters.

## Keyword

**Keyword** is text that must be in the response body. The match is case-sensitive. Spectate reads up to 1 MiB of the body. Text after the first 1 MiB is not checked.

Select **Invert keyword check** to fail the check when the body contains the keyword. Use this for text such as `Maintenance mode` or `Fatal error`.

Spectate checks the keyword only when the status code is expected. The keyword can have up to 255 characters.

## Method, headers and user agent

| Setting | Values | Default |
|---|---|---|
| **Method** | `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` | `GET` |
| **Headers** | Up to 25 headers. Names up to 255 characters, values up to 2,500 characters. | None |
| **User agent** | Up to 255 characters | `Spectate/1.0 (+https://docs.spectate.net/faq/uptime-monitor-bot)` |

To add a header, go to the **Headers** section and select **Add header**. A `Host` header sets the host name that the request asks for. If you set both **User agent** and a `User-Agent` header, **User agent** wins.

Some firewalls block unknown bots. To allow Spectate, see [The uptime monitor bot](/faq/uptime-monitor-bot) and [IP addresses](/faq/ip-addresses).

## Authentication

Set **Authentication** under **HTTP request → Advanced**.

| **Authentication** | Uses | Sends |
|---|---|---|
| None | | No credentials |
| Basic | **Auth username** and **Auth password / token** | HTTP Basic authentication |
| Bearer | **Auth password / token** | `Authorization: Bearer TOKEN` |
| Digest | **Auth username** and **Auth password / token** | HTTP Digest authentication, MD5 or SHA-256, `qop=auth` |

Spectate encrypts the password or token. The dashboard and the API never show it again. The field shows **Saved** when Spectate has a stored value. To keep the stored value, leave the field empty when you save.

## Redirects

Spectate follows up to **Max redirects** redirects, 0 to 10. The dashboard sets 3 for a new monitor. In the API, `max_redirects: null` follows up to 10.

If the server asks for more redirects than the limit, Spectate checks the last redirect response itself. With the default **Expected status**, a `3xx` response counts as up.

If a redirect goes to another host, scheme or port, Spectate removes credentials before it follows the redirect. It removes `Authorization`, `Cookie` and your custom headers. It keeps `Accept`, `Accept-Encoding`, `Accept-Language`, `Cache-Control`, `Pragma` and `User-Agent`. A redirect from `http` on port 80 to `https` on port 443 of the same host keeps all headers.

## Timeouts

| Setting | Limits | Default |
|---|---|---|
| **Timeout** | The whole check, 1 to 60 seconds | 10 seconds in the dashboard, 30 seconds in the API |
| **Connection timeout** | Only the TCP connection, 1 to 60 seconds | The value of **Timeout** |

**Connection timeout** is under **HTTP request → Advanced**. If it is longer than **Timeout**, **Timeout** applies.

## TLS

An HTTPS monitor verifies the certificate of the server against the trust store of the checker and the host name of the URL. If the verification fails, the check fails.

Select **Allow insecure requests** in the **TLS** section to skip this verification for the uptime check. Use it for self-signed certificates or an internal certificate authority. The separate [certificate checks](/monitors/certificates) still report and alert on certificate problems.

## Failure snapshots and screenshots

When an HTTP or HTTPS monitor goes down, Spectate keeps a snapshot of what the checker saw. It records one snapshot per outage, from the check that confirmed the failure.

A snapshot has:

- The error, the status code and the response time.
- The final URL after redirects, and the IP address that answered.
- The response headers. Spectate replaces the values of `Set-Cookie`, `Cookie`, `Authorization` and `Proxy-Authorization` with `[redacted]`.
- The first 128 KiB of the body, and the page title.
- A screenshot of the page, 1440 by 900 pixels, from the same region.

Spectate takes the response and the screenshot only when the server sent an HTTP response. A refused connection, a DNS error or a TLS error has no snapshot body and no screenshot.

The screenshot uses the user agent, headers and Basic or Bearer authentication of the monitor. It sends them only to the monitor's own host. Digest authentication does not work for screenshots.

Screenshots are part of every paid plan and the trial. The snapshot shows on the alert page under **What we saw**, and on the monitor **Overview** under **Recent failures**. Spectate deletes snapshots and screenshots after 90 days.

| Screenshot status | Meaning |
|---|---|
| `pending` | The checker takes the screenshot. It arrives a few seconds after the alert. |
| `captured` | The screenshot is stored. |
| `failed` | No screenshot was possible. The snapshot shows the reason. |
| `not_requested` | The plan has no screenshots, or the server sent no HTTP response. |

## Settings reference

The names in the [public API](/api-reference/monitors). Settings in `advanced_settings` are marked with `advanced_settings.`.

| Dashboard label | API field |
|---|---|
| **Target** | `uri` |
| **Max redirects** | `max_redirects` |
| **Timeout** | `timeout` |
| **Expected status** | `expected_http_status_code` |
| **Allow insecure requests** | `allow_insecure_requests` |
| **Headers** | `headers`, a list of `key` and `value` |
| **Method** | `advanced_settings.method` |
| **Keyword** | `advanced_settings.keyword` |
| **Invert keyword check** | `advanced_settings.keyword_inverted` |
| **Connection timeout** | `advanced_settings.connection_timeout` |
| **User agent** | `advanced_settings.useragent` |
| **Authentication** | `advanced_settings.auth_method`: `basic`, `bearer` or `digest` |
| **Auth username** | `advanced_settings.auth_user` |
| **Auth password / token** | `advanced_settings.auth_password`, write-only |
