Self-hosted on-call scheduling, alert routing, alert delivery, reminders, and escalations for teams that want control over their incident workflow.
IncidentRelay helps SRE, DevOps, platform, infrastructure, and operations teams route alerts to the right people through the right channels without depending on a hosted incident-management platform.
It provides the core building blocks of an on-call system:
- access groups and RBAC-style group roles;
- teams and on-call rotations;
- alert intake routes with per-route tokens;
- Alertmanager, Zabbix, and generic webhook integrations;
- Mattermost, Slack, Telegram, Discord, Microsoft Teams, email, webhook, and voice-call notifications;
- acknowledge and resolve workflows;
- reminders and escalation to the next on-call user;
- rotation overrides;
- alert silences;
- calendar view for on-call schedules;
- personal API tokens;
- Swagger/OpenAPI documentation.
IncidentRelay is designed for self-hosted environments where teams need predictable behavior, clear ownership, easy integrations, and full control over alert routing.
Many teams need on-call routing, but do not always need a large SaaS incident platform.
IncidentRelay focuses on the practical workflow:
Monitoring system -> Route -> Team -> Rotation -> Notification channels -> ACK / Resolve
A route owns its own intake token, so external systems send alerts to an exact alert path:
ROUTE_INTAKE_TOKEN -> Route -> Team -> Rotation -> Channels
Channels only describe where notifications are delivered. Routes decide which team receives the alert and which channels are used.
This keeps alert delivery easier to reason about, easier to audit, and safer for self-hosted deployments.
Run IncidentRelay in your own environment, with your own database, your own network rules, and your own operational policies.
Alert intake tokens belong to routes, not channels. This makes it clear which incoming integration is allowed to submit alerts to which team and rotation.
Use groups as access boundaries. Teams, rotations, routes, channels, alerts, and silences are scoped through groups and memberships.
Unacknowledged alerts can trigger repeated reminders and then escalate to the next on-call user according to the team configuration.
Mattermost Bot API mode supports interactive Acknowledge and Resolve buttons, message updates, and severity-based attachment colors.
Telegram notifications can include action buttons and alert links. Telegram callback/polling processing is handled by the optional incidentrelay-telegram-worker service.
IncidentRelay can be extended with custom voice providers for self-hosted installations. Providers can implement text-to-speech calls, call status callbacks, DTMF button callbacks, ACK / Resolve actions from phone keypad, and optional call status polling.
IncidentRelay includes Swagger/OpenAPI documentation and personal API tokens with scopes for alerts, resources, and profile access.
| Source | Endpoint |
|---|---|
| Alertmanager | POST /api/integrations/alertmanager |
| Zabbix | POST /api/integrations/zabbix |
| Generic webhook | POST /api/integrations/webhook |
| Channel | Notes |
|---|---|
| Mattermost | Incoming webhook mode or Bot API mode with buttons and updates |
| Slack | Webhook notifications |
| Telegram | Bot notifications and optional action buttons |
| Discord | Webhook notifications |
| Microsoft Teams | Webhook notifications |
| Email recipients | |
| Webhook | Generic outbound webhook |
| Voice call | Pluggable provider API for self-hosted voice integrations |
Choose the installation method that matches your environment.
Recommended for quick start, testing, and simple self-hosted deployments.
docker compose up -d --buildWith PostgreSQL:
docker compose \
-f docker-compose.yml \
-f docker-compose.postgres.yml \
up -dRead more: Docker installation
Recommended for RHEL, Rocky Linux, AlmaLinux, and CentOS Stream.
sudo dnf install -y curl
sudo curl -fsSL \
https://repo.incidentrelay.io/incidentrelay.repo \
-o /etc/yum.repos.d/incidentrelay.repo
sudo dnf makecache
sudo dnf install -y incidentrelayFor older yum-based systems:
sudo yum install -y curl
sudo curl -fsSL \
https://repo.incidentrelay.io/incidentrelay.repo \
-o /etc/yum.repos.d/incidentrelay.repo
sudo yum makecache
sudo yum install -y incidentrelayRead more: RedHat RPM installation
Recommended when you want to run IncidentRelay directly from source code or manage the Python environment manually.
Read more: Systemd installation
Common paths used by the RPM and systemd installation:
/var/www/incidentrelay # application code
/var/www/incidentrelay/venv # Python environment or venv-compatible wrapper
/etc/incidentrelay/incidentrelay.conf # main configuration file
/var/lib/incidentrelay # runtime data
/var/log/incidentrelay # logs
/usr/local/lib/incidentrelay/voice_providers # custom voice providers
Systemd services:
incidentrelay-web.service # HTTP API, UI, webhooks
incidentrelay-scheduler.service # reminders, escalations, periodic jobs
incidentrelay-telegram-worker.service # optional Telegram callbacks/polling
System user:
incidentrelay
IncidentRelay reads the configuration file path from:
INCEDENTRELAY_CONFIG_FILE
Example:
export INCEDENTRELAY_CONFIG_FILE=/etc/incidentrelay/incidentrelay.confFor production, set the public URL used for generated links and callback URLs:
[server]
public_base_url = https://incidentrelay.example.comSQLite is suitable for small single-node installations:
[database]
type = sqlite
path = /var/lib/incidentrelay/incidentrelay.dbPostgreSQL is recommended for larger or long-running production installations:
[database]
type = postgresql
host = 127.0.0.1
port = 5432
name = incidentrelay
user = incidentrelay
password = change-meRead more: Configuration
After installation, initialize the database and create the first administrator.
For RPM/systemd installations:
sudo -u incidentrelay \
INCEDENTRELAY_CONFIG_FILE=/etc/incidentrelay/incidentrelay.conf \
/var/www/incidentrelay/venv/bin/python \
/var/www/incidentrelay/manage.py migrateFor Docker installations:
docker compose exec incidentrelay-web \
python manage.py migrateFor RPM/systemd installations:
sudo -u incidentrelay \
INCEDENTRELAY_CONFIG_FILE=/etc/incidentrelay/incidentrelay.conf \
/var/www/incidentrelay/venv/bin/python \
/var/www/incidentrelay/manage.py create-admin \
--username admin \
--password 'change-me-123' \
--email admin@example.comFor Docker installations:
docker compose exec incidentrelay-web \
python manage.py create-admin \
--username admin \
--password 'change-me-123' \
--email admin@example.comChange the password and email before using these commands in production.
After the first login:
1. Create a group
2. Create users
3. Add users to the group
4. Create a team
5. Add users to the team
6. Create a rotation
7. Add rotation members
8. Create notification channels
9. Create a route
10. Copy the route intake token
11. Configure Alertmanager, Zabbix, or webhook sender
12. Send a test alert
13. Acknowledge or resolve the alert
Detailed guide: First login and initial setup
curl -X POST http://127.0.0.1:8080/api/integrations/alertmanager \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ALERTMANAGER_ROUTE_TOKEN' \
-d '{
"status": "firing",
"alerts": [
{
"status": "firing",
"labels": {
"alertname": "DiskFull",
"severity": "critical",
"team": "infra",
"instance": "host1"
},
"annotations": {
"summary": "Disk is full",
"description": "/var is 95% full"
},
"fingerprint": "disk-full-host1-var"
}
]
}'More examples:
Mattermost has two modes.
Incoming webhook mode sends plain messages only.
Bot API mode is recommended when you want:
Acknowledgebutton;Resolvebutton;- message updates after ACK / Resolve;
- severity-based colors.
More details: Mattermost integration
IncidentRelay supports custom voice providers for self-hosted installations.
A provider is a Python module that can be placed into:
/usr/local/lib/incidentrelay/voice_providers
Custom providers can implement:
- text-to-speech call creation;
- provider call ID tracking;
- call status callbacks;
- DTMF button callbacks;
- ACK / Resolve actions from phone keypad;
- optional call status polling.
Start here:
- Custom Voice Providers
- Provider API
- Configuration
- Callbacks and DTMF
- Security
- Troubleshooting
- Example providers
Swagger UI is available at:
/docs
OpenAPI JSON is available at:
/api/openapi.json
Create demo data:
python manage.py demo-dataThe command creates demo groups, users, teams, rotations, channels, routes, and route intake tokens.
Static demo-data check:
python app/check_demo_data.pyMore details: Demo data
After running migrations, verify that all Peewee model tables and columns exist in the configured database:
python app/check_schema.pyExpected output:
Schema check OK: all model tables and columns exist.
More details: Schema check
If an alert is not visible or not delivered:
1. Check that the correct route intake token was used.
2. Check that the endpoint matches the route source.
3. Check that route matchers match alert labels.
4. Check that the group is active.
5. Check that the team is active.
6. Check that the UI active group is correct.
7. Select "All my groups" and reload the Alerts page.
8. Check routing_error in the integration response.
9. Check JSON logs by error_id if the server returned one.
More details: Troubleshooting
See LICENSE.