Chapter 6
Kinds & NIPs
A periodic table of event kinds and the specs that define them.
Same envelope, different stamp! Let's sort the mail by kind.
One envelope, many stamps
So far every
So how does an app know which is which? One tiny field: the 1 means “short text note”, 0 means “my profile”,
7 means “reaction”, 30023 means “long-form article”. That’s it. No new message types, no new
endpoints: Nostr grows by inventing new numbers.
Think of the kind as the section of a library. The books (events) are all bound the same way, but
the sticker on the spine tells the librarian (the
The periodic table of kinds
Chemists sort elements by their properties. We can do the same with kinds: the color of a tile is its storage category, which is decided purely by the number’s range. Click around: every tile opens a real example event. Try to visit all four colors.
The periodic table of kinds
Every tile is an event kind. Filter by storage category or search, then pick a tile to see a real example event.
60 kinds shown
Regular Relays keep every one.
Replaceable Relays keep only the latest per author.
Ephemeral Relays forward but never store them.
Addressable Relays keep the latest per author and d tag.
Short text note
Kind 1
RegularA plain-text post, like a tweet.
- What relays do
- Relays keep every one. Range: 1–2, 4–44, 1000–9999
- Defined in
- Read NIP-10 on GitHub
Example event
A real signed event from our fixture set.
{ "id": "ea2e3eb8fe5e6cfbc202da21df546f68c6673e9a00c0aed61cffbac7aed9faf7" ,"pubkey": "a73883912a48c3551c1548fd454876d577126a61c76b5486c807bfec5869e183" ,"created_at": 1735686600 ,"kind": 1 , "tags": [ ] ,"content": "testing testing is this thing on" ,"sig": "82bc74fdbd5b113f257f4c8b2a6db64410ae897362bd42839fe9a34737d5ecb518a99f8517058ef8c2beadc222142e4d68f034e829edc9dd1b6bd13d2a139a7d" } Ask a relay for this kind
["REQ","kinds-demo",{"kinds":[1],"limit":10}]
Under the hood: where kinds are registered Show details
There is no central registry server: the list of known kinds lives in the README of the
nostr-protocol/nips repository, next to the NIP that
defines each one. Examples in the table above are either real fixture events (verified signatures) or
templates signed in your browser with a public demo key using a fixed auxRand, so the bytes are
identical on every visit.
import { kinds } from "nostr-tools";
kinds.ShortTextNote; // 1
kinds.LongFormArticle; // 30023
kinds.classifyKind(30023); // "parameterized" (nostr-tools' older name for addressable)
kinds.isReplaceableKind(10002); // trueFour ways to be stored
The number tells a relay what to keep.
- Regular (
1,2,4–44,1000–9999): a diary. Every page is kept. Notes, reactions, reposts and zap receipts pile up forever (or until the relay decides otherwise). (Replaceable Replaceable event: An event where only the newest one per author and kind is kept, like a profile (kind 0) or follow list (kind 3).0,3,10000–19999): a whiteboard. Each person gets one per kind; writing a new one wipes the old. Your profile ( ), yourkind 0 Metadata: Your profile: a kind 0 event whose content is JSON with fields like name, about, picture, nip05 and lud16. (kind 3) and your relay list (kind 10002) work this way.follow list Follow list: A kind 3 event listing the pubkeys you follow as p tags. Each new version replaces the previous one. (Ephemeral Ephemeral event: An event (kinds 20000–29999) that relays forward to current subscribers but do not store.20000–29999): a phone call. Relays pass it to whoever is listening right now and then forget it. Perfect for login challenges and signer chatter. (Addressable Addressable event: A replaceable event identified by kind, author and a d tag, so one person can have many of them (kinds 30000–39999).30000–39999): a set of labeled whiteboards. One per person, per kind, perdtag. That’s how you can edit several independently.long-form articles Long-form content: Articles and blog posts written in Markdown and published as kind 30023 events.
Play with it. Publish a few versions, switch categories, and then try re-sending an older copy:
Relay storage simulator
Publish several versions of an event and watch what the relay keeps on its shelf.
Relay shelf 0 events stored
The shelf is empty.
Live subscribers
Nobody has received anything yet.
For replaceable and addressable events the newest created_at wins. If two versions share the exact
same second, relays keep the one with the lowest id (first in alphabetical order), so every relay
ends up agreeing on the same winner no matter which copy arrived first.
Under the hood: NIP-01 storage rules Show details
The exact rules from NIP-01:
| Category | Range | Relay keeps |
|---|---|---|
| regular | 1000 <= n < 10000 || 4 <= n < 45 || n == 1 || n == 2 |
every event |
| replaceable | 10000 <= n < 20000 || n == 0 || n == 3 |
latest per (pubkey, kind) |
| ephemeral | 20000 <= n < 30000 |
nothing (forward only) |
| addressable | 30000 <= n < 40000 |
latest per (pubkey, kind, d) |
Kinds 45–999 and 40000–65535 fall outside every range: NIP-01 says nothing about storing them, and most
relays treat them as regular. An addressable event is pointed at with its address kind:pubkey:d, either
in an a tag or encoded as an
["a", "30023:e550c6e92808f358382b7b8c14345344f5ef9a299529834d1c26d57b6ace44cc:relays-explained", "wss://relay.alpha.example"]Asking for “the current version” is a normal filter, because the relay only stores one:
["REQ", "article", { "kinds": [30023], "authors": ["e550c6…"], "#d": ["relays-explained"] }]Want to test your intuition? Type any number and see which neighborhood it lives in:
Kind number classifier
Kind 30023 is Addressable.
Relays keep the latest per author and d tag.
We know this one: Long-form article (NIP-23).
NIPs: how Nostr grows without a boss
Who decides that 7 means “reaction”? Nobody, and everybody. A
- Someone has an idea. A developer wants polls, or calendars, or marketplaces.
- They build it first. Ideally in a real client and relay, picking a kind number nobody else uses.
- They open a pull request. People argue, simplify, and poke holes in it in public.
- It gets merged when it’s real. The README asks that a NIP be implemented in at least two clients and one relay (where applicable), make sense, be optional and backwards-compatible, and not add a second way to do the same thing.
The key trick is the word optional. A client that doesn’t understand kind 31922 (a calendar event)
simply ignores it. Nothing breaks. That’s why Nostr can grow sideways: microblogging, long-form,
livestreams, code collaboration and wallets all share the same relays and the same keys.
Most NIPs have two-digit decimal names (01, 57), but newer ones may use hex-looking names such as
7D (threads) or C7 (chats). The kind number and the NIP number are unrelated: kind 7 is defined
in NIP-25, not NIP-07.
Under the hood: NIPs worth reading Show details
Useful starting points in the NIPs repository:
- NIP-01: the event format, kind 0 and the four storage categories (kind 1 is specified in NIP-10)
- NIP-02: follow list (kind 3)
(spec): long-form content (kind 30023, drafts 30024)NIP-23 NIP-23: Long-form content: blog-style Markdown articles as addressable kind 30023 events (drafts use 30024).- NIP-51: lists, standard (10000+) and sets (30000+)
- NIP-65: relay list metadata (kind 10002)
- NIP-31: put a human-readable
alttag on custom kinds, so clients that don’t understand them can still show something. The NIPs README now marks NIP-31 as unrecommended, but analttag on a custom kind is still a harmless courtesy - NIP-89: apps announce which kinds they handle (31990), users recommend apps (31989)
Inventing a private kind for your app? Pick an unused number in the right range for the storage
behavior you want, add an alt tag, and document it.
Quick check
Takeaways
- Every event has a kind: a number that says what it is (a note, a profile, a reaction…).
- The number's range tells relays how to store it: regular (keep all), replaceable (keep latest), ephemeral (keep none), addressable (keep latest per d tag).
- For replaceable and addressable events, the newest created_at wins; ties go to the lowest id.
- NIPs are the community's open specs. A new kind is just a number plus a NIP that explains it.
- Clients ignore kinds they don't understand, so new features never break old apps.