← Back to Nostr Implementation Possibilities
NIP 28specificationdraftlightningkey-managementscriptrelaynostrevents

Public Chat

This NIP defines new event kinds for public chat channels, channel messages, and basic client-side moderation. It reserves five event kinds (40-44) for immediate use:

No reviews
Unknown·Updated Mar 29, 2026·0 reviews·0 attestations·View source
Collections:NIPs — Merged

Specification

NIP-28

Public Chat

`draft` `optional`

This NIP defines new event kinds for public chat channels, channel messages, and basic client-side moderation.

It reserves five event kinds (40-44) for immediate use:

  • `40 - channel create`
  • `41 - channel metadata`
  • `42 - channel message`
  • `43 - hide message`
  • `44 - mute user`
  • Client-centric moderation gives client developers discretion over what types of content they want included in their apps, while imposing no additional requirements on relays.

    ## Kind 40: Create channel

    Create a public chat channel.

    In the channel creation `content` field, Client SHOULD include basic channel metadata (`name`, `about`, `picture` and `relays` as specified in kind 41).

    ```jsonc

    {

    "content": "{\"name\": \"Demo Channel\", \"about\": \"A test channel.\", \"picture\": \"https://placekitten.com/200/200\", \"relays\": [\"wss://nos.lol\", \"wss://nostr.mom\"]}",

    // other fields...

    }

    ```

    ## Kind 41: Set channel metadata

    Update a channel's public metadata.

    Kind 41 is used to update the metadata without modifying the event id for the channel. Only the most recent kind 41 per `e` tag value MAY be available.

    Clients SHOULD ignore kind 41s from pubkeys other than the kind 40 pubkey.

    Clients SHOULD support basic metadata fields:

  • `name` - string - Channel name
  • `about` - string - Channel description
  • `picture` - string - URL of channel picture
  • `relays` - array - List of relays to download and broadcast events to
  • Clients MAY add additional metadata fields.

    Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay.

    It is also possible to set the category name using the "t" tag. This category name can be searched and filtered.

    ```jsonc

    {

    "content": "{\"name\": \"Updated Demo Channel\", \"about\": \"Updating a test channel.\", \"picture\": \"https://placekitten.com/201/201\", \"relays\": [\"wss://nos.lol\", \"wss://nostr.mom\"]}",

    "tags": [

    ["e", <channel_create_event_id>, <relay-url>, "root"],

    ["t", <category_name-1>],

    ["t", <category_name-2>],

    ["t", <category_name-3>],

    ],

    // other fields...

    }

    ```

    ## Kind 42: Create channel message

    Send a text message to a channel.

    Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay and specify whether it is a reply or root message.

    Clients SHOULD append [NIP-10](10.md) "p" tags to replies.

    Root message:

    ```jsonc

    {

    "content": <string>,

    "tags": [["e", <kind_40_event_id>, <relay-url>, "root"]],

    // other fields...

    }

    ```

    Reply to another message:

    ```jsonc

    {

    "content": <string>,

    "tags": [

    ["e", <kind_40_event_id>, <relay-url>, "root"],

    ["e", <kind_42_event_id>, <relay-url>, "reply"],

    ["p", <pubkey>, <relay-url>],

    // rest of tags...

    ],

    // other fields...

    }

    ```

    ## Kind 43: Hide message

    User no longer wants to see a certain message.

    The `content` may optionally include metadata such as a `reason`.

    Clients SHOULD hide event 42s shown to a given user, if there is an event 43 from that user matching the event 42 `id`.

    Clients MAY hide event 42s for other users other than the user who sent the event 43.

    (For example, if three users 'hide' an event giving a reason that includes the word 'pornography', a Nostr client that is an iOS app may choose to hide that message for all iOS clients.)

    ```jsonc

    {

    "content": "{\"reason\": \"Dick pic\"}",

    "tags": [["e", <kind_42_event_id>]],

    // other fields...

    }

    ```

    ## Kind 44: Mute user

    User no longer wants to see messages from another user.

    The `content` may optionally include metadata such as a `reason`.

    Clients SHOULD hide event 42s shown to a given user, if there is an event 44 from that user matching the event 42 `pubkey`.

    Clients MAY hide event 42s for users other than the user who sent the event 44.

    ```jsonc

    {

    "content": "{\"reason\": \"Posting dick pics\"}",

    "tags": [["p", <pubkey>]],

    // other fields...

    }

    ```

    ## Relay recommendations

    Clients SHOULD use the relay URLs of the metadata events.

    Clients MAY use any relay URL. For example, if a relay hosting the original kind 40 event for a channel goes offline, clients could instead fetch channel data from a backup relay, or a relay that clients trust more than the original relay.

    Motivation

    If we're solving censorship-resistant communication for social media, we may as well solve it also for Telegram-style messaging.

    We can bring the global conversation out from walled gardens into a true public square open to all.

    Additional info

  • [Chat demo PR with fiatjaf+jb55 comments](https://github.com/ArcadeCity/arcade/pull/28)
  • [Conversation about NIP16](https://t.me/nostr_protocol/29566)
  • Discussion (0 threads)

    Loading discussions...