Chapter 56 - Moderation
56
Nostr Implementation Possibility - Hex № 56

Reporting

A signed flag on the wire: kind 1984 events let users report objectionable profiles, notes, and files — and let everyone else decide what to do about it.

1 Overview

A report is a kind 1984 event. It signals to users and relays that some referenced content is objectionable. The report names a target: a user, a note, or a file blob. It also names a reason, called the report type.

The definition of objectionable is subjective. This NIP does not define it. Every agent on the network — users, apps, relays — may consume reports and act on them as it sees fit. A report is advice, not a command. No relay must delete anything. No client must hide anything.

Reports are ordinary signed events. Anyone can publish one. Anyone can query them with a normal NIP-01 filter, for example {"kinds":[1984],"#p":[<pubkey>]}. This makes moderation data open and portable instead of locked inside one platform.

Hint!

Why 1984? The kind number is a nod to Orwell. It sits in the regular event range, so relays store every report and clients can tally them over time.

Reporter client Relay Friends' clients: blur / hide Admin manual takedown kind 1984 REQ #p / #e
Fig. 56-1 — Report flow. One report, many independent readers. Each reader chooses its own response.

2 The Report Event

A report is a regular event with kind set to 1984. The content field MAY carry additional information from the reporting entity, in free text. An empty content is valid. The tags carry the machine-readable part of the report.

