# 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](#whats-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://: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](#priority) | | `Tags:` header | Not mapped yet — see [What's different](#whats-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:** ```bash curl -H "Title: Backup finished" -d "Backup completed successfully" ntfy.sh/mytopic ``` **Plain curl, Notizarr:** ```bash curl -H "Title: Backup finished" \ -H "Authorization: Bearer nzr_your_token_here" \ -d "Backup completed successfully" \ http://: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:** ```bash curl ntfy.sh -d '{"topic":"mytopic","title":"Backup finished","message":"Backup completed successfully","click":"https://backups.example.com"}' ``` **JSON publish, Notizarr:** ```bash curl -H "Authorization: Bearer nzr_your_token_here" \ -d '{"topic":"mytopic","title":"Backup finished","message":"Backup completed successfully","click":"https://backups.example.com"}' \ http://: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](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](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](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](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.