1 Overview
Nostr events are signed and, once published, copies can spread to many relays and many clients. A user cannot reach into every copy and erase it. NIP-09 gives the user a formal way to ask.
The author of an event publishes a second event, kind 5, that lists the events to remove. This is the deletion request. Relays that see it and already store the listed events should stop serving those events. Clients that see it should hide the listed events, or mark them as disowned by their author.
A deletion request only works against events made by the same author. Nobody can delete another user's event this way. Nothing in this NIP forces every relay or every client to comply. Some relays keep no history; some clients ignore deletion requests entirely. Deletion is best-effort, not enforcement.
This NIP depends on NIP-01 for the event object, the e/a tag shapes, and the idea of an addressable event. Read that chapter first if the terms below look unfamiliar.
2 The Deletion Request Event
Kind 5 marks an event as a deletion request. It must carry one or more e or a tags, each pointing at an event the author wants deleted. Deletion requests should also carry one k tag per referenced event, giving that event's kind.
The content field may hold a plain-text note that explains the reason for the request. This field is optional. An empty string is valid.
{
"kind": 5
"pubkey": <32-byte hex pubkey 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"
// id, created_at, sig: same rules as every event, see NIP-01
}
| Kind | Name | Rule |
|---|---|---|
| 5 | Deletion Request | Content of a deletion request event. A regular event under the NIP-01 kind-range convention, so relays are expected to store it, not just the events it targets. |
3 Tags
NIP-09 uses three tags. All three follow the general tag shape defined in NIP-01.
| Tag | Requirement | Shape | Meaning |
|---|---|---|---|
| e | required, unless using a | ["e", <event id>] | Requests deletion of one regular event, by its exact id. |
| a | required, unless using e | ["a", "<kind>:<pubkey>:<d-identifier>"] | Requests deletion of an addressable or replaceable event, by its coordinate. |
| k | should include, one per referenced event | ["k", "<kind>"] | States the kind of the matching e or a tagged event. Lets a relay or client sort deletions without loading each target first. |
A deletion request lists one or more targets. Use as many e, a, and k tags as needed in a single kind-5 event; there is no rule against combining unrelated deletions in one request.
4 Relay Behavior
- A relay should delete, or stop publishing, any event referenced by an
etag when that event'spubkeyis identical to the deletion request'spubkey. - A relay should keep publishing and sharing the deletion request event itself, indefinitely. Other clients and relays may not yet have the event it targets, and they need the deletion request to catch up later.
- When an
atag is used, a relay should delete every stored version of that addressable or replaceable event with acreated_atat or before the deletion request's owncreated_at. - A relay may check that a deletion request only references events sharing its own
pubkey, but this check is not required. A relay does not always hold every referenced event, so it cannot always perform the check.
The source spec never explicitly restates the pubkey-match rule for a tags the way it does for e tags. In practice the match is implicit: the pubkey segment inside an a tag's coordinate is already part of the address, so a relay comparing it to the deletion request's pubkey is applying the same rule, just read from a different place in the tag. Because the rule is only spelled out for e tags, implementers should not assume every relay applies it consistently to a tags too.
5 Client Behavior
A client may fully hide any event referenced by a valid deletion request: text notes, direct messages, and any other kind. Alternatively, a client may keep showing the event with an icon or notice that the author has disowned it.
A client may use the deletion request's content to replace the display of the deleted event's own content. If it does, the interface must make clear that the text shown is the deletion reason, not the original content.
A client displays the deletion request event itself however it chooses — not at all, or with a prominent notice.
A client may tell the user that requesting deletion does not guarantee removal. Some relays and clients already hold a copy and may never see, or may ignore, the request.
A client must check every e-tagged event's pubkey against the deletion request's own pubkey before hiding or deleting it. Relays cannot be trusted to have done this already; a relay may not even hold the referenced event to check.
6 Deletion Request of a Deletion Request
Publishing a deletion request that targets another deletion request has no effect. Clients and relays are not required to support "un-requesting" a deletion.
Once a user sends kind:5, treat that request as final. There is no standard way to withdraw it.
7 Worked Example
Below, a user publishes a text note, then decides to delete it along with an old long-form article. Orange lines go to the relay. Blue lines come from the relay.
-- publish the original note -- → ["EVENT", {"id":"dcd59a1b…464a2","pubkey":"3bf0c63f…","kind":1, "created_at":1749700000,"tags":[],"content":"gm nostr","sig":"7ac1…"}] ← ["OK", "dcd59a1b…464a2", true, ""] -- publish an addressable long-form article, d = "draft-1" -- → ["EVENT", {"id":"968c5a2e…ad7a4","pubkey":"3bf0c63f…","kind":30023, "created_at":1749700500,"tags":[["d","draft-1"]],"content":"# early draft","sig":"91fe…"}] ← ["OK", "968c5a2e…ad7a4", true, ""] -- the author changes their mind and deletes both -- → ["EVENT", {"id":"a10f77c2…e55b1","pubkey":"3bf0c63f…","kind":5, "created_at":1749762600, "tags":[ ["e","dcd59a1b…464a2"], ["a","30023:3bf0c63f…:draft-1"], ["k","1"], ["k","30023"] ], "content":"these posts were published by accident","sig":"c02a…"}] ← ["OK", "a10f77c2…e55b1", true, ""] -- a second client asks for the deleted note -- → ["REQ", "check", {"ids":["dcd59a1b…464a2"]}] ← ["EOSE", "check"] -- no EVENT was sent: the relay honored the deletion request -- -- the client also fetches the deletion request itself, to explain the gap -- → ["REQ", "why", {"kinds":[5], "authors":["3bf0c63f…"]}] ← ["EVENT", "why", {"kind":5, "content":"these posts were published by accident", …}] ← ["EOSE", "why"] -- attacker tries to delete someone else's note; client must reject it locally -- ← ["EVENT", "feed", {"id":"badreq1…","pubkey":"eeeeeeee…","kind":5, "tags":[["e","dcd59a1b…464a2"]], "content":"", …}] // client compares pubkeys: eeeeeeee… != 3bf0c63f… (the note's real author) // client ignores this deletion request; the note stays visible
8 Version History
NIP-09 grew from a single-tag "delete this event" note into a multi-tag request covering addressable events. Notable changes, newest first:
- 20262026-06Code fence style changed from
jsonctoyamlacross the manual; no rule change. - 20252025-12Added the
relaytag to the spec header, marking this NIP as relevant to relay operators (#2173). - 20242024-08Renamed the event from "deletion" to "retraction" for one day, then settled on "deletion request", the name used today.
- 20242024-07Added the optional
ktag, so a request can state the kind of each referenced event. - 20242024-06Clarified that an
a-tag deletion covers every version of the addressable event up to the request's own timestamp. - 20232023-11Removed a stale reference to NIP-33 after its addressable-event rules merged into NIP-01.
- 20232023-06Added the
atag, extending deletion requests to addressable and replaceable events (#600). - 20232023-04General wording fixes and small clarifications to the spec text.
- 20222022-11Strengthened the relay-side wording: relays should actively stop serving deleted events, not merely tolerate the request.
- Origin2022-05-01fiatjaf migrated the NIP, defining kind 5 with
e-tag deletion requests.
Original Proposal - Credits
| Author | fiatjaf |
| First commit | 2022-05-01 — “migrate nips from main nostr repo” (spec predates the repository) |
| Status | draft - optional — relays and clients may implement it |
| Source | 09.md on GitHub - full change history |
9 See Also
- NIP-01 — the event object,
e/atag shapes, and addressable/replaceable events referenced throughout this chapter. - NIP-33 — the earlier home of addressable events, before that content merged into NIP-01; the
atag here targets what that NIP defined. - NIP-40 — expiration timestamps, a second way to make an event disappear, set in advance instead of requested afterward.
- NIP-62 — Request to Vanish, a stronger, account-wide relay request to erase everything from a pubkey.