Wire format - kind 1984 report
{
  "kind": 1984,
  "tags": [
    ["p", <reported user's pubkey>, <report type>],
    ["e", <reported note id, if reporting a note>, <report type>],
    ["x", <reported blob hash, if reporting a file>, <report type>]
  ],
  "content": <optional free-text explanation>
  // other NIP-01 fields: id, pubkey, created_at, sig
}

3 Tags and Report Types

The tags identify the report target. The rules are:

  • The report MUST include a p tag with the pubkey of the user you report.
  • If you report a note, the report MUST also include an e tag with the note id.
  • The tag that points at the reported target MUST carry a report type string as its 3rd entry. This applies to the e, p, or x tag being reported.
Target tags
TagValueRule
ppubkey of the reported userRequired in every report. Carries the report type when the profile itself is the target.
eid of the reported noteRequired when a note is the target. Carries the report type in that case.
xinfo hash of the reported file blobSHOULD hold the blob hash. When present, the client MUST also include an e tag with the id of the event that contains the blob.
servermedia server URLOptional companion to x. Points to a media server that may host the reported blob.
llabel valueMAY be used, as defined in NIP-32, for further qualification and querying.
Llabel namespaceMAY be used, as defined in NIP-32, together with l.

The report type is one of seven fixed strings:

Report types
TypeMeaning
nudityDepictions of nudity, porn, and similar content.
malwareVirus, trojan horse, worm, robot, spyware, adware, back door, ransomware, rootkit, kidnapper, and similar threats.
profanityProfanity, hateful speech, and similar content.
illegalSomething that may be illegal in some jurisdiction.
spamSpam.
impersonationSomeone pretends to be someone else.
otherReports that do not fit the categories above.

Some report types only make sense for profile reports. impersonation is the clear example: a note cannot impersonate, a profile can. Put such types on the p tag.

Profile report Note report Blob report ["p", pubkey, type] ["e", note id, type] + ["p", pubkey] ["x", blob hash, type] + ["e", carrier event id, type] + ["server", media URL] (optional)
Fig. 56-2 — Three report shapes. The typed tag names the target. Every shape also carries a p tag for the user.
Tech Note

The spec says the report type "MUST be included as the 3rd entry to the e, p or x tag being reported". Yet its own note-report example carries a bare ["p", <pubkey>] with no type, and the blob-report example types both x and e. Read the MUST as applying only to the tag that points at the reported target; treat types on companion tags as optional. Parsers should tolerate both forms. The x paragraph is also loose: it says the hash "SHOULD" be present but never defines the hash function; in practice it is the sha256 hash used by media NIPs.

4 Client Behavior

Clients can use reports from friends to make moderation decisions, if they choose to. Reports become a web-of-trust signal: a report from a followed user carries more weight than a report from a stranger.

Example policy: when 3 or more of your friends report a profile for nudity, the client can offer an option to blur photos from that account automatically. The threshold, the action, and the opt-in are all client decisions. This NIP mandates none of them.

Hint!

Combine reports with NIP-51 mute lists. Reports are public signals from others; mute lists are your own private or public block decisions. Together they cover most client-side moderation needs.

5 Relay Behavior

Relays should not perform automatic moderation from reports. Reports are cheap to publish, so bad actors can game any automatic rule. A wave of fake spam reports must not silence a real user.

Human review works better. Relay admins can use reports from trusted moderators to take down illegal or explicit content when the relay does not allow such things. The trust decision stays with the admin, not with the raw report count.

Warning!

Never delete or block on report volume alone. Anyone can create thousands of keypairs and file thousands of reports. Weigh the reporter, not just the report.

6 Worked Examples

Four reports, one per target shape. Only kind, tags, and content are shown; the other NIP-01 fields (id, pubkey, created_at, sig) are present in real events.

Report 1 - profile, with NIP-32 labels
{
  "kind": 1984,
  "tags": [
    ["p", "<pubkey>", "nudity"],
    ["L", "social.nos.ontology"],
    ["l", "NS-nud", "social.nos.ontology"]
  ],
  "content": ""
}
Report 2 - a note
{
  "kind": 1984,
  "tags": [
    ["e", "<eventId>", "illegal"],
    ["p", "<pubkey>"]
  ],
  "content": "He's insulting the king!"
}
Report 3 - impersonation (profile only)
{
  "kind": 1984,
  "tags": [
    ["p", "<impersonator pubkey>", "impersonation"]
  ],
  "content": "Profile is impersonating nostr:<victim bech32 pubkey>"
}
Report 4 - a file blob
{
  "kind": 1984,
  "tags": [
    ["x", "<blob hash>", "malware"],
    ["e", "<event id which contains the blob on x tag>", "malware"],
    ["server", "https://you-may-find-the-blob-here.com/path-to-url.ext"]
  ],
  "content": "This file contains malware software in it."
}

To read reports about a user or a note, query the standard indexed-tag filters:

Session transcript - fetching reports
→ ["REQ", "mod", {"kinds":[1984], "#p":["<pubkey>"], "limit":100}]
← ["EVENT", "mod", {"kind":1984, "tags":[["p","<pubkey>","spam"]], …}]
← ["EVENT", "mod", {"kind":1984, "tags":[["p","<pubkey>","nudity"]], …}]
← ["EOSE", "mod"]
→ ["CLOSE", "mod"]

7 Version History

NIP-56 has stayed small since 2023. The main additions are labels and blob reports. Notable changes, newest first:

  • 20252025-01Added the x tag for reporting file blobs, with the companion e and server tags.
  • 20242024-04Added the malware report type and rewrote the intro: reports address users and relays, not only moderators.
  • 20232023-07Example content switched from deprecated NIP-08 indexed mentions to NIP-27 bech32 mentions.
  • 20232023-06Added optional l/L labeling per NIP-32.
  • 2023+2023-2026Typo fixes, JSON reformatting, author-line removal, and code-fence cleanup.
  • Origin2023-02William Casarin published the first version: kind 1984 with typed p/e tags and six report types.

Original Proposal - Credits

AuthorWilliam Casarin
First commit2023-02-07 — “NIP-56: Reporting” (PR #205)
Statusactive - optional — clients and relays may ignore reports entirely
Source56.md on GitHub - full change history

8 See Also

  • NIP-01 — the base event format and the e/p tags that reports build on.
  • NIP-32 — the l/L labeling system for finer report qualification.
  • NIP-27 — bech32 mentions like the nostr: reference in the impersonation example.
  • NIP-51 — mute lists; the personal counterpart to public reports.
  • NIP-17 — private messages, for sensitive reports you do not want public.