12<html lang="en">3<head>4<meta charset="utf-8">5<meta name="viewport" content="width=device-width, initial-scale=1">6<title>NIP-01 - Basic Protocol Flow — Nostr Instruction Manual</title>7<meta name="description" content="NIP-01: the basic Nostr protocol. Events, signatures, kinds, filters, and the client–relay message flow. Complete manual page.">8<link rel="preload" href="../assets/fonts/michroma-400-latin.woff2" as="font" type="font/woff2" crossorigin>9<link rel="preload" href="../assets/fonts/exo2-var-latin.woff2" as="font" type="font/woff2" crossorigin>10<link rel="preload" href="../assets/fonts/sairacondensed-600-latin.woff2" as="font" type="font/woff2" crossorigin>11<link rel="preload" href="../assets/fonts/sairacondensed-700-latin.woff2" as="font" type="font/woff2" crossorigin>12<link rel="preload" href="../assets/fonts/sairacondensed-500-latin.woff2" as="font" type="font/woff2" crossorigin>13<link rel="preload" href="../assets/fonts/sharetechmono-400-latin.woff2" as="font" type="font/woff2" crossorigin>14<link rel="preload" href="../assets/fonts/exo2-400i-latin.woff2" as="font" type="font/woff2" crossorigin>15<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml">16<link rel="stylesheet" href="../assets/manual.css">17</head>18<body>1920<svg width="0" height="0" style="position:absolute">21 <defs>22 <marker id="arr" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">23 <path d="M1,1 L8,4.5 L1,8 Z" fill="#f26a00"/>24 </marker>25 <marker id="arrb" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">26 <path d="M1,1 L8,4.5 L1,8 Z" fill="#2e5f9e"/>27 </marker>28 </defs>29</svg>3031<div class="page">32 <span class="staple s1"></span><span class="staple s2"></span>3334 <header class="band">35 <a class="logo" href="../index.html">NOSTR<b>▸</b>PROTOCOL MANUAL</a>36 <span class="booklet-note">Chapter 01 - Core Rules</span>37 </header>38 <nav class="tabs">39 <a href="../index.html">Contents</a>40 <a href="#overview" class="on">Overview</a>41 <a href="#spec">Spec</a>42 <a href="#examples">Examples</a>43 <a href="#history">History</a>44 </nav>4546 <div class="chapter">47 <div class="nipno" data-n="01">01</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 01</div>50 <h1>Basic Protocol Flow</h1>51 <p class="sub">The one rule set that every client and every relay must implement. Everything else in this manual builds on this chapter.</p>52 </div>53 </div>5455 <main class="spread">56 <div class="main">5758 <h2 class="bar" id="overview"><span class="num">1</span> Overview</h2>59 <p>Nostr has only two kinds of programs. A <strong>client</strong> creates and reads messages. A <strong>relay</strong> stores and forwards messages. This NIP defines how they talk.</p>60 <p>The protocol has one object type: the <strong>event</strong>. A user signs each event with a private key. Anyone can verify the signature with the matching public key. No server owns your identity. No server owns your data.</p>61 <p>Clients and relays exchange events over a plain WebSocket connection. A client sends three message types. A relay answers with five message types. That is the whole protocol.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>New to Nostr? Learn this chapter first. All other NIPs add optional features on top of these rules. If a term looks unfamiliar later in the manual, it is probably defined here.</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 190" role="img" aria-label="Client publishes an event to relays; other clients subscribe and receive it">71 <rect class="d-actor" x="10" y="70" width="110" height="50" rx="8"/>72 <text class="d-actor-label" x="65" y="99" text-anchor="middle">Client A</text>73 <rect class="d-actor" x="225" y="20" width="110" height="44" rx="8"/>74 <text class="d-actor-label" x="280" y="47" text-anchor="middle">Relay 1</text>75 <rect class="d-actor" x="225" y="126" width="110" height="44" rx="8"/>76 <text class="d-actor-label" x="280" y="153" text-anchor="middle">Relay 2</text>77 <rect class="d-actor" x="440" y="70" width="110" height="50" rx="8"/>78 <text class="d-actor-label" x="495" y="99" text-anchor="middle">Client B</text>79 <path class="d-msg d-flow" d="M122,84 C170,70 180,52 223,44"/>80 <path class="d-msg d-flow" d="M122,106 C170,120 180,138 223,146"/>81 <path class="d-msg blue d-flow" d="M337,44 C380,52 390,70 438,84"/>82 <path class="d-msg blue d-flow" d="M337,146 C380,138 390,120 438,106"/>83 <text class="d-label" x="160" y="48" text-anchor="middle">EVENT</text>84 <text class="d-label" x="400" y="48" text-anchor="middle">REQ / EVENT</text>85 <circle r="4" fill="#f26a00">86 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,84 C170,70 180,52 223,44"/>87 </circle>88 <circle r="4" fill="#2e5f9e">89 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M337,44 C380,52 390,70 438,84"/>90 </circle>91 </svg>92 </div>93 <figcaption>Fig. 1-1 — <b>The basic flow.</b> Client A publishes one signed event to many relays. Client B subscribes and receives it.</figcaption>94 </figure>9596 <h2 class="bar" id="spec"><span class="num">2</span> The Event Object</h2>97 <p>Every user has a keypair on the curve <code>secp256k1</code>. Signatures and public keys follow the <a href="https://bips.xyz/340">BIP-340 Schnorr standard</a>. An event has this exact wire format:</p>9899 <div class="crt">100 <div class="titlebar">Wire format - event object</div>101<pre>{102 <span class="k">"id"</span>: <span class="c"><32-byte lowercase hex sha256 of the serialized event></span>103 <span class="k">"pubkey"</span>: <span class="c"><32-byte lowercase hex public key of the creator></span>104 <span class="k">"created_at"</span>: <span class="c"><unix timestamp, seconds></span>105 <span class="k">"kind"</span>: <span class="c"><integer, 0 – 65535></span>106 <span class="k">"tags"</span>: [[<span class="c"><string></span>, ...], ...]107 <span class="k">"content"</span>: <span class="c"><arbitrary string></span>108 <span class="k">"sig"</span>: <span class="c"><64-byte lowercase hex Schnorr signature of the id></span>109}</pre>110 </div>111112 <div class="tscroll"><table class="ref">113 <caption>Field reference</caption>114 <tr><th>Field</th><th>Type</th><th>Rule</th></tr>115 <tr><td class="btn">id</td><td>hex string, 64 chars</td><td>The sha256 hash of the serialized event. Computed, not chosen.</td></tr>116 <tr><td class="btn">pubkey</td><td>hex string, 64 chars</td><td>The public key of the creator. Lowercase hex.</td></tr>117 <tr><td class="btn">created_at</td><td>integer</td><td>Unix timestamp in seconds. Set by the creator.</td></tr>118 <tr><td class="btn">kind</td><td>integer</td><td>0 to 65535. Tells clients how to interpret the event. See §4.</td></tr>119 <tr><td class="btn">tags</td><td>array of arrays</td><td>Each tag is an array of one or more strings. See §3.</td></tr>120 <tr><td class="btn">content</td><td>string</td><td>Arbitrary payload. Meaning depends on the kind.</td></tr>121 <tr><td class="btn">sig</td><td>hex string, 128 chars</td><td>Schnorr signature of the <code>id</code> hash, made with the creator's key.</td></tr>122 </table></div>123124 <h3>Serialization: how to compute the ID</h3>125 <p>To get <code>event.id</code>, serialize the event into a UTF-8 JSON array. Then hash the string with <code>sha256</code>. The array has this fixed shape:</p>126 <div class="crt">127 <div class="titlebar">Serialization target</div>128<pre>[0, <span class="k">pubkey</span>, <span class="k">created_at</span>, <span class="k">kind</span>, <span class="k">tags</span>, <span class="k">content</span>]</pre>129 </div>130 <p>Every implementation must produce the same bytes for the same event. Follow these rules exactly:</p>131 <ul>132 <li>Encode with UTF-8.</li>133 <li>Do not add whitespace, line breaks, or any formatting.</li>134 <li>In <code>content</code>, escape only these characters: line break as <code>\n</code>, double quote as <code>\"</code>, backslash as <code>\\</code>, carriage return as <code>\r</code>, tab as <code>\t</code>, backspace as <code>\b</code>, form feed as <code>\f</code>. Output all other characters verbatim.</li>135 </ul>136 <div class="box warn">137 <span class="tag">Warning!</span>138 <p>Do not use your language's default JSON escaper. Many escape more characters than the list above (for example <code>/</code> or non-ASCII). One extra escape changes the hash, and the event ID will not verify.</p>139 </div>140141 <figure class="diagram">142 <div class="frame">143 <svg viewBox="0 0 560 120" role="img" aria-label="Event fields flow into serialization, then sha256, producing the id, which is signed to produce sig">144 <rect class="d-actor" x="10" y="35" width="120" height="50" rx="8"/>145 <text class="d-actor-label" x="70" y="57" text-anchor="middle">Event</text>146 <text class="d-note" x="70" y="74" text-anchor="middle">fields</text>147 <rect class="d-actor" x="180" y="35" width="110" height="50" rx="8"/>148 <text class="d-actor-label" x="235" y="57" text-anchor="middle">Serialize</text>149 <text class="d-note" x="235" y="74" text-anchor="middle">[0,pk,ts,k,tags,c]</text>150 <rect class="d-actor" x="340" y="35" width="90" height="50" rx="8"/>151 <text class="d-actor-label" x="385" y="57" text-anchor="middle">sha256</text>152 <text class="d-note" x="385" y="74" text-anchor="middle">→ id</text>153 <rect class="d-actor" x="480" y="35" width="70" height="50" rx="8"/>154 <text class="d-actor-label" x="515" y="57" text-anchor="middle">Sign</text>155 <text class="d-note" x="515" y="74" text-anchor="middle">→ sig</text>156 <path class="d-msg d-flow" d="M132,60 L177,60"/>157 <path class="d-msg d-flow" d="M292,60 L337,60"/>158 <path class="d-msg d-flow" d="M432,60 L477,60"/>159 </svg>160 </div>161 <figcaption>Fig. 1-2 — <b>ID pipeline.</b> Serialize, hash, sign. The <code>id</code> and <code>sig</code> fields are outputs, never inputs.</figcaption>162 </figure>163164 <h2 class="bar" id="tags"><span class="num">3</span> Tags</h2>165 <p>A tag is an array of strings. The first string is the tag <strong>name</strong>. The second string is the tag <strong>value</strong>. Later elements have no fixed name.</p>166 <div class="crt">167 <div class="titlebar">Example - tags array</div>168<pre>"tags": [169 [<span class="s">"e"</span>, <span class="s">"5c83da77af1d…226f36"</span>, <span class="s">"wss://nostr.example.com"</span>],170 [<span class="s">"p"</span>, <span class="s">"f7234bd4c139…76e9ca"</span>],171 [<span class="s">"a"</span>, <span class="s">"30023:f7234bd4c139…76e9ca:abcd"</span>, <span class="s">"wss://nostr.example.com"</span>],172 [<span class="s">"alt"</span>, <span class="s">"reply"</span>]173]</pre>174 </div>175 <p>This NIP defines three standard tags. They keep the same meaning in every event kind:</p>176 <div class="tscroll"><table class="ref">177 <caption>Standard tags</caption>178 <tr><th>Tag</th><th>Points to</th><th>Full form</th></tr>179 <tr><td class="btn">e</td><td>another event</td><td><code>["e", <event id>, <relay URL, optional>, <author pubkey, optional>]</code></td></tr>180 <tr><td class="btn">p</td><td>another user</td><td><code>["p", <pubkey>, <relay URL, optional>]</code></td></tr>181 <tr><td class="btn">a</td><td>an addressable or replaceable event</td><td><code>["a", "<kind>:<pubkey>:<d value>", <relay URL, optional>]</code> — for a normal replaceable event, leave the <code>d</code> value empty but keep the trailing colon.</td></tr>182 </table></div>183 <div class="box tech">184 <span class="tag">Tech Note</span>185 <p>Relays index every tag whose name is one English letter (<code>a</code>–<code>z</code>, <code>A</code>–<code>Z</code>). Only the first value of each tag is indexed. Query indexed tags with filter keys like <code>{"#e": [<event id>]}</code>.</p>186 </div>187188 <h2 class="bar" id="kinds"><span class="num">4</span> Kinds and Storage Classes</h2>189 <p>The <code>kind</code> number tells a client what an event means. It also tells a relay how to store the event. A tag can mean different things in different kinds. Each NIP may claim unused kind numbers and define their meaning.</p>190 <p>This NIP defines one kind. <strong>Kind 0 — user metadata:</strong> the <code>content</code> is a stringified JSON object such as <code>{"name": …, "about": …, "picture": …}</code> that describes the author. <a href="24.html">NIP-24</a> lists extra metadata fields. A relay may delete an older kind-0 event when it receives a newer one from the same pubkey.</p>191192 <figure class="diagram">193 <div class="frame">194 <svg viewBox="0 0 560 168" role="img" aria-label="Kind number ranges and their storage classes">195 <text class="d-actor-label" x="10" y="18">Kind range map</text>196 <rect x="10" y="30" width="130" height="26" rx="4" fill="#2e5f9e"/>197 <text class="d-label" x="75" y="47" text-anchor="middle" fill="#fff">0, 3 - 10000–19999</text>198 <text class="d-note" x="150" y="47">REPLACEABLE — relay keeps only the latest per pubkey+kind</text>199 <rect x="10" y="64" width="130" height="26" rx="4" fill="#f26a00"/>200 <text class="d-label" x="75" y="81" text-anchor="middle" fill="#fff">1–2, 4–44 - 1000–9999</text>201 <text class="d-note" x="150" y="81">REGULAR — relay stores all of them</text>202 <rect x="10" y="98" width="130" height="26" rx="4" fill="#7d8794"/>203 <text class="d-label" x="75" y="115" text-anchor="middle" fill="#fff">20000–29999</text>204 <text class="d-note" x="150" y="115">EPHEMERAL — relay does not store them</text>205 <rect x="10" y="132" width="130" height="26" rx="4" fill="#2c7a3f"/>206 <text class="d-label" x="75" y="149" text-anchor="middle" fill="#fff">30000–39999</text>207 <text class="d-note" x="150" y="149">ADDRESSABLE — latest per pubkey+kind+d tag value</text>208 </svg>209 </div>210 <figcaption>Fig. 1-3 — <b>Storage classes by kind range.</b> These ranges are conventions; relay implementations may differ.</figcaption>211 </figure>212213 <ul>214 <li><strong>Regular</strong> events: relays are expected to store all of them.</li>215 <li><strong>Replaceable</strong> events: for each <code>pubkey</code> + <code>kind</code> pair, relays must keep only the latest event. They may discard older versions.</li>216 <li><strong>Ephemeral</strong> events: relays are not expected to store them at all.</li>217 <li><strong>Addressable</strong> events: for each <code>kind</code> + <code>pubkey</code> + <code>d</code>-tag-value triple, relays must keep only the latest event.</li>218 </ul>219 <div class="box hint">220 <span class="tag">Hint!</span>221 <p>Two replaceable events with the same timestamp? Keep the one whose <code>id</code> sorts first in lexical order. When a client requests replaceable events, the relay should return only the latest version, even if it stored several.</p>222 </div>223224 <h2 class="bar" id="messages"><span class="num">5</span> Client ↔ Relay Messages</h2>225 <p>A relay exposes one WebSocket endpoint. A client should open a single connection per relay and reuse it for all subscriptions. A relay may limit connections per IP or client. A relay must accept connections on only one endpoint when extra path segments do not change its behavior.</p>226227 <div class="tscroll"><table class="ref">228 <caption>Client → relay (3 message types)</caption>229 <tr><th>Message</th><th>Shape</th><th>Purpose</th></tr>230 <tr><td class="btn">EVENT</td><td><code>["EVENT", <event>]</code></td><td>Publish an event.</td></tr>231 <tr><td class="btn">REQ</td><td><code>["REQ", <sub_id>, <filter1>, <filter2>, …]</code></td><td>Request stored events and subscribe to new ones.</td></tr>232 <tr><td class="btn">CLOSE</td><td><code>["CLOSE", <sub_id>]</code></td><td>Stop a subscription.</td></tr>233 </table></div>234235 <p><code><sub_id></code> is a non-empty string, at most 64 characters. It identifies a subscription <em>per connection</em>. Relays must track subscription IDs separately for each WebSocket connection; the IDs are not globally unique. A new <code>REQ</code> with the same ID replaces the old subscription.</p>236237 <h3>Filters</h3>238 <div class="crt">239 <div class="titlebar">Filter object</div>240<pre>{241 <span class="k">"ids"</span>: <span class="c"><list of event ids></span>242 <span class="k">"authors"</span>: <span class="c"><list of lowercase pubkeys></span>243 <span class="k">"kinds"</span>: <span class="c"><list of kind numbers></span>244 <span class="k">"#<letter>"</span>: <span class="c"><list of tag values, e.g. "#e": event ids></span>245 <span class="k">"since"</span>: <span class="c"><unix ts — match if created_at >= since></span>246 <span class="k">"until"</span>: <span class="c"><unix ts — match if created_at <= until></span>247 <span class="k">"limit"</span>: <span class="c"><max events in the initial query></span>248}</pre>249 </div>250 <p>Filter logic follows four rules:</p>251 <ol>252 <li>Inside one list, values are OR: one match is enough.</li>253 <li>Between attributes of one filter, conditions are AND: all must match.</li>254 <li>Between multiple filters in one <code>REQ</code>, filters are OR: any filter may match.</li>255 <li><code>ids</code>, <code>authors</code>, <code>#e</code>, and <code>#p</code> must contain exact 64-character lowercase hex values.</li>256 </ol>257 <p>The <code>limit</code> attribute applies only to the initial query and is ignored afterwards. The relay returns the last <code>limit</code> events ordered by <code>created_at</code>, newest first; ties sort by lowest <code>id</code> first. Returning fewer events is acceptable. Returning many more is not: it overwhelms clients.</p>258259 <div class="tscroll"><table class="ref">260 <caption>Relay → client (5 message types)</caption>261 <tr><th>Message</th><th>Shape</th><th>Purpose</th></tr>262 <tr><td class="btn">EVENT</td><td><code>["EVENT", <sub_id>, <event>]</code></td><td>Deliver an event that matches a subscription. Sent only for subscriptions the client opened.</td></tr>263 <tr><td class="btn">OK</td><td><code>["OK", <event_id>, true|false, <message>]</code></td><td>Accept or reject a client's <code>EVENT</code>. Mandatory reply.</td></tr>264 <tr><td class="btn">EOSE</td><td><code>["EOSE", <sub_id>]</code></td><td>End of stored events. Everything after this is real-time.</td></tr>265 <tr><td class="btn">CLOSED</td><td><code>["CLOSED", <sub_id>, <message>]</code></td><td>The relay refused or terminated a subscription on its side.</td></tr>266 <tr><td class="btn">NOTICE</td><td><code>["NOTICE", <message>]</code></td><td>Human-readable errors and other information. No rules defined.</td></tr>267 </table></div>268269 <p>The <code>OK</code> and <code>CLOSED</code> messages carry a machine-readable status. The message string starts with a single-word prefix, then <code>:</code>, then a human-readable text. When <code>OK</code> is <code>true</code>, the message may be empty. The standard prefixes are:</p>270 <div class="tscroll"><table class="ref">271 <caption>Standard status prefixes</caption>272 <tr><th>Prefix</th><th>Meaning</th></tr>273 <tr><td class="btn">duplicate</td><td>The relay already has this event.</td></tr>274 <tr><td class="btn">pow</td><td>Proof-of-work status (see <a href="13.html">NIP-13</a>).</td></tr>275 <tr><td class="btn">blocked</td><td>The relay refuses this pubkey or event.</td></tr>276 <tr><td class="btn">rate-limited</td><td>Slow down.</td></tr>277 <tr><td class="btn">invalid</td><td>The event fails validation.</td></tr>278 <tr><td class="btn">restricted</td><td>The client is not allowed to write.</td></tr>279 <tr><td class="btn">mute</td><td>Nobody was listening to this ephemeral event; it was ignored.</td></tr>280 <tr><td class="btn">error</td><td>Anything else, such as an internal failure.</td></tr>281 </table></div>282283 <figure class="diagram">284 <div class="frame">285 <svg viewBox="0 0 560 300" role="img" aria-label="Sequence diagram: client sends REQ, relay returns stored events, EOSE, then live events until CLOSE">286 <line class="d-wire" x1="110" y1="40" x2="110" y2="285" stroke-dasharray="3 4"/>287 <line class="d-wire" x1="450" y1="40" x2="450" y2="285" stroke-dasharray="3 4"/>288 <rect class="d-actor" x="55" y="8" width="110" height="30" rx="6"/>289 <text class="d-actor-label" x="110" y="28" text-anchor="middle">Client</text>290 <rect class="d-actor" x="395" y="8" width="110" height="30" rx="6"/>291 <text class="d-actor-label" x="450" y="28" text-anchor="middle">Relay</text>292 <path class="d-msg" d="M110,62 L445,62"/>293 <text class="d-label" x="280" y="55" text-anchor="middle">["REQ", "sub1", {"kinds":[1],"limit":3}]</text>294 <path class="d-msg blue" d="M450,95 L115,95"/>295 <text class="d-label" x="280" y="88" text-anchor="middle">["EVENT", "sub1", {…}] × stored matches</text>296 <path class="d-msg blue" d="M450,128 L115,128"/>297 <text class="d-label" x="280" y="121" text-anchor="middle">["EOSE", "sub1"]</text>298 <path class="d-msg blue d-flow" d="M450,170 L115,170"/>299 <text class="d-label" x="280" y="163" text-anchor="middle">["EVENT", "sub1", {…}] live, as they arrive</text>300 <path class="d-msg" d="M110,215 L445,215"/>301 <text class="d-label" x="280" y="208" text-anchor="middle">["CLOSE", "sub1"]</text>302 <text class="d-note" x="280" y="250" text-anchor="middle">Subscription ends. The WebSocket stays open for other subscriptions.</text>303 </svg>304 </div>305 <figcaption>Fig. 1-4 — <b>Subscription lifecycle.</b> Stored events first, then <code>EOSE</code>, then real-time delivery until <code>CLOSE</code>.</figcaption>306 </figure>307308 <h2 class="bar" id="examples"><span class="num">6</span> Worked Example</h2>309 <p>The session below shows one full round trip. Client A publishes a kind-1 note. Client B subscribes and receives it. Orange lines go to the relay. Blue lines come from the relay.</p>310 <div class="crt">311 <div class="titlebar">Session transcript - wss://relay.example.com</div>312<pre><span class="c">-- Client A publishes --</span>313<span class="send">→ ["EVENT", {"id":"b1a649ebe8…","pubkey":"22a12a12…","created_at":1749762600,314 "kind":1,"tags":[],"content":"Running nostr.","sig":"e8551d85…"}]</span>315<span class="recv">← ["OK", "b1a649ebe8…", true, ""]</span>316317<span class="c">-- Client B subscribes --</span>318<span class="send">→ ["REQ", "feed", {"kinds":[1], "authors":["22a12a12…"], "limit":10}]</span>319<span class="recv">← ["EVENT", "feed", {"id":"b1a649ebe8…", "kind":1, "content":"Running nostr.", …}]</span>320<span class="recv">← ["EOSE", "feed"]</span>321<span class="c">-- later, new matching events stream in live --</span>322<span class="recv">← ["EVENT", "feed", {"id":"9f2c11ab…", …}]</span>323<span class="send">→ ["CLOSE", "feed"]</span>324325<span class="c">-- a rejection looks like this --</span>326<span class="recv">← ["OK", "d2b649ffa1…", false, "rate-limited: slow down there chief"]</span>327<span class="recv">← ["CLOSED", "feed2", "unsupported: filter contains unknown elements"]</span></pre>328 </div>329330 <h2 class="bar" id="history"><span class="num">7</span> Version History</h2>331 <p>NIP-01 is a living document. It started as a short note by fiatjaf and has absorbed several other NIPs over time. Notable changes, newest first:</p>332 <ul class="patchnotes">333 <li><span class="ver">2026</span><span class="when">2026-05</span>Clarified that relays must accept connections on a single endpoint when path segments do not change behavior.</li>334 <li><span class="ver">2025</span><span class="when">2025-07</span>Added the <code>mute</code> status prefix for ignored ephemeral events.</li>335 <li><span class="ver">2025</span><span class="when">2025-02</span>Added the optional author pubkey as the 4th element of the <code>e</code> tag; added the <code>restricted</code> prefix.</li>336 <li class="minor"><span class="ver">2024</span><span class="when">2024</span>Clarified <code>limit</code> ordering, subscription-ID scope, and the trailing colon in <code>a</code> tags for replaceable events.</li>337 <li><span class="ver">2023</span><span class="when">2023-06</span>Absorbed <a href="16.html">NIP-16</a> (event treatment), <a href="20.html">NIP-20</a> (<code>OK</code> command results), and <a href="33.html">NIP-33</a> (addressable events). Kind ranges and storage classes became part of the core.</li>338 <li><span class="ver">2023</span><span class="when">2023-01</span>Absorbed <a href="12.html">NIP-12</a>: generic single-letter tag queries became core filter behavior.</li>339 <li><span class="ver">2022</span><span class="when">2022-05</span>Migrated into the dedicated <code>nostr-protocol/nips</code> repository. The <code>limit</code> filter attribute arrived days later.</li>340 <li><span class="ver">Origin</span><span class="when">2020-11</span>fiatjaf published the first protocol description in the original <code>fiatjaf/nostr</code> repository.</li>341 </ul>342343 <div class="credits">344 <h3 class="cardhead">Original Proposal - Credits</h3>345 <table>346 <tr><td>Author</td><td>fiatjaf</td></tr>347 <tr><td>First commit</td><td>2022-05-01 — “migrate nips from main nostr repo” (spec predates the repo, 2020)</td></tr>348 <tr><td>Status</td><td>draft - mandatory — every client and relay must implement it</td></tr>349 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/01.md">01.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/01.md">full change history</a></td></tr>350 </table>351 </div>352353 <h2 class="bar"><span class="num">8</span> See Also</h2>354 <ul>355 <li><a href="10.html">NIP-10</a> — defines <code>kind:1</code> text notes and reply threading.</li>356 <li><a href="19.html">NIP-19</a> — bech32 encodings (<code>npub</code>, <code>nsec</code>, <code>note</code>) for the raw hex keys and IDs used here.</li>357 <li><a href="11.html">NIP-11</a> — the relay information document; how a relay describes its limits.</li>358 <li><a href="24.html">NIP-24</a> — extra fields for the kind-0 metadata object.</li>359 <li><a href="42.html">NIP-42</a> — authentication of clients to relays on top of this flow.</li>360 </ul>361 </div>362363 <aside>364 <div class="cartridge">365 <div class="inner">366 <h3 class="cardhead">Spec Card</h3>367 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>368 <dl>369 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip mandatory">mandatory</span></dd>370 <dt>Defines</dt><dd>event - kind 0 - e/p/a tags - REQ filters - OK/EOSE/CLOSED</dd>371 <dt>Kind range</dt><dd>storage classes for 0–65535</dd>372 <dt>Requires</dt><dd>nothing — this is the root spec</dd>373 <dt>Transport</dt><dd>WebSocket - JSON arrays</dd>374 <dt>Crypto</dt><dd>secp256k1 - BIP-340 Schnorr - sha256</dd>375 <dt>First commit</dt><dd>2022-05-01</dd>376 <dt>Last updated</dt><dd>2026-06-13</dd>377 </dl>378 </div>379 </div>380 </aside>381 </main>382383 <nav class="navbtns">384 <a href="../index.html">◀ Contents</a>385 <a href="02.html">NIP-02: Follow List ▶</a>386 </nav>387388 <footer class="pagefoot">389 <a href="../index.html">Nostr Protocol Manual</a>390 <span class="pageno">NIP 01 / F4</span>391 </footer>392</div>393394<script src="../assets/webmcp.js" defer></script>395</body>396</html>