Multi-channel from one request
Email over SMTP or AWS SES, SMS via webhook to your gateway of choice, and an in-app inbox — all from a single send. Adding a channel is a configuration change, not an integration project.
Apache 2.0 · self-hostable
Hermes fans a single notification out across channels — with real-time delivery to the browser over WebSocket, per-user preferences, and templates you manage rather than hard-code.
curl -X POST https://hermes.example.com/v1/send \
-H "Authorization: Bearer $API_KEY" \
-d '{"to":{"user_id":"user123"},
"template":"welcome","data":{"name":"Alice"}}'
<hermes-inbox api="…" token="…" socket="…">
Transactional email, an SMS fallback, a bell icon with unread badges, a preferences page, and the plumbing to keep them consistent. Teams usually build it twice — once badly, once again under load — or hand it to a SaaS vendor along with their user data.
Hermes is that layer, built properly and run on your own infrastructure.
Email over SMTP or AWS SES, SMS via webhook to your gateway of choice, and an in-app inbox — all from a single send. Adding a channel is a configuration change, not an integration project.
Notifications appear the moment they are delivered, pushed over a WebSocket via Centrifugo. No polling, no page refresh.
Bell, badge, panel, live updates and mark-read actions ship as a standard custom element — any framework or none — with a native React binding over the same element.
Templates hold per-channel content and resolve at dispatch time with a Redis-backed cache. Categories carry default channels; a required category bypasses opt-in entirely.
Every attempt emits an event. Status only advances — pending → sent → delivered → read → archived — and terminal failures land in a dead-letter stream for inspection and replay.
No per-notification pricing, no vendor holding your recipient list. A Helm chart installs every service; a reference Terraform deployment runs it for real.
Nine Go services, NATS JetStream between each stage
01
Auth, idempotency, publish. No DB on the hot path.
02
Persists, resolves templates and channels, fans out.
03
SMTP/SES, SMS webhook, inbox push via Centrifugo.
04
Batch-inserts events, rolls status forward. Never backwards.
05
WebSocket → HTTP-streaming → polling, negotiated.
Write path — API key auth
Send is a deliberately thin ingestion layer: it authenticates the API key, applies idempotency, and publishes to NATS. Dispatch persists the notification record, resolves templates and channels, and fans out to per-channel delivery subjects.
Read path — JWT auth
Inbox Service serves the user's inbox with cursor-based pagination. User Service manages profiles and notification preferences. Centrifugo pushes live updates on user-scoped channels.
Two auth modes, kept separate
API keys, HMAC-SHA256 hashed at rest, for server-to-server Send and Admin APIs. Short-lived Hermes-issued JWTs, multi-key for rotation, for the user-facing Inbox and User APIs.
Where the two models actually differ
Get started
A Helm chart installs every service plus bundled PostgreSQL, NATS, Redis and Centrifugo, with the schema migration and stream provisioning applied automatically.
Terraform for VPC, EKS, Aurora PostgreSQL, ElastiCache and ECR — all on Graviton — with ArgoCD for GitOps sync and Kargo for staged promotion behind an operator approval.
make dev-up brings up a full local Kubernetes environment on k3d with Tilt and hot reload. Unit, integration, end-to-end and k6 load tests ship with it.
helm install hermes oci://ghcr.io/hermesnotifications/charts/hermes \
--namespace hermes --create-namespace \
--set global.domain=hermes.example.com \
--set hermes.jwt.secret="$(openssl rand -base64 32)" \
--set hermes.apiKey.hmacSecret="$(openssl rand -base64 32)"
The bundled datastores are for evaluation only; production means external datastores over TLS and the documented hardening steps.
Docs hub · API reference · integration guide · ADRs
Server SDKs, plus browser packages for the client, the React binding and the embeddable widget.
A Next.js UI for organizations, categories, templates and API keys.
hermes manages categories, templates and API keys, sends notifications, and opens an interactive TUI inbox with live updates.
$ hermes inbox --user user123
┌─ Inbox ──────────────────── ● live ─┐
│ ● api-gateway promoted 4s │
│ ● Alice invited you 2m │
│ Weekly usage report 1d │
└──── r read · a archive · q quit ────┘
$ hermes send --template welcome --to user123
queued 01J8F2… → email, inbox