|
|
@@ -946,19 +946,24 @@ _Supported on:_ :material-android: :material-firefox:
|
|
|
You can **update, clear (mark as read and dismiss), or delete notifications** that have already been delivered. This is useful for scenarios
|
|
|
like download progress updates, replacing outdated information, or dismissing notifications that are no longer relevant.
|
|
|
|
|
|
-* Updating notifications will alter the content of an existing notification.
|
|
|
-* Clearing notifications will mark them as read and dismiss them from the notification drawer.
|
|
|
-* Deleting notifications will remove them from the notification drawer and remove them in the clients as well (if supported).
|
|
|
+* [Updating notifications](#updating-notifications) will alter the content of an existing notification.
|
|
|
+* [Clearing notifications](#clearing-notifications) will mark them as read and dismiss them from the notification drawer.
|
|
|
+* [Deleting notifications](#deleting-notifications) will remove them from the notification drawer and remove them in the clients as well (if supported).
|
|
|
|
|
|
-The way this works is that when you publish a message with a specific **sequence ID**, clients that receive the
|
|
|
-notification will treat it as part of a sequence. When a new message with the same sequence ID is published, clients
|
|
|
-will update the existing notification instead of creating a new one. You can also
|
|
|
+Here's an example of a download progress notification being updated over time on Android:
|
|
|
|
|
|
<div id="updating-notifications-screenshots" class="screenshots">
|
|
|
<a href="../../static/img/android-screenshot-notification-update-1.png"><img src="../../static/img/android-screenshot-notification-update-1.png"/></a>
|
|
|
<a href="../../static/img/android-screenshot-notification-update-2.png"><img src="../../static/img/android-screenshot-notification-update-2.png"/></a>
|
|
|
</div>
|
|
|
|
|
|
+To facilitate updating notifications and altering existing notifications, ntfy messages are linked together in a sequence,
|
|
|
+using a **sequence ID**. When a notification is meant to be updated, cleared, or deleted, you publish a new message with the
|
|
|
+same sequence ID and the clients will perform the appropriate action on the existing notification.
|
|
|
+
|
|
|
+Existing ntfy messages will not be updated on the server or in the message cache. Instead, a new message is created that indicates
|
|
|
+the update, clear, or delete action. This append-only behavior ensures that message history remains intact.
|
|
|
+
|
|
|
### Updating notifications
|
|
|
To update an existing notification, publish a new message with the same sequence ID. Clients will replace the previous
|
|
|
notification with the new one. You can either:
|
|
|
@@ -968,7 +973,7 @@ notification with the new one. You can either:
|
|
|
`X-Sequence-ID` header (or any of its aliases: `Sequence-ID` or`SID`)
|
|
|
|
|
|
If you don't know the sequence ID ahead of time, you can publish a message first and then use the returned
|
|
|
-message `id` to update it. The message ID of the first message will then serve as the sequence ID for subsequent updates:
|
|
|
+message `id` to update it. Here's an example:
|
|
|
|
|
|
=== "Command line (curl)"
|
|
|
```bash
|
|
|
@@ -1115,8 +1120,8 @@ message `id` to update it. The message ID of the first message will then serve a
|
|
|
]));
|
|
|
```
|
|
|
|
|
|
-You can also use a custom sequence ID (e.g., a download ID, job ID, etc.) when publishing the first message. This is
|
|
|
-less cumbersome, since you don't need to capture the message ID first. Just publish directly to
|
|
|
+You can also use a **custom sequence ID** (e.g., a download ID, job ID, etc.) when publishing the first message.
|
|
|
+**This is less cumbersome**, since you don't need to capture the message ID first. Just publish directly to
|
|
|
`/<topic>/<sequence_id>`:
|
|
|
|
|
|
=== "Command line (curl)"
|
|
|
@@ -1145,12 +1150,13 @@ less cumbersome, since you don't need to capture the message ID first. Just publ
|
|
|
|
|
|
=== "HTTP"
|
|
|
``` http
|
|
|
+ # Publish a message with a custom sequence ID
|
|
|
POST /mytopic/my-download-123 HTTP/1.1
|
|
|
Host: ntfy.sh
|
|
|
|
|
|
Downloading file...
|
|
|
- ```
|
|
|
- ``` http
|
|
|
+
|
|
|
+ # Update again using the X-Sequence-ID header
|
|
|
POST /mytopic HTTP/1.1
|
|
|
Host: ntfy.sh
|
|
|
X-Sequence-ID: my-download-123
|
|
|
@@ -1247,12 +1253,24 @@ less cumbersome, since you don't need to capture the message ID first. Just publ
|
|
|
]));
|
|
|
```
|
|
|
|
|
|
-You can also set the sequence ID via the `sid` query parameter, or when [publishing as JSON](#publish-as-json)
|
|
|
-using the `sequence_id` field.
|
|
|
+You can also set the sequence ID via the `sequence-id` [query parameter](#list-of-all-parameters), or when
|
|
|
+[publishing as JSON](#publish-as-json) using the `sequence_id` field.
|
|
|
+
|
|
|
+If the message ID (`id`) and the sequence ID (`sequence_id`) are different, the ntfy server will include the `sequence_id`
|
|
|
+field the response. A sequence of updates may look like this (first example from above):
|
|
|
+
|
|
|
+```json
|
|
|
+{"id":"xE73Iyuabi","time":1673542291,"event":"message","topic":"mytopic","message":"Downloading file..."}
|
|
|
+{"id":"yF84Jzvbcj","time":1673542295,"event":"message","topic":"mytopic","sequence_id":"xE73Iyuabi","message":"Download 50% ..."}
|
|
|
+{"id":"zG95Kawdde","time":1673542300,"event":"message","topic":"mytopic","sequence_id":"xE73Iyuabi","message":"Download complete"}
|
|
|
+```
|
|
|
|
|
|
### Clearing notifications
|
|
|
-To clear a notification (mark it as read and dismiss it from the notification drawer), send a PUT request to
|
|
|
-`/<topic>/<sequence_id>/clear` (or `/<topic>/<sequence_id>/read` as an alias):
|
|
|
+Clearing a notification means **marking it as read and dismissing it from the notification drawer**.
|
|
|
+
|
|
|
+To do this, send a PUT request to the `/<topic>/<sequence_id>/clear` endpoint (or `/<topic>/<sequence_id>/read` as an alias).
|
|
|
+This will then emit a `message_clear` event that is used by the clients (web app and Android app) to update the read status
|
|
|
+and dismiss the notification.
|
|
|
|
|
|
=== "Command line (curl)"
|
|
|
```bash
|
|
|
@@ -1295,13 +1313,17 @@ To clear a notification (mark it as read and dismiss it from the notification dr
|
|
|
]));
|
|
|
```
|
|
|
|
|
|
-This publishes a `message_clear` event, which tells clients to:
|
|
|
+An example response from the server with the `message_clear` event may look like this:
|
|
|
|
|
|
-- Mark the notification as read in the app
|
|
|
-- Dismiss the browser/Android notification
|
|
|
+```json
|
|
|
+{"id":"jkl012","time":1673542305,"event":"message_clear","topic":"mytopic","sequence_id":"my-download-123"}
|
|
|
+```
|
|
|
|
|
|
### Deleting notifications
|
|
|
-To delete a notification entirely, send a DELETE request to `/<topic>/<sequence_id>`:
|
|
|
+Deleting a notification means **removing it from the notification drawer and from the client's database**.
|
|
|
+
|
|
|
+To do this, send a DELETE request to the `/<topic>/<sequence_id>` endpoint. This will emit a `message_delete` event
|
|
|
+that is used by the clients (web app and Android app) to remove the notification entirely.
|
|
|
|
|
|
=== "Command line (curl)"
|
|
|
```bash
|
|
|
@@ -1344,51 +1366,16 @@ To delete a notification entirely, send a DELETE request to `/<topic>/<sequence_
|
|
|
]));
|
|
|
```
|
|
|
|
|
|
-This publishes a `message_delete` event, which tells clients to:
|
|
|
+An example response from the server with the `message_delete` event may look like this:
|
|
|
|
|
|
-- Delete the notification from the database
|
|
|
-- Dismiss the browser/Android notification
|
|
|
+```json
|
|
|
+{"id":"mno345","time":1673542400,"event":"message_delete","topic":"mytopic","sequence_id":"my-download-123"}
|
|
|
+```
|
|
|
|
|
|
!!! info
|
|
|
Deleted sequences can be revived by publishing a new message with the same sequence ID. The notification will
|
|
|
reappear as a new message.
|
|
|
|
|
|
-### Full example
|
|
|
-Here's a complete example showing the lifecycle of a notification with updates, clearing, and deletion:
|
|
|
-
|
|
|
-```bash
|
|
|
-# 1. Create a notification with a custom sequence ID
|
|
|
-$ curl -d "Starting backup..." ntfy.sh/mytopic/backup-2024
|
|
|
-
|
|
|
-# 2. Update the notification with progress
|
|
|
-$ curl -d "Backup 50% complete..." ntfy.sh/mytopic/backup-2024
|
|
|
-
|
|
|
-# 3. Update again when complete
|
|
|
-$ curl -d "Backup finished successfully!" ntfy.sh/mytopic/backup-2024
|
|
|
-
|
|
|
-# 4. Clear the notification (dismiss from notification drawer)
|
|
|
-$ curl -X PUT ntfy.sh/mytopic/backup-2024/clear
|
|
|
-
|
|
|
-# 5. Later, delete the notification entirely
|
|
|
-$ curl -X DELETE ntfy.sh/mytopic/backup-2024
|
|
|
-```
|
|
|
-
|
|
|
-When polling the topic, you'll see the complete sequence of events:
|
|
|
-
|
|
|
-```bash
|
|
|
-$ curl -s "ntfy.sh/mytopic/json?poll=1&since=all" | jq .
|
|
|
-```
|
|
|
-
|
|
|
-```json
|
|
|
-{"id":"abc123","time":1673542291,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Starting backup..."}
|
|
|
-{"id":"def456","time":1673542295,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Backup 50% complete..."}
|
|
|
-{"id":"ghi789","time":1673542300,"event":"message","topic":"mytopic","sequence_id":"backup-2024","message":"Backup finished successfully!"}
|
|
|
-{"id":"jkl012","time":1673542305,"event":"message_clear","topic":"mytopic","sequence_id":"backup-2024"}
|
|
|
-{"id":"mno345","time":1673542400,"event":"message_delete","topic":"mytopic","sequence_id":"backup-2024"}
|
|
|
-```
|
|
|
-
|
|
|
-Clients process these events in order, keeping only the latest state for each sequence ID.
|
|
|
-
|
|
|
## Message templating
|
|
|
_Supported on:_ :material-android: :material-apple: :material-firefox:
|
|
|
|
|
|
@@ -4384,6 +4371,7 @@ table in their canonical form.
|
|
|
|-----------------|--------------------------------------------|-----------------------------------------------------------------------------------------------|
|
|
|
| `X-Message` | `Message`, `m` | Main body of the message as shown in the notification |
|
|
|
| `X-Title` | `Title`, `t` | [Message title](#message-title) |
|
|
|
+| `X-Sequence-ID` | `Sequence-ID`, `SID` | [Sequence ID](#updating-deleting-notifications) for updating/clearing/deleting notifications |
|
|
|
| `X-Priority` | `Priority`, `prio`, `p` | [Message priority](#message-priority) |
|
|
|
| `X-Tags` | `Tags`, `Tag`, `ta` | [Tags and emojis](#tags-emojis) |
|
|
|
| `X-Delay` | `Delay`, `X-At`, `At`, `X-In`, `In` | Timestamp or duration for [delayed delivery](#scheduled-delivery) |
|