clone

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

main
nip.guide / site / nips / 21.html
21.html 17.7K
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-21 - `nostr:` URI scheme — Nostr Instruction Manual</title>7<meta name="description" content="NIP-21: the nostr: URI scheme. One URI prefix for NIP-19 identifiers, plus HTML link tags that bind webpages to Nostr events and profiles.">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 21 - Interop</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="21">21</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 21</div>50 <h1><code>nostr:</code> URI scheme</h1>51 <p class="sub">One URI prefix that lets any webpage, app, or operating system point at a Nostr profile or event.</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 identifiers live inside Nostr apps. The rest of the world runs on links. This NIP standardizes one common URI scheme, <code>nostr:</code>, so any program can link to a Nostr entity. The goal is maximum interoperability and openness in the network.</p>60 <p>A <code>nostr:</code> URI is a prefix plus one <a href="19.html">NIP-19</a> bech32 identifier. A webpage can link to a profile. An email can link to an event. An operating system can route the click to the user's preferred Nostr client. No app needs to know which client the user prefers.</p>61 <p>The NIP also defines the reverse direction. An HTML page can declare, with standard <code>&lt;link&gt;</code> tags, that its content or its author also exists on Nostr. Section 3 covers this.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>Register your client as the system handler for the <code>nostr:</code> scheme. Then every <code>nostr:</code> link on the web becomes a door into your app. Users click once and land on the right profile or event.</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 130" role="img" aria-label="A nostr: link on a webpage opens the system handler, which starts a Nostr client, which decodes the NIP-19 identifier and fetches the entity from relays">71 <rect class="d-actor" x="10" y="35" width="110" height="50" rx="8"/>72 <text class="d-actor-label" x="65" y="57" text-anchor="middle">Webpage</text>73 <text class="d-note" x="65" y="74" text-anchor="middle">nostr: link</text>74 <rect class="d-actor" x="160" y="35" width="110" height="50" rx="8"/>75 <text class="d-actor-label" x="215" y="57" text-anchor="middle">OS handler</text>76 <text class="d-note" x="215" y="74" text-anchor="middle">scheme = nostr</text>77 <rect class="d-actor" x="310" y="35" width="110" height="50" rx="8"/>78 <text class="d-actor-label" x="365" y="57" text-anchor="middle">Client</text>79 <text class="d-note" x="365" y="74" text-anchor="middle">decode NIP-19</text>80 <rect class="d-actor" x="460" y="35" width="90" height="50" rx="8"/>81 <text class="d-actor-label" x="505" y="57" text-anchor="middle">Relays</text>82 <text class="d-note" x="505" y="74" text-anchor="middle">fetch entity</text>83 <path class="d-msg d-flow" d="M122,60 L157,60"/>84 <path class="d-msg d-flow" d="M272,60 L307,60"/>85 <path class="d-msg d-flow" d="M422,60 L457,60"/>86 <circle r="4" fill="#f26a00">87 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,60 L157,60 M272,60 L307,60 M422,60 L457,60"/>88 </circle>89 </svg>90 </div>91 <figcaption>Fig. 21-1 — <b>Click-to-client flow.</b> A <code>nostr:</code> link travels from webpage to handler to client. The client decodes the identifier and fetches the entity.</figcaption>92 </figure>9394 <h2 class="bar" id="spec"><span class="num">2</span> The URI Scheme</h2>95 <p>The scheme is <code>nostr:</code>. The identifier that comes after the colon is expected to be the same as an identifier defined in <a href="19.html">NIP-19</a>, except <code>nsec</code>. A private key must never appear in a link.</p>9697 <div class="crt">98 <div class="titlebar">URI format</div>99<pre><span class="k">nostr:</span><span class="c">&lt;NIP-19 bech32 identifier, any prefix except nsec&gt;</span></pre>100 </div>101102 <div class="tscroll"><table class="ref">103 <caption>NIP-19 identifiers inside a nostr: URI</caption>104 <tr><th>Prefix</th><th>Points to</th><th>Allowed?</th></tr>105 <tr><td class="btn">npub</td><td>a public key</td><td>Yes.</td></tr>106 <tr><td class="btn">nprofile</td><td>a profile, with relay hints</td><td>Yes.</td></tr>107 <tr><td class="btn">nevent</td><td>an event, with relay hints</td><td>Yes.</td></tr>108 <tr><td class="btn">naddr</td><td>an addressable event coordinate</td><td>Yes.</td></tr>109 <tr><td class="btn">note</td><td>a bare event id</td><td>Not excluded by the text. See the Tech Note below.</td></tr>110 <tr><td class="btn">nsec</td><td>a private key</td><td>Never. The one explicit exclusion.</td></tr>111 </table></div>112113 <p>The source spec lists these example URIs:</p>114 <div class="crt">115 <div class="titlebar">Example nostr: URIs</div>116<pre><span class="c">-- a public key --</span>117nostr:<span class="s">npub1sn0wdenkukak0d9dfczzeacvhkrgz92ak56egt7vdgzn8pv2wfqqhrjdv9</span>118119<span class="c">-- a profile with relay hints --</span>120nostr:<span class="s">nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p</span>121122<span class="c">-- an event with relay hints --</span>123nostr:<span class="s">nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm</span></pre>124 </div>125126 <div class="box warn">127 <span class="tag">Warning!</span>128 <p>Never build a <code>nostr:</code> URI around an <code>nsec</code> identifier. A URI is made to be shared. A shared <code>nsec</code> is a leaked private key, and the account it controls is lost.</p>129 </div>130131 <div class="box tech">132 <span class="tag">Tech Note</span>133 <p>The spec excludes only <code>nsec</code>. It does not exclude <code>note</code>. Yet a 2026-03 edit removed all <code>note1</code> mentions from the document. So <code>nostr:note1…</code> is not forbidden by the text, but the spec no longer shows it. Prefer <code>nevent</code>, which carries relay hints. The spec also gives no rule for unknown or malformed identifiers; handling is left to the client.</p>134 </div>135136 <h2 class="bar" id="linking"><span class="num">3</span> Linking HTML Pages to Nostr Entities</h2>137 <p>Some content exists in two mediums at once. For example, a web server exposes Markdown articles as HTML pages and also as <code>kind:30023</code> events, served under itself as a relay or through some other relay. Standard HTML <code>&lt;link&gt;</code> tags bind the two copies together. The <code>href</code> of each tag is a <code>nostr:</code> URI.</p>138139 <div class="tscroll"><table class="ref">140 <caption>Link relations</caption>141 <tr><th>rel value</th><th>Associates the page with</th><th>Typical href</th></tr>142 <tr><td class="btn">alternate</td><td>the Nostr event that carries the same content</td><td><code>nostr:naddr1…</code> or another event identifier</td></tr>143 <tr><td class="btn">me</td><td>the Nostr profile of the page's owner</td><td><code>nostr:nprofile1…</code> or <code>nostr:npub1…</code></td></tr>144 <tr><td class="btn">author</td><td>the Nostr profile of the page's author</td><td><code>nostr:nprofile1…</code> or <code>nostr:npub1…</code></td></tr>145 </table></div>146147 <p>Use <code>rel="alternate"</code> when the same content is served via the two mediums. Use <code>rel="me"</code> or <code>rel="author"</code> to assign authorship of a webpage to a Nostr profile. A crawler or a browser extension reads these tags and offers the Nostr version of the page or its author.</p>148149 <figure class="diagram">150 <div class="frame">151 <svg viewBox="0 0 560 170" role="img" aria-label="An HTML head links with rel alternate to a kind 30023 event and with rel me or author to a Nostr profile">152 <rect class="d-actor" x="10" y="60" width="140" height="50" rx="8"/>153 <text class="d-actor-label" x="80" y="82" text-anchor="middle">HTML page</text>154 <text class="d-note" x="80" y="99" text-anchor="middle">&lt;head&gt; link tags</text>155 <rect class="d-actor" x="400" y="14" width="150" height="50" rx="8"/>156 <text class="d-actor-label" x="475" y="36" text-anchor="middle">Event</text>157 <text class="d-note" x="475" y="53" text-anchor="middle">kind:30023 article</text>158 <rect class="d-actor" x="400" y="106" width="150" height="50" rx="8"/>159 <text class="d-actor-label" x="475" y="128" text-anchor="middle">Profile</text>160 <text class="d-note" x="475" y="145" text-anchor="middle">page owner / author</text>161 <path class="d-msg d-flow" d="M152,74 C260,60 300,48 397,40"/>162 <path class="d-msg blue d-flow" d="M152,96 C260,110 300,122 397,130"/>163 <text class="d-label" x="272" y="40" text-anchor="middle">rel="alternate" - nostr:naddr1…</text>164 <text class="d-label" x="272" y="126" text-anchor="middle">rel="me" / "author" - nostr:nprofile1…</text>165 <circle r="4" fill="#f26a00">166 <animateMotion dur="2.6s" repeatCount="indefinite" path="M152,74 C260,60 300,48 397,40"/>167 </circle>168 <circle r="4" fill="#2e5f9e">169 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M152,96 C260,110 300,122 397,130"/>170 </circle>171 </svg>172 </div>173 <figcaption>Fig. 21-2 — <b>Page-to-Nostr association.</b> One page declares its Nostr twin with <code>rel="alternate"</code> and its Nostr author with <code>rel="me"</code> or <code>rel="author"</code>.</figcaption>174 </figure>175176 <h2 class="bar" id="examples"><span class="num">4</span> Worked Examples</h2>177 <p>The first block is the spec's own example of a page that serves the same article as a <code>kind:30023</code> event. The <code>naddr</code> identifier names the addressable event coordinate.</p>178 <div class="crt">179 <div class="titlebar">HTML - rel="alternate" to a kind:30023 event</div>180<pre>&lt;<span class="k">head</span>&gt;181 &lt;<span class="k">link</span> rel=<span class="s">"alternate"</span> href=<span class="s">"nostr:naddr1qqyrzwrxvc6ngvfkqyghwumn8ghj7enfv182 96x5ctx9e3k7mgzyqalp33lewf5vdq847t6te0wvnags0gs0mu72kz8938tn24wlfze6qc183 yqqq823cph95ag"</span> /&gt;184&lt;/<span class="k">head</span>&gt;</pre>185 </div>186187 <p>The second block assigns authorship of a webpage to a Nostr profile. The <code>rel="me"</code> and <code>rel="author"</code> relations work the same way; the spec shows <code>rel="me"</code>.</p>188 <div class="crt">189 <div class="titlebar">HTML - rel="me" to a Nostr profile</div>190<pre>&lt;<span class="k">head</span>&gt;191 &lt;<span class="k">link</span> rel=<span class="s">"me"</span> href=<span class="s">"nostr:nprofile1qyxhwumn8ghj7mn0wvhxcmmvqyd8wumn8ghj7192 un9d3shjtnhv4ehgetjde38gcewvdhk6qpq80cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j193 4s3evf6u64th6gkwswpnfsn"</span> /&gt;194&lt;/<span class="k">head</span>&gt;</pre>195 </div>196197 <p>The third block shows the client side. The client receives a <code>nostr:</code> URI from the OS handler. It decodes the <a href="19.html">NIP-19</a> payload, reads the relay hints, and fetches the entity with a normal <a href="01.html">NIP-01</a> subscription.</p>198 <div class="crt">199 <div class="titlebar">Client session - resolving a nostr:nevent1… URI</div>200<pre><span class="c">-- OS hands the client: nostr:nevent1qqstna2yre… --</span>201<span class="c">-- client decodes: id = 5c83…, relays = wss://relay.example.com --</span>202<span class="send">→ ["REQ", "uri1", {"ids":["5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]}]</span>203<span class="recv">← ["EVENT", "uri1", {"id":"5c83da77af1d…", "kind":1, "content":"…", …}]</span>204<span class="recv">← ["EOSE", "uri1"]</span>205<span class="send">→ ["CLOSE", "uri1"]</span>206<span class="c">-- client renders the event --</span></pre>207 </div>208209 <h2 class="bar" id="history"><span class="num">5</span> Version History</h2>210 <p>NIP-21 is short and stable. It gained one major feature since birth: the HTML link associations. Notable changes, newest first:</p>211 <ul class="patchnotes">212 <li><span class="ver">2026</span><span class="when">2026-03</span>Removed all mentions of <code>note1</code> identifiers from the examples.</li>213 <li><span class="ver">2025</span><span class="when">2025-05</span>Added the HTML <code>&lt;link&gt;</code> associations: <code>rel="alternate"</code> for events, <code>rel="me"</code> and <code>rel="author"</code> for profiles.</li>214 <li><span class="ver">2023</span><span class="when">2023-05</span>Renamed the feature from "URL scheme" to "URI scheme".</li>215 <li class="minor"><span class="ver">2023+</span><span class="when">2023-2025</span>Housekeeping: author list removed, links made relative, markup fixes.</li>216 <li><span class="ver">Origin</span><span class="when">2023-01</span>fiatjaf added NIP-21, the <code>nostr:</code> url scheme.</li>217 </ul>218219 <div class="credits">220 <h3 class="cardhead">Original Proposal - Credits</h3>221 <table>222 <tr><td>Author</td><td>fiatjaf</td></tr>223 <tr><td>First commit</td><td>2023-01-24 — “add NIP-21, `nostr:` url scheme.”</td></tr>224 <tr><td>Status</td><td>draft - optional — implement it to make your entities linkable</td></tr>225 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/21.md">21.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/21.md">full change history</a></td></tr>226 </table>227 </div>228229 <h2 class="bar"><span class="num">6</span> See Also</h2>230 <ul>231 <li><a href="19.html">NIP-19</a> — defines the bech32 identifiers that follow the <code>nostr:</code> prefix.</li>232 <li><a href="01.html">NIP-01</a> — the base protocol; how a client fetches the entity a URI names.</li>233 <li><a href="23.html">NIP-23</a> — <code>kind:30023</code> long-form articles, the spec's example for <code>rel="alternate"</code>.</li>234 <li><a href="27.html">NIP-27</a> — how <code>nostr:</code> URIs appear inside event <code>content</code> as text mentions.</li>235 <li><a href="05.html">NIP-05</a> — another bridge between the web and Nostr identities, via DNS names.</li>236 </ul>237 </div>238239 <aside>240 <div class="cartridge">241 <div class="inner">242 <h3 class="cardhead">Spec Card</h3>243 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>244 <dl>245 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span></dd>246 <dt>Defines</dt><dd><code>nostr:</code> URI scheme - rel="alternate"/"me"/"author" links</dd>247 <dt>Kinds</dt><dd>none — links to existing events</dd>248 <dt>Requires</dt><dd><a href="19.html">NIP-19</a> identifiers - <a href="01.html">NIP-01</a></dd>249 <dt>Transport</dt><dd>URI - HTML link tags</dd>250 <dt>First commit</dt><dd>2023-01-24</dd>251 <dt>Last updated</dt><dd>2026-03-20</dd>252 </dl>253 </div>254 </div>255 </aside>256 </main>257258 <nav class="navbtns">259 <a href="20.html">◀ NIP-20: Command Results</a>260 <a href="22.html">NIP-22: Comment ▶</a>261 </nav>262263 <footer class="pagefoot">264 <a href="../index.html">Nostr Protocol Manual</a>265 <span class="pageno">NIP 21 / F4</span>266 </footer>267</div>268269<script src="../assets/webmcp.js" defer></script>270</body>271</html>