Skip to content

Self-hosted notification router, written in Rust

Every event, to whoever needs to know.

Your services send events to one HTTP endpoint. Routes decide who is told, on which channel and how often: duplicates are counted instead of repeated, bursts are grouped into one message, and what nobody acknowledges is escalated.

  • One binary
  • SQLite or Postgres
  • Web UI built in
  • AGPLv3
The ramzes overview: events received by severity over the last day, the share of deliveries that arrived, and the noisiest sources and topics.The ramzes overview: events received by severity over the last day, the share of deliveries that arrived, and the noisiest sources and topics.

How it works

Three steps, each of which you can look at afterwards.

  1. Send

    A service posts JSON to /v1/events with a source key. Alertmanager, Grafana, GitHub, GitLab and Sentry post their own webhooks to a source address instead, and any other JSON is mapped in the app.

    Sending events
  2. Route

    Routes are checked in order. A route that matches opens a notification for each of its targets, and its policy decides whether that is sent now, counted, grouped or held.

    Routes
  3. Deliver

    The message goes to Slack, Teams, Discord, email, a pager, a phone or any URL, and is retried until it arrives. Each attempt is recorded where you can see it.

    Channels
curl -X POST http://localhost:7269/v1/events \
  -H "Authorization: Bearer <source key>" \
  -H "Content-Type: application/json" \
  -d '{"topic": "orders.failed", "title": "Order 7 failed", "severity": "error"}'

What it does

ramzes sits between the things that notice a problem and the people who should hear about it.

From anything, to anywhere

Formats follow each service's documentation and are pinned by tests. None has been run against the live service yet; the page of verified claims says exactly what was checked.

What was verified, and how

Run it yourself

One container with a built-in database, built from a checkout of the repository. The setup screen takes you from an empty instance to a message in your channel.

docker compose -f deploy/compose.yaml up --build