clone

every nostr nip as a chapter of an illustrated, early-2000s printed game manual

main
nip.guide / site / nips / 23.html
23.html 19.5K
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="utf-8">5<meta name="viewport" content="width=device-width, initial-scale=1">6<title>NIP-23 - Long-form Content — Nostr Instruction Manual</title>7<meta name="description" content="NIP-23: long-form articles as kind 30023 addressable events. Markdown content, metadata tags, editability, naddr linking, and NIP-22 comments.">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 23 - Media</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="23">23</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 23</div>50 <h1>Long-form Content</h1>51 <p class="sub">Articles and blog posts as editable Markdown events. Write once, revise forever, keep one stable address.</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>A kind-1 note is short and frozen. An article is long and lives on. This NIP defines <strong>kind 30023</strong> for long-form text content, generally called an article or a blog post.</p>60 <p>Kind 30023 is an <strong>addressable event</strong> as defined in <a href="01.html">NIP-01</a>. The relay keeps only the latest event for each pubkey + kind + <code>d</code>-tag-value triple. So the author can edit an article. Readers always fetch the newest version at the same address.</p>61 <p>The <code>content</code> is Markdown. Metadata such as the title, a cover image, and a summary travel in tags. A stable <a href="19.html">NIP-19</a> <code>naddr</code> code links to the article from anywhere.</p>62 <p>This NIP is optional. "Social" clients that deal primarily with kind-1 notes are not expected to implement it.</p>6364 <div class="box warn">65 <span class="tag">Warning!</span>66 <p><strong>Kind 30024 is deprecated.</strong> It carried long-form drafts: the same format as kind 30023, self-encrypted with <a href="04.html">NIP-04</a>. Do not use it for new drafts. Use <a href="37.html">NIP-37</a> draft events instead.</p>67 </div>6869 <div class="box tech">70 <span class="tag">Tech Note</span>71 <p>The source spec describes the deprecated kind 30024 only as "self-encrypted nip04, same format as kind 30023". It never specifies the encryption procedure in detail. Treat old 30024 events as best-effort legacy data. Also, the spec's own example event carries a <code>published_at</code> of <code>1296962229</code> (year 2011), earlier than its <code>created_at</code> and earlier than Nostr itself. It is placeholder data, not a rule.</p>72 </div>7374 <h2 class="bar" id="spec"><span class="num">2</span> Format</h2>75 <p>The <code>content</code> of a kind-30023 event is a string of text in Markdown syntax. The goal is maximum compatibility and readability across clients and devices. A client that creates long-form notes must follow two hard rules:</p>76 <ul>77 <li><strong>MUST NOT</strong> hard line-break paragraphs of text. Do not insert arbitrary line breaks, for example at 80-column boundaries.</li>78 <li><strong>MUST NOT</strong> support adding HTML to the Markdown.</li>79 </ul>8081 <div class="crt">82 <div class="titlebar">Wire format - kind 30023 article</div>83<pre>{84 <span class="k">"kind"</span>: 30023,85 <span class="k">"created_at"</span>: <span class="c">&lt;unix ts of the LAST update, seconds&gt;</span>,86 <span class="k">"content"</span>: <span class="c">&lt;article body, Markdown, no HTML, no hard line breaks&gt;</span>,87 <span class="k">"tags"</span>: [88 [<span class="s">"d"</span>, <span class="c">&lt;stable article identifier&gt;</span>],89 [<span class="s">"title"</span>, <span class="c">&lt;article title&gt;</span>], <span class="c">// optional</span>90 [<span class="s">"image"</span>, <span class="c">&lt;cover image URL&gt;</span>], <span class="c">// optional</span>91 [<span class="s">"summary"</span>, <span class="c">&lt;article summary&gt;</span>], <span class="c">// optional</span>92 [<span class="s">"published_at"</span>, <span class="c">&lt;unix ts, string&gt;</span>], <span class="c">// optional</span>93 [<span class="s">"t"</span>, <span class="c">&lt;topic hashtag&gt;</span>], ... <span class="c">// optional</span>94 ],95 <span class="k">"pubkey"</span>: <span class="c">&lt;author&gt;</span>, <span class="k">"id"</span>: <span class="c">&lt;...&gt;</span>, <span class="k">"sig"</span>: <span class="c">&lt;...&gt;</span>96}</pre>97 </div>9899 <h2 class="bar" id="metadata"><span class="num">3</span> Metadata Tags</h2>100 <p>Use the <code>created_at</code> field for the date of the last update. Use <code>t</code> tags for "tags" or "hashtags": topics for which the article is relevant. Other metadata fields can be added as tags when necessary. This NIP standardizes four of them. All four remain strictly optional.</p>101102 <div class="tscroll"><table class="ref">103 <caption>Metadata reference</caption>104 <tr><th>Tag / field</th><th>Value</th><th>Purpose</th></tr>105 <tr><td class="btn">d</td><td>string identifier</td><td>The stable address of the article. Required for editability. See §4.</td></tr>106 <tr><td class="btn">title</td><td>string</td><td>The article title.</td></tr>107 <tr><td class="btn">image</td><td>URL</td><td>An image to show along with the title.</td></tr>108 <tr><td class="btn">summary</td><td>string</td><td>The article summary.</td></tr>109 <tr><td class="btn">published_at</td><td>stringified unix seconds</td><td>The timestamp of the first time the article was published.</td></tr>110 <tr><td class="btn">t</td><td>string</td><td>A topic hashtag. Repeat the tag for each topic.</td></tr>111 <tr><td class="btn">created_at</td><td>unix seconds (event field)</td><td>The date of the last update.</td></tr>112 </table></div>113114 <div class="box hint">115 <span class="tag">Hint!</span>116 <p>Editing moves <code>created_at</code> forward with each revision. Keep <code>published_at</code> fixed at the first release. Show <code>published_at</code> as the byline date and <code>created_at</code> as "last updated".</p>117 </div>118119 <h2 class="bar" id="editability"><span class="num">4</span> Editability</h2>120 <p>Articles are meant to be editable. Each article must include a <code>d</code> tag with an identifier for the article. To publish a new version, sign a new kind-30023 event with the same <code>d</code> value. The relay replaces the old version.</p>121 <p>Clients should take care to publish and read these events only from relays that implement addressable replacement. If a relay does not implement it, clients should also take care to hide old versions of the same article that they may receive.</p>122123 <figure class="diagram">124 <div class="frame">125 <svg viewBox="0 0 560 250" role="img" aria-label="Author publishes an article, then an edit with the same d tag; the relay keeps only the latest version and serves it to the reader">126 <line class="d-wire" x1="90" y1="40" x2="90" y2="235" stroke-dasharray="3 4"/>127 <line class="d-wire" x1="280" y1="40" x2="280" y2="235" stroke-dasharray="3 4"/>128 <line class="d-wire" x1="470" y1="40" x2="470" y2="235" stroke-dasharray="3 4"/>129 <rect class="d-actor" x="40" y="8" width="100" height="30" rx="6"/>130 <text class="d-actor-label" x="90" y="28" text-anchor="middle">Author</text>131 <rect class="d-actor" x="230" y="8" width="100" height="30" rx="6"/>132 <text class="d-actor-label" x="280" y="28" text-anchor="middle">Relay</text>133 <rect class="d-actor" x="420" y="8" width="100" height="30" rx="6"/>134 <text class="d-actor-label" x="470" y="28" text-anchor="middle">Reader</text>135 <path class="d-msg" d="M90,62 L275,62"/>136 <text class="d-label" x="182" y="55" text-anchor="middle">EVENT 30023, d:"my-post", v1</text>137 <path class="d-msg d-flow" d="M90,102 L275,102"/>138 <text class="d-label" x="182" y="95" text-anchor="middle">EVENT 30023, d:"my-post", v2</text>139 <text class="d-note" x="280" y="130" text-anchor="middle">relay keeps only v2</text>140 <path class="d-msg" d="M470,158 L285,158"/>141 <text class="d-label" x="378" y="151" text-anchor="middle">REQ {"kinds":[30023], ...}</text>142 <path class="d-msg blue d-flow" d="M280,195 L465,195"/>143 <text class="d-label" x="378" y="188" text-anchor="middle">EVENT v2 (latest only)</text>144 <circle r="4" fill="#f26a00">145 <animateMotion dur="2.6s" repeatCount="indefinite" path="M90,102 L275,102"/>146 </circle>147 <circle r="4" fill="#2e5f9e">148 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M280,195 L465,195"/>149 </circle>150 </svg>151 </div>152 <figcaption>Fig. 23-1 — <b>Edit cycle.</b> A new event with the same <code>d</code> value replaces the old article. Readers get only the latest version.</figcaption>153 </figure>154155 <h2 class="bar" id="linking"><span class="num">5</span> Linking and References</h2>156 <p>Link to an article with the <a href="19.html">NIP-19</a> <code>naddr</code> code along with the <code>a</code> tag. The <code>a</code> tag form is defined in <a href="01.html">NIP-01</a>: <code>["a", "30023:&lt;pubkey&gt;:&lt;d value&gt;", &lt;relay URL, optional&gt;]</code>.</p>157 <p>References to other Nostr notes, articles, or profiles must follow <a href="27.html">NIP-27</a>. Write them inside the <code>content</code> as <a href="21.html">NIP-21</a> <code>nostr:...</code> links. Optionally add matching <code>e</code> or <code>a</code> tags for these references, as the example in §7 shows.</p>158159 <figure class="diagram">160 <div class="frame">161 <svg viewBox="0 0 560 130" role="img" aria-label="The active kind 30023 holds published articles; the deprecated kind 30024 draft flow is replaced by NIP-37">162 <rect class="d-actor" x="10" y="20" width="150" height="50" rx="8"/>163 <text class="d-actor-label" x="85" y="42" text-anchor="middle">kind 30023</text>164 <text class="d-note" x="85" y="59" text-anchor="middle">published article</text>165 <rect class="d-actor" x="10" y="82" width="150" height="40" rx="8" stroke-dasharray="4 3"/>166 <text class="d-actor-label" x="85" y="100" text-anchor="middle">kind 30024</text>167 <text class="d-note" x="85" y="115" text-anchor="middle">draft - DEPRECATED</text>168 <rect class="d-actor" x="400" y="20" width="150" height="50" rx="8"/>169 <text class="d-actor-label" x="475" y="42" text-anchor="middle">naddr + a tag</text>170 <text class="d-note" x="475" y="59" text-anchor="middle">stable address</text>171 <rect class="d-actor" x="400" y="82" width="150" height="40" rx="8"/>172 <text class="d-actor-label" x="475" y="100" text-anchor="middle">NIP-37 drafts</text>173 <text class="d-note" x="475" y="115" text-anchor="middle">preferred</text>174 <path class="d-msg d-flow" d="M162,45 L397,45"/>175 <text class="d-label" x="280" y="38" text-anchor="middle">linked by</text>176 <path class="d-msg blue" d="M162,102 L397,102"/>177 <text class="d-label" x="280" y="95" text-anchor="middle">replaced by</text>178 </svg>179 </div>180 <figcaption>Fig. 23-2 — <b>Kinds and addresses.</b> Kind 30023 is the article. The <code>naddr</code> code addresses it. Kind 30024 drafts give way to <a href="37.html">NIP-37</a>.</figcaption>181 </figure>182183 <h2 class="bar" id="replies"><span class="num">6</span> Replies and Comments</h2>184 <p>Replies to a kind-30023 article <strong>MUST</strong> use <a href="22.html">NIP-22</a> <code>kind 1111</code> comments. Do not reply with kind-1 notes. The comment carries the article's address, so it survives edits of the article.</p>185186 <h2 class="bar" id="examples"><span class="num">7</span> Worked Example</h2>187 <p>The event below is the spec's example article, published and then confirmed by the relay. The <code>content</code> holds NIP-27 <code>nostr:</code> references. The <code>e</code> and <code>a</code> tags mirror those references.</p>188 <div class="crt">189 <div class="titlebar">Session transcript - wss://relay.example.com</div>190<pre><span class="c">-- author publishes the article --</span>191<span class="send">→ ["EVENT", {192 "kind": 30023,193 "created_at": 1675642635,194 "content": "Lorem [ipsum][nostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g5…]195 dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt196 ut labore et dolore magna aliqua. […] Read more at nostr:naddr1qqzkjurnw4ksz…",197 "tags": [198 ["d", "lorem-ipsum"],199 ["title", "Lorem Ipsum"],200 ["published_at", "1296962229"],201 ["t", "placeholder"],202 ["e", "b3e392b11f5d4f28321cedd09303a748acfd0487aea5a7450b3481c60b6e4f87",203 "wss://relay.example.com"],204 ["a", "30023:a695f6b60119d9521934a691347d9f78e8770b56da16bb255ee286ddf9fda919:ipsum",205 "wss://relay.nostr.org"]206 ],207 "pubkey": "…", "id": "…", "sig": "…"208 }]</span>209<span class="recv">← ["OK", "…", true, ""]</span>210211<span class="c">-- a reader fetches the article by address --</span>212<span class="send">→ ["REQ", "art", {"kinds":[30023], "authors":["…"], "#d":["lorem-ipsum"]}]</span>213<span class="recv">← ["EVENT", "art", { "kind":30023, "tags":[["d","lorem-ipsum"], …], … }]</span>214<span class="recv">← ["EOSE", "art"]</span></pre>215 </div>216217 <h2 class="bar" id="history"><span class="num">8</span> Version History</h2>218 <p>NIP-23 changed its addressing scheme several times in its first weeks. Then it settled. Notable changes, newest first:</p>219 <ul class="patchnotes">220 <li><span class="ver">2026</span><span class="when">2026-05</span>Deprecated <code>kind 30024</code> drafts in favor of <a href="37.html">NIP-37</a>.</li>221 <li><span class="ver">2025</span><span class="when">2025-03</span>Replies to articles must use <a href="22.html">NIP-22</a> <code>kind 1111</code> comments.</li>222 <li class="minor"><span class="ver">2024</span><span class="when">2024</span>Renamed "parameterized replaceable event" to "addressable event"; removed a stale <a href="12.html">NIP-12</a> mention.</li>223 <li><span class="ver">2023</span><span class="when">2023-07</span>Added the formatting rules: no hard line breaks, no HTML in Markdown (William Casarin).</li>224 <li><span class="ver">2023</span><span class="when">2023-05</span>Suggested <code>kind 30024</code> for encrypted drafts (Alejandro Gomez).</li>225 <li><span class="ver">2023</span><span class="when">2023-03</span>Switched references in <code>content</code> to <a href="27.html">NIP-27</a> <code>nostr:</code> links.</li>226 <li class="minor"><span class="ver">2023</span><span class="when">2023-02</span>Early churn: <code>nref</code> became <code>nitem</code>, then <code>naddr</code>; the <code>i</code> tag became <code>a</code>; the YAML frontmatter and the NIP-01 bridge event were dropped.</li>227 <li><span class="ver">Origin</span><span class="when">2023-02-03</span>fiatjaf published "NIP-23: long-form content."</li>228 </ul>229230 <div class="credits">231 <h3 class="cardhead">Original Proposal - Credits</h3>232 <table>233 <tr><td>Author</td><td>fiatjaf</td></tr>234 <tr><td>First commit</td><td>2023-02-03 — “NIP-23: long-form content.”</td></tr>235 <tr><td>Status</td><td>draft - optional — social clients may skip it</td></tr>236 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/23.md">23.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/23.md">full change history</a></td></tr>237 </table>238 </div>239240 <h2 class="bar"><span class="num">9</span> See Also</h2>241 <ul>242 <li><a href="01.html">NIP-01</a> — addressable events, the <code>d</code> tag, and the <code>a</code> tag that this NIP builds on.</li>243 <li><a href="22.html">NIP-22</a> — <code>kind 1111</code> comments, the mandatory reply format for articles.</li>244 <li><a href="19.html">NIP-19</a> — the <code>naddr</code> bech32 code that links to an article.</li>245 <li><a href="21.html">NIP-21</a> — the <code>nostr:</code> URI scheme used inside the Markdown.</li>246 <li><a href="27.html">NIP-27</a> — how to write references to notes and profiles in <code>content</code>.</li>247 <li><a href="37.html">NIP-37</a> — draft events, the replacement for deprecated <code>kind 30024</code>.</li>248 </ul>249 </div>250251 <aside>252 <div class="cartridge">253 <div class="inner">254 <h3 class="cardhead">Spec Card</h3>255 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>256 <dl>257 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span></dd>258 <dt>Defines</dt><dd>kind 30023 - title/image/summary/published_at tags</dd>259 <dt>Kinds</dt><dd>30023 (30024 deprecated)</dd>260 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="19.html">NIP-19</a> - <a href="21.html">NIP-21</a> - <a href="22.html">NIP-22</a> - <a href="27.html">NIP-27</a></dd>261 <dt>Content</dt><dd>Markdown - no HTML - no hard breaks</dd>262 <dt>First commit</dt><dd>2023-02-03</dd>263 <dt>Last updated</dt><dd>2026-05-18</dd>264 </dl>265 </div>266 </div>267 </aside>268 </main>269270 <nav class="navbtns">271 <a href="22.html">◀ NIP-22: Comment</a>272 <a href="24.html">NIP-24: Extra Metadata Fields and Tags ▶</a>273 </nav>274275 <footer class="pagefoot">276 <a href="../index.html">Nostr Protocol Manual</a>277 <span class="pageno">NIP 23 / F4</span>278 </footer>279</div>280281<script src="../assets/webmcp.js" defer></script>282</body>283</html>