Files
Notizarr/docs/migration-ntfy.md
T
2026-09-07 09:54:30 +00:00

4.6 KiB

Migrating from ntfy

Notizarr's ingestion listener (:8081) accepts ntfy-style publish requests at POST /:topic, so most existing ntfy integrations only need a URL and an auth header changed — not a rewrite. This isn't a full ntfy protocol clone (see What's different below); it covers the parts of ntfy that are actually used for publishing a message.

Quick reference

ntfy Notizarr
https://ntfy.sh/mytopic http://<lan-ip>:8081/mytopic
No auth, or ntfy access tokens Authorization: Bearer nzr_... (create one in Admin → API Tokens)
Title: header Title: header — same
Priority: header Accepted, stored, min/1 skips push — see Priority
Tags: header Not mapped yet — see What's different
Click: header Click: header — same, becomes the notification's link
Attach: header Attach: header — same, treated as an image URL
Filename: header Filename: header — stored as metadata
plain-text body plain-text body — same, becomes the message
JSON publish ({"topic", "message", ...}) JSON publish — same shape, topic comes from the URL path instead
Query params (?title=...) Query params — same

Before / after examples

Plain curl, ntfy:

curl -H "Title: Backup finished" -d "Backup completed successfully" ntfy.sh/mytopic

Plain curl, Notizarr:

curl -H "Title: Backup finished" \
     -H "Authorization: Bearer nzr_your_token_here" \
     -d "Backup completed successfully" \
     http://<lan-ip>:8081/mytopic

The only changes: the host/port, and adding the Authorization header. If you were using ntfy's optional access tokens, this direction is the same — you're just switching to a Notizarr-issued token with real per-service scoping instead.

JSON publish, ntfy:

curl ntfy.sh -d '{"topic":"mytopic","title":"Backup finished","message":"Backup completed successfully","click":"https://backups.example.com"}'

JSON publish, Notizarr:

curl -H "Authorization: Bearer nzr_your_token_here" \
     -d '{"topic":"mytopic","title":"Backup finished","message":"Backup completed successfully","click":"https://backups.example.com"}' \
     http://<lan-ip>:8081/mytopic

Same JSON body. topic in the body is redundant with the URL path but harmless if you leave it — Notizarr always takes the topic from the path on this endpoint.

Getting a token

  1. Log into Notizarr as an admin.
  2. Settings → Admin → API Tokens → Create token.
  3. Give it a name matching the service (e.g. "Gitea", "Uptime Kuma").
  4. Copy the nzr_... value immediately — it's shown once.
  5. Optionally scope it to specific topics under "Restrict topics" so a leaked token from one integration can't publish everywhere.

What's different

Deliberately not replicated, because the goal is easy migration, not a full protocol clone (and some of these are explicit non-goals — see docs/phase1/00-README.md):

  • Priority. ntfy's priority levels (min/low/default/high/urgent, or 1-5) are accepted and stored on the notification. Only min/1 changes delivery: that notification is skipped during push fan-out (still stored and shown in-app), so a single noisy sender can be silenced without a separate topic. The other levels are accepted but don't yet change anything further (no sound/vibration mapping, no urgent-bypasses-DND). Whether a topic pushes at all otherwise is controlled by that topic's push ON/OFF setting — see docs/phase1/04-api-design.md.
  • Tags/emoji. ntfy's Tags: header (e.g. warning,skull) isn't parsed into emoji prefixes. If you want an emoji in the title, put it directly in the Title: header or JSON title field, same as ntfy's own emoji-in-title convention.
  • Attachments. Attach: is treated as an image URL the browser loads directly — there's no server-side download, proxying, or file upload. This is a deliberate security choice (see the SSRF section of docs/phase1/02-threat-model.md), not a temporary gap.
  • Auth is required by default. Unlike a bare ntfy instance, publishing always needs a valid Authorization: Bearer token — there's no anonymous-publish mode.

Home Assistant, Seerr, Uptime Kuma, and other services

See docs/home-assistant.md for a worked Home Assistant example (replacing ntfy.publish) and equivalent webhook configurations for Seerr, Uptime Kuma, and any service with a generic webhook option.