Monitors / TLS
TLS
Handshake a TLS listener that is not HTTP. Certificate expiry included.
How it works
The probe opens a TLS session to a host and port — Postgres, Redis, custom services, anything that speaks TLS. It records whether the handshake succeeded, the peer certificate expiry, and an optional payload exchange after the handshake.
Default port is 443 when you omit one. verify_tls controls whether the certificate must chain and match the hostname.
Target
host:port, or tls://host:port. Port defaults to 443.
tls://db.example.com:5432Type fields
| Field | What it does |
|---|---|
verify_tls | Verify the certificate chain and hostname. Defaults to on. |
request_body | Optional payload written after the handshake. The reply is [BODY]. |
proxy_url | HTTP or SOCKS proxy for the outbound dial. |
Placeholders
Available on this type. See conditions for operators and pat() / has() / len() / any().
[CONNECTED] [CERTIFICATE_EXPIRATION] [RESPONSE_TIME] [IP] [BODY] [DOMAIN_EXPIRATION]
Defaults
New monitors of this type start with:
[CONNECTED] == true[CERTIFICATE_EXPIRATION] > 48hExample conditions
[CONNECTED] == true[CERTIFICATE_EXPIRATION] > 48hGraphQL
type is Tls. Same fields as the admin, camelCase in the input (intervalSeconds, requestBody, probeIds).
mutation {
createMonitor(input: {
name: "DB TLS"
type: Tls
target: "tls://db.example.com:5432"
conditions: ["[CONNECTED] == true", "[CERTIFICATE_EXPIRATION] > 48h"]
}) { id }
}Terraform
Resource is nominal_monitor from returnearly/nominal. type is Tls. Shared arguments match the shared fields in snake_case (name, target, interval_seconds, probe_ids, channel_ids). Omitted conditions use the type defaults.
Type arguments: verify_tls, request_body, proxy_url. proxy_url is sensitive.
resource "nominal_monitor" "db_tls" {
name = "DB TLS"
type = "Tls"
target = "tls://db.example.com:5432"
verify_tls = true
conditions = ["[CONNECTED] == true", "[CERTIFICATE_EXPIRATION] > 48h"]
}