Skip to content

Relay

The easiest way to connect your services to PushWard. Point webhooks at relay.pushward.app — no Docker containers, no self-hosting, no per-user configuration needed.

Supported Providers

Grafana

POST /grafana
notification

Events

  • Firing
  • Resolved (grouped by alertname)
Live Activity demonstration

Public Relay

PushWard hosts a public relay at relay.pushward.app — no deployment required. Just point your services at it with your integration key.

Example: Grafana webhook
# Grafana Contact Point URL:
https://relay.pushward.app/grafana

# HTTP Header:
Authorization: Bearer hlk_YOUR_INTEGRATION_KEY
💡 Tip

The public relay supports all 19 providers listed above. If you prefer to self-host, see the self-hosted setup further down.

How It Works

pushward-relay extracts the hlk_ integration key from each incoming webhook request. The relay infrastructure scales horizontally — one instance can serve many users concurrently. Per-user usage is bounded by your account's plan (free tier monthly quotas; unlimited on paid).

  1. Receive — external services send webhooks to provider-specific routes
  2. Authenticate — the integration key is extracted from the Authorization: Bearer hlk_... header (or Basic Auth password for Radarr/Sonarr/Prowlarr)
  3. Transform — the provider handler maps the webhook payload to a push notification or Live Activity update depending on the event type
  4. Forward — the request is sent to PushWard using the caller's integration key

Push Notifications vs Live Activities

Each provider delivers events as either a push notification (banner alert) or a Live Activity (Dynamic Island + Lock Screen), depending on the event type:

DeliveryProvidersUse case
Notification onlyGrafana, Prowlarr, BazarrOne-shot alerts — firing/resolved, health, grabs, subtitle downloads
Live Activity onlyArgoCD, Jellyfin, Uptime Kuma, Backrest, Proxmox, Overseerr, Gatus, Changedetection, Paperless, UnmanicMulti-step progress tracking (syncs, downloads, playback)
BothRadarr, SonarrGrab/Download → Live Activity; Health, Rename, Add/Delete → notification
Info

Relay requires PostgreSQL for persistent state (sync tracking, download lifecycle, playback progress across restarts and tenants). Stateless providers (Grafana, Prowlarr, Changedetection) still require a database connection to start.

Per-request overrides

Append query parameters to any provider webhook URL to override that provider's delivery behavior for a single request. This is handy when one source should behave differently from the provider default — for example forcing a noisy alert to a plain notification, or bumping a deploy's priority. An explicit parameter always wins over the provider-computed value and your static config; omitting a parameter leaves today's behavior unchanged.

ParameterValuesEffect
channelsComma-separated: activity, notificationRestricts which delivery surfaces this request may use. channels=notification suppresses Live Activities and only sends push notifications; channels=activity does the reverse. Must list at least one valid surface.
priorityInteger 0-10Sets the eviction / relevance priority for any Live Activity the request creates.
levelpassive, active, time-sensitive, criticalSets the notification interruption level for any push notification the request sends.
Force a Grafana alert to a time-sensitive notification only
https://relay.pushward.app/grafana?channels=notification&level=time-sensitive
Warning

An invalid value is rejected with 400 before the webhook is processed — an unknown channels surface, a priority that isn't an integer 0-10, or a level outside the four allowed values. Fix the URL rather than retrying.

Setup

1. Get Your Integration Key

Open the PushWard app → Settings → Integration Key to find your default hlk_ key.

To create a dedicated key for this integration:

  1. Go to Settings → Manage Keys
  2. Tap +
  3. Set name (e.g. "Relay"), choose , scope, and optionally restrict tografana-*, argocd-*
  4. Copy the generated hlk_ key

2. Self-Hosted (Optional)

If you prefer to run your own relay instance:

docker-compose.yml
services:
  pushward-relay:
    image: ghcr.io/mac-lucky/pushward-relay:latest
    ports:
      - "8090:8090"
    environment:
      PUSHWARD_URL: https://api.pushward.app
      PUSHWARD_DATABASE_DSN: postgres://user:pass@db:5432/relay?sslmode=disable
    restart: unless-stopped

  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: relay
    volumes:
      - relay-data:/var/lib/postgresql/data

volumes:
  relay-data:
💡 Tip

For Radarr, Sonarr, and Prowlarr, use Basic Auth with the hlk_ key as the password (username is ignored), since their webhook settings only support Basic Auth.

Authentication

Two patterns depending on the provider:

MethodProvidersFormat
Bearer tokenMost providersAuthorization: Bearer hlk_...
Basic AuthRadarr, Sonarr, Prowlarr, Bazarrhlk_... as password

Configuration

Environment VariableDescriptionDefault
PUSHWARD_URLPushWard server URL--
PUSHWARD_DATABASE_DSNPostgreSQL connection string--
PUSHWARD_SERVER_ADDRESSHTTP listen address:8090

Each provider can be individually enabled/disabled and configured with its own priority, cleanup delay, and stale timeout via environment variables or YAML config.