-
![](https://pfp.nostr.build/1988ca56c3d4574c5fb90298a593fdb0f5d583af0afa044b825c69fcd7686ee8.jpg)
@ Dezh Technologies
2025-01-14 13:18:51
# Abstract
In this article, we try to explain how deletion requests on the Nostr work, and how we can probably improve this using filters.
## NIP-09: Deletion Request
As you know, we can request the election of an event that we own using a kind 5 event like the below based on nip-09:
```json
{
"kind": 5,
"pubkey": "<32-bytes hex-encoded public key of the event creator>",
"tags": [
["e", "dcd59..464a2"],
["e", "968c5..ad7a4"],
["a", "<kind>:<pubkey>:<d-identifier>"],
["k", "1"],
["k", "30023"]
],
"content": "these posts were published by accident",
// other fields...
}
```
There are 2 important limitations to this model:
1. We can't request a to delete huge amount of events with complex conditions in one request since it would result in an event with a lot of tags which may some relays even reject because of the number of tags. for example, you can think of deleting all of your reactions to the posts of one of your followings.
3. There is no guarantee for a kind 5 request to be executed by all relays and clients since they can keep a copy of events json forever.
## Deletion Using Filters
Based on issues that we had with the old model used in nip-09 we tried to find different ways to fix them. Deletion using filter i is a new model that tries to fix the first issue. The third issue is still under research.
Nostr utilizes a query model called `filter` to query events that can be checked and matched with an event and receive only 2 results that are matched and not matched. So, we can define a structure that can be matched with any number of events.
We define a new tag called `filter` which contains a stringified Nostr filter. Using this tag, we construct a kind 5 event that requests the deletion of all events matching with that event. Here is an example:
```json
{
"kind": 5,
"pubkey": "aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c",
"tags": [
["filter", "{\n \"authors\": [\"aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c\"],\n \"kinds\": [7],\n \"#p\": \"aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c\",\n \"since\": 0,\n \"until\": 2147483647,\n}"]
],
"content": "i don't want to be selfish anymore.",
// other fields...
}
```
In this example, [`aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c`](https://njump.me/example@dezh.tech) public key requests to delete all of their reactions on their on events.
Or using the example below, you can request account deletion:
```json
{
"kind": 5,
"pubkey": "aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c",
"tags": [
["filter", "{\n \"authors\": [\"aca682c51c44c9046461de0cb34bcc6338d5562cdf9062aee9c3ca5a4ca0ab3c\"],\n}"]
],
"content": "use my new pubkey: cc6...a0a.",
// other fields...
}
```
### Filter Limitations and Details
Here is a list of limitations and considerations for those who are using the `filter` tag on kind 5:
1. `authors`: This field must be implicit and it MUST always contain one pubkey which is the pubkey of the deletion author. Some relays MAY accept multiple pubkeys from moderators events. (but it's RECOMMENDED for it to be applied from nip-86 management API, [gRPC API](https://docs.dezh.tech/docs/immortal/managment/apis), or anything used for managing relay.)
2. `limit`: This field MUST be ignored since the limit selection can be different in the relay/client internal system.
3. `search`: A relay **MAY** support NIP-50 `search` for this purpose.
4. `until/since`: These fields would be used instead of the event `created_at` for time. But relay MAY follow any of the below behaviors:
4.1. They only let pubkeys request the deletion of old events, not future events and consider the `since` field.
4.2 They MAY keep a list of deleted filters in a hashmap with `pubkey` as the key to check any incoming event with the filter and they can drop the filer once we pass the `until`. this would be an expensive action to accept kind 5 from all pubkeys, relays MAY charge some fee or require some amount of work to accept kind 5 in this case.
Thanks [mike@mikedilger.com](https://njump.me/mike@mikedilger.com) for sharing his ideas on [this PR](https://github.com/nostr-protocol/nips/pull/1509#issuecomment-2587967823).
### Uses cases
Here is a small list of use cases for this model:
1. Account Deletion Request: a pubkey can request for deletion of their account.
2. Bulk Remove: Chat clients for example can support the selection of multiple messages and requests for deletion.
3. Force Limit: The Relays that keep the filter using the `until` field can be used by a pubkey to force the relay to not accept a specific event matching that filter for a specific time.
## Final Words
This standard is currently in beta version, not merged in the [nips](https://github.com/nostr-protocol/nips) repo, and it is implemented and supported in the [Immortal](https://github.com/dezh-tech/immortal) relay.
1. [Open PR on NIPs](https://github.com/nostr-protocol/nips/pull/1509).
2. [Example implementation in Golang](https://github.com/dezh-tech/immortal/pull/110).