Self-hosted endpoint monitoring

Stay nominal.

In ops, nominal means everything is within expected parameters. Nominal is the monitor that tells you when it isn’t.

nominal
adjective operating as expected; within normal limits

Database-backed monitors. Readable conditions. GraphQL, Terraform, and alerts where you already sit.

Why Nominal

Monitors as data, not a pile of YAML.

Write conditions as expressions. Put the records in a database you can query, mutate, and Terraform.

HTTP and ping

Custom method, headers, and body for HTTPS. ICMP with a TCP fallback when the network won’t let you ping.

Readable conditions

[STATUS], [BODY], [RESPONSE_TIME], [IP], [CONNECTED], [CERTIFICATE_EXPIRATION].

GraphQL and Terraform

API tokens for GraphQL. A Terraform provider when the admin shouldn’t be the source of truth.

Multi-region probes

Each region has its own queue. Workers set PROBE_REGION and check from where you actually run.

Alert where you already sit

Mail, Slack, Teams, Discord, generic webhooks, and PagerDuty.

Auth that fits the box

Login, no login, or Cloudflare Access in front of the admin. GraphQL always uses tokens.

Conditions

Write checks as expressions.

Nominal evaluates them on every run and keeps the history.

[STATUS] == 200
[RESPONSE_TIME] < 400
[CERTIFICATE_EXPIRATION] > 48h
[BODY] == pat(*"ok"*)
[CONNECTED] != false

Get started

Clone it. Boot it. Watch something.

git clone https://github.com/returnearly/nominal.git
cd nominal
cp .env.example .env
php artisan key:generate
docker compose up --build

Admin is at http://localhost:8000/admin. Create a GraphQL token with php artisan nominal:token.

Open the repository Terraform provider