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-43 - Relay Access Metadata and Requests — Nostr Instruction Manual</title>7<meta name="description" content="NIP-43: relays advertise roles and membership lists; clients request to join or leave a relay with invite codes. 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 43 - Relay Ops</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="43">43</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 43</div>50 <h1>Relay Access Metadata and Requests</h1>51 <p class="sub">A members-only relay that can say who belongs, and a front door where clients ask to get in.</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>Some relays are private clubs. Only members can write, and sometimes only members can read. Before this NIP, a locked-out user had no protocol-level way to ask for a key. This NIP gives relays a voice and users a doorbell.</p>60 <p>The relay side is <strong>metadata</strong>. A relay publishes events that define member <strong>roles</strong>, list its <strong>members</strong>, and announce when a member is added or removed. The relay signs these events with its own identity key: the pubkey in the <code>self</code> field of its <a href="11.html">NIP-11</a> information document.</p>61 <p>The user side is <strong>requests</strong>. A user sends a <strong>join request</strong> with an invite code, asks the relay for an <strong>invite code</strong>, or sends a <strong>leave request</strong> to give up access. The relay answers each join request with a plain <a href="01.html">NIP-01</a> <code>OK</code> message.</p>62 <p>Every event in this NIP carries the <a href="70.html">NIP-70</a> protected tag: a tag named <code>-</code>. It marks the event as protected, so other relays must not accept it from anyone except its author.</p>6364 <figure class="diagram">65 <div class="frame">66 <svg viewBox="0 0 560 200" role="img" aria-label="The relay publishes role, membership, and add or remove events; the user sends join, invite, and leave requests">67 <rect class="d-actor" x="10" y="75" width="110" height="50" rx="8"/>68 <text class="d-actor-label" x="65" y="104" text-anchor="middle">User</text>69 <rect class="d-actor" x="440" y="75" width="110" height="50" rx="8"/>70 <text class="d-actor-label" x="495" y="104" text-anchor="middle">Relay</text>71 <path class="d-msg d-flow" d="M122,88 C240,60 320,60 438,88"/>72 <text class="d-label" x="280" y="60" text-anchor="middle">28934 join - 28936 leave</text>73 <path class="d-msg blue d-flow" d="M438,112 C320,140 240,140 122,112"/>74 <text class="d-label" x="280" y="152" text-anchor="middle">33534 roles - 13534 members - 8000/8001 - 28935 invite</text>75 <text class="d-note" x="280" y="180" text-anchor="middle">Relay events are signed by the NIP-11 "self" pubkey.</text>76 <circle r="4" fill="#f26a00">77 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,88 C240,60 320,60 438,88"/>78 </circle>79 <circle r="4" fill="#2e5f9e">80 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M438,112 C320,140 240,140 122,112"/>81 </circle>82 </svg>83 </div>84 <figcaption>Fig. 43-1 — <b>Two directions.</b> The relay publishes access metadata. The user sends access requests.</figcaption>85 </figure>8687 <div class="tscroll"><table class="ref">88 <caption>Event kinds in this NIP</caption>89 <tr><th>Kind</th><th>Name</th><th>Signer</th><th>Storage class</th></tr>90 <tr><td class="btn">33534</td><td>Role definition</td><td>relay</td><td>addressable</td></tr>91 <tr><td class="btn">13534</td><td>Membership list</td><td>relay</td><td>replaceable</td></tr>92 <tr><td class="btn">8000</td><td>Add user</td><td>relay</td><td>regular</td></tr>93 <tr><td class="btn">8001</td><td>Remove user</td><td>relay</td><td>regular</td></tr>94 <tr><td class="btn">28934</td><td>Join request</td><td>user</td><td>ephemeral</td></tr>95 <tr><td class="btn">28935</td><td>Invite</td><td>relay</td><td>ephemeral</td></tr>96 <tr><td class="btn">28936</td><td>Leave request</td><td>user</td><td>ephemeral</td></tr>97 </table></div>9899 <h2 class="bar" id="spec"><span class="num">2</span> Role Definitions — Kind 33534</h2>100 <p>A relay may publish a <code>kind 33534</code> event to define a role. A role is a named position that the relay can assign to members. The relay must sign the event with the <a href="11.html">NIP-11</a> <code>self</code> pubkey.</p>101 <p>Two tags are required:</p>102 <ul>103 <li>The <a href="70.html">NIP-70</a> <code>-</code> tag.</li>104 <li>A <code>d</code> tag. Its value is the role id.</li>105 </ul>106 <p>Four tags are optional:</p>107 <div class="tscroll"><table class="ref">108 <caption>Optional role tags</caption>109 <tr><th>Tag</th><th>Value</th></tr>110 <tr><td class="btn">label</td><td>A label for the role.</td></tr>111 <tr><td class="btn">description</td><td>A description of the role.</td></tr>112 <tr><td class="btn">color</td><td>A hue value from <code>0</code> to <code>360</code> for the role.</td></tr>113 <tr><td class="btn">order</td><td>An order integer for the role. Clients use it for display only.</td></tr>114 </table></div>115 <div class="crt">116 <div class="titlebar">Wire format - role definition</div>117<pre>{118 <span class="k">"kind"</span>: 33534,119 <span class="k">"pubkey"</span>: <span class="c"><nip11.self></span>,120 <span class="k">"tags"</span>: [121 [<span class="s">"-"</span>],122 [<span class="s">"d"</span>, <span class="s">"28b7e50f"</span>],123 [<span class="s">"label"</span>, <span class="s">"king"</span>],124 [<span class="s">"description"</span>, <span class="s">"ruler of the relay"</span>],125 [<span class="s">"color"</span>, <span class="s">"37"</span>],126 [<span class="s">"order"</span>, <span class="s">"1"</span>]127 ]128 <span class="c">// ...other fields</span>129}</pre>130 </div>131 <p>A relay may treat members with a given role differently in its access policies. The NIP defines no mechanism to inspect those policies at this time.</p>132133 <h2 class="bar" id="members"><span class="num">3</span> Membership Lists — Kind 13534</h2>134 <p>A relay may publish a <code>kind 13534</code> event to list the pubkeys that have access to it. The relay must sign the event with the <a href="11.html">NIP-11</a> <code>self</code> pubkey.</p>135 <p>Two tags are required:</p>136 <ul>137 <li>The <a href="70.html">NIP-70</a> <code>-</code> tag.</li>138 <li>One <code>member</code> tag per member. Its value is the member's hex pubkey. Assigned role ids may follow as later elements of the same tag.</li>139 </ul>140 <div class="crt">141 <div class="titlebar">Wire format - membership list</div>142<pre>{143 <span class="k">"kind"</span>: 13534,144 <span class="k">"pubkey"</span>: <span class="c"><nip11.self></span>,145 <span class="k">"tags"</span>: [146 [<span class="s">"-"</span>],147 [<span class="s">"member"</span>, <span class="s">"c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5"</span>],148 [<span class="s">"member"</span>, <span class="s">"ee1d336e13779e4d4c527b988429d96de16088f958cbf6c074676ac9cfd9c958"</span>, <span class="s">"28b7e50f"</span>]149 ]150 <span class="c">// ...other fields</span>151}</pre>152 </div>153 <div class="box warn">154 <span class="tag">Warning!</span>155 <p>The list is not exhaustive and not authoritative. To determine membership, consult two events: the relay's <code>kind 13534</code> list and the member's own <code>kind 10010</code> event.</p>156 </div>157 <div class="box tech">158 <span class="tag">Tech Note</span>159 <p>The source references a <code>kind 10010</code> event by the member but does not define it and does not link a NIP that does. The pointer is unresolved as written.</p>160 </div>161162 <h2 class="bar" id="announce"><span class="num">4</span> Add and Remove Announcements — Kinds 8000 / 8001</h2>163 <p>A relay may publish a <code>kind 8000</code> event when it adds a member. A relay may publish a <code>kind 8001</code> event when it removes a member. Both events must be signed with the <a href="11.html">NIP-11</a> <code>self</code> pubkey. Both events require two tags:</p>164 <ul>165 <li>The <a href="70.html">NIP-70</a> <code>-</code> tag.</li>166 <li>A <code>p</code> tag with the member's hex pubkey.</li>167 </ul>168 <div class="crt">169 <div class="titlebar">Wire format - add user / remove user</div>170<pre>{171 <span class="k">"kind"</span>: 8000, <span class="c">// or 8001 to remove</span>172 <span class="k">"pubkey"</span>: <span class="c"><nip11.self></span>,173 <span class="k">"tags"</span>: [174 [<span class="s">"-"</span>],175 [<span class="s">"p"</span>, <span class="s">"c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5"</span>]176 ]177 <span class="c">// ...other fields</span>178}</pre>179 </div>180181 <h2 class="bar" id="join"><span class="num">5</span> Join Request — Kind 28934</h2>182 <p>A user may send a <code>kind 28934</code> event to a relay to request admission. The event must have a <code>claim</code> tag that holds an invite code. The event's <code>created_at</code> must be now, plus or minus a few minutes.</p>183 <div class="crt">184 <div class="titlebar">Wire format - join request</div>185<pre>{186 <span class="k">"kind"</span>: 28934,187 <span class="k">"pubkey"</span>: <span class="c"><user pubkey></span>,188 <span class="k">"tags"</span>: [189 [<span class="s">"-"</span>],190 [<span class="s">"claim"</span>, <span class="c"><invite code></span>]191 ]192 <span class="c">// ...other fields</span>193}</pre>194 </div>195 <p>When a relay receives a claim, it must report the status of the claim in an <code>OK</code> message. Failed claims should use the standard <code>restricted:</code> prefix from <a href="42.html">NIP-42</a>. On success, the relay should update its <code>kind 13534</code> member list. It may also publish a <code>kind 8000</code> add-user event.</p>196 <div class="crt">197 <div class="titlebar">OK responses to a claim</div>198<pre><span class="recv">← ["OK", <event-id>, false, "restricted: that invite code is expired."]</span>199<span class="recv">← ["OK", <event-id>, false, "restricted: that is an invalid invite code."]</span>200<span class="recv">← ["OK", <event-id>, true, "duplicate: you are already a member of this relay."]</span>201<span class="recv">← ["OK", <event-id>, true, "info: welcome to wss://relay.bunk.skunk!"]</span></pre>202 </div>203 <div class="box tech">204 <span class="tag">Tech Note</span>205 <p>Two small gaps in the source. First, the join-request example carries the <code>-</code> tag, but the prose lists only <code>claim</code> as required. Second, the sample replies use <code>info:</code>, which is not a standard <a href="01.html">NIP-01</a> <code>OK</code> prefix.</p>206 </div>207208 <h2 class="bar" id="invite"><span class="num">6</span> Invite Request — Kind 28935</h2>209 <p>A user may ask a relay for a claim string. To do this, the user requests <code>kind 28935</code> events with a normal <a href="01.html">NIP-01</a> <code>REQ</code> subscription. The relay answers with a <code>kind 28935</code> event. That event must be signed with the <a href="11.html">NIP-11</a> <code>self</code> pubkey.</p>210 <div class="crt">211 <div class="titlebar">Wire format - invite</div>212<pre>{213 <span class="k">"kind"</span>: 28935,214 <span class="k">"pubkey"</span>: <span class="c"><nip11.self></span>,215 <span class="k">"tags"</span>: [216 [<span class="s">"-"</span>],217 [<span class="s">"claim"</span>, <span class="c"><invite code></span>]218 ]219 <span class="c">// ...other fields</span>220}</pre>221 </div>222 <div class="box hint">223 <span class="tag">Hint!</span>224 <p>Kind 28935 sits in the ephemeral range, so relays store nothing. A relay must opt in and generate claims on the fly when a request arrives. This improves security: the relay can issue a different claim per request, issue claims only to certain users, or expire claims.</p>225 </div>226227 <h2 class="bar" id="leave"><span class="num">7</span> Leave Request — Kind 28936</h2>228 <p>A user may send a <code>kind 28936</code> event to a relay to request that their access be revoked. The event must include the <a href="70.html">NIP-70</a> <code>-</code> tag. The event's <code>created_at</code> must be now, plus or minus a few minutes.</p>229 <div class="crt">230 <div class="titlebar">Wire format - leave request</div>231<pre>{232 <span class="k">"kind"</span>: 28936,233 <span class="k">"tags"</span>: [[<span class="s">"-"</span>]]234 <span class="c">// ...other fields</span>235}</pre>236 </div>237 <p>On a leave request, the relay should update its <code>kind 13534</code> member list. It may also publish a <code>kind 8001</code> remove-user event.</p>238239 <h2 class="bar" id="impl"><span class="num">8</span> Implementation Rule</h2>240 <p>Clients must check the relay's <a href="11.html">NIP-11</a> information document first. Only when <code>supported_nips</code> includes this NIP may a client request <code>kind 28935</code> events from the relay or send <code>kind 28934</code> events to it.</p>241242 <figure class="diagram">243 <div class="frame">244 <svg viewBox="0 0 560 300" role="img" aria-label="Sequence diagram: client fetches an invite, sends a join request, relay replies OK, updates the member list, and announces the new member">245 <line class="d-wire" x1="110" y1="40" x2="110" y2="285" stroke-dasharray="3 4"/>246 <line class="d-wire" x1="450" y1="40" x2="450" y2="285" stroke-dasharray="3 4"/>247 <rect class="d-actor" x="55" y="8" width="110" height="30" rx="6"/>248 <text class="d-actor-label" x="110" y="28" text-anchor="middle">Client</text>249 <rect class="d-actor" x="395" y="8" width="110" height="30" rx="6"/>250 <text class="d-actor-label" x="450" y="28" text-anchor="middle">Relay</text>251 <path class="d-msg" d="M110,62 L445,62"/>252 <text class="d-label" x="280" y="55" text-anchor="middle">["REQ", "inv", {"kinds":[28935]}]</text>253 <path class="d-msg blue" d="M450,95 L115,95"/>254 <text class="d-label" x="280" y="88" text-anchor="middle">["EVENT", "inv", {kind 28935, claim}]</text>255 <path class="d-msg d-flow" d="M110,133 L445,133"/>256 <text class="d-label" x="280" y="126" text-anchor="middle">["EVENT", {kind 28934, ["claim", …]}]</text>257 <path class="d-msg blue" d="M450,171 L115,171"/>258 <text class="d-label" x="280" y="164" text-anchor="middle">["OK", <id>, true, "info: welcome!"]</text>259 <path class="d-msg blue" d="M450,209 L115,209"/>260 <text class="d-label" x="280" y="202" text-anchor="middle">kind 13534 updated - kind 8000 published</text>261 <text class="d-note" x="280" y="250" text-anchor="middle">The user is now a member. Access policy is up to the relay.</text>262 <circle r="4" fill="#f26a00">263 <animateMotion dur="2.6s" repeatCount="indefinite" path="M110,133 L445,133"/>264 </circle>265 </svg>266 </div>267 <figcaption>Fig. 43-2 — <b>Admission flow.</b> Fetch an invite, send the claim, get an <code>OK</code>, appear in the member list.</figcaption>268 </figure>269270 <h2 class="bar" id="examples"><span class="num">9</span> Worked Example</h2>271 <p>The session below shows a full admission. Alice's client checks NIP-11 support out of band, fetches an invite, joins, and later leaves. Orange lines go to the relay. Blue lines come from the relay.</p>272 <div class="crt">273 <div class="titlebar">Session transcript - wss://club.example.com</div>274<pre><span class="c">-- 1. fetch an invite (relay supports NIP-43 per its NIP-11 document) --</span>275<span class="send">→ ["REQ", "inv", {"kinds":[28935]}]</span>276<span class="recv">← ["EVENT", "inv", {"kind":28935, "pubkey":"a1b2c3d4…",277 "tags":[["-"],["claim","XK42-MEOW"]], …}]</span>278<span class="recv">← ["EOSE", "inv"]</span>279<span class="send">→ ["CLOSE", "inv"]</span>280281<span class="c">-- 2. join with the claim --</span>282<span class="send">→ ["EVENT", {"kind":28934, "pubkey":"c308e1f8…", "created_at":1782796800,283 "tags":[["-"],["claim","XK42-MEOW"]], "content":"", "sig":"…"}]</span>284<span class="recv">← ["OK", "7f31aa02…", true, "info: welcome to wss://club.example.com!"]</span>285286<span class="c">-- 3. the relay updates its metadata --</span>287<span class="recv">← ["EVENT", "meta", {"kind":8000, "pubkey":"a1b2c3d4…",288 "tags":[["-"],["p","c308e1f8…"]], …}]</span>289<span class="recv">← ["EVENT", "meta", {"kind":13534, "pubkey":"a1b2c3d4…",290 "tags":[["-"],["member","c308e1f8…"]], …}]</span>291292<span class="c">-- 4. months later, alice leaves --</span>293<span class="send">→ ["EVENT", {"kind":28936, "pubkey":"c308e1f8…", "tags":[["-"]], …}]</span>294<span class="recv">← ["EVENT", "meta", {"kind":8001, "pubkey":"a1b2c3d4…",295 "tags":[["-"],["p","c308e1f8…"]], …}]</span>296297<span class="c">-- a failed claim looks like this --</span>298<span class="recv">← ["OK", "9c00d1ef…", false, "restricted: that invite code is expired."]</span></pre>299 </div>300301 <h2 class="bar" id="history"><span class="num">10</span> Version History</h2>302 <p>NIP-43 is young. It arrived in late 2025 and grew a role system half a year later. Notable changes, newest first:</p>303 <ul class="patchnotes">304 <li><span class="ver">2026</span><span class="when">2026-06</span>Added role definitions (<code>kind 33534</code>). <code>member</code> tags in the membership list may now carry role ids as extra elements.</li>305 <li class="minor"><span class="ver">2026</span><span class="when">2026-06</span>Reformatted the example blocks from <code>jsonc</code> to <code>yaml</code> across the repository.</li>306 <li><span class="ver">2025</span><span class="when">2025-12</span>Added the <code>relay</code> tag to the NIP's status line.</li>307 <li><span class="ver">Origin</span><span class="when">2025-10</span>hodlbod proposed relay access requests: membership lists, add/remove announcements, and the join, invite, and leave kinds.</li>308 </ul>309310 <div class="credits">311 <h3 class="cardhead">Original Proposal - Credits</h3>312 <table>313 <tr><td>Author</td><td>hodlbod</td></tr>314 <tr><td>First commit</td><td>2025-10-30 — “Add relay access requests” (<a href="https://github.com/nostr-protocol/nips/pull/1079">PR #1079</a>)</td></tr>315 <tr><td>Status</td><td>draft - optional - relay — for relays with membership and their clients</td></tr>316 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/43.md">43.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/43.md">full change history</a></td></tr>317 </table>318 </div>319320 <h2 class="bar"><span class="num">11</span> See Also</h2>321 <ul>322 <li><a href="01.html">NIP-01</a> — the event object, <code>REQ</code> subscriptions, and <code>OK</code> messages used here.</li>323 <li><a href="11.html">NIP-11</a> — the relay information document; source of the <code>self</code> pubkey and <code>supported_nips</code>.</li>324 <li><a href="70.html">NIP-70</a> — protected events; defines the <code>-</code> tag required on every event in this NIP.</li>325 <li><a href="42.html">NIP-42</a> — client authentication; defines the <code>restricted:</code> prefix used for failed claims.</li>326 </ul>327 </div>328329 <aside>330 <div class="cartridge">331 <div class="inner">332 <h3 class="cardhead">Spec Card</h3>333 <div class="lights"><span class="led on"></span><span class="led warn"></span><span class="led warn"></span></div>334 <dl>335 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span><span class="chip">relay</span></dd>336 <dt>Defines</dt><dd>member/claim/label/description/color/order tags - role and membership events - join/invite/leave requests</dd>337 <dt>Kinds</dt><dd>33534 - 13534 - 8000 - 8001 - 28934 - 28935 - 28936</dd>338 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="11.html">NIP-11</a> - <a href="70.html">NIP-70</a> - <a href="42.html">NIP-42</a></dd>339 <dt>Transport</dt><dd>WebSocket - JSON arrays</dd>340 <dt>First commit</dt><dd>2025-10-30</dd>341 <dt>Last updated</dt><dd>2026-06-29</dd>342 </dl>343 </div>344 </div>345 </aside>346 </main>347348 <nav class="navbtns">349 <a href="42.html">◀ NIP-42: Authentication of clients to relays</a>350 <a href="44.html">NIP-44: Encrypted Payloads (Versioned) ▶</a>351 </nav>352353 <footer class="pagefoot">354 <a href="../index.html">Nostr Protocol Manual</a>355 <span class="pageno">NIP 43 / F4</span>356 </footer>357</div>358359<script src="../assets/webmcp.js" defer></script>360</body>361</html>