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-53 - Live Streaming and Spaces — Nostr Instruction Manual</title>7<meta name="description" content="NIP-53: live streaming events, live chat, meeting spaces, meeting rooms, and room presence. Kinds 30311, 1311, 30312, 30313, and 10312. 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 53 - 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="53">53</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 53</div>50 <h1>Live Streaming and Spaces</h1>51 <p class="sub">Advertise a live stream, a chat room, or a meeting space as an event. Update it while people join, speak, and leave.</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>This NIP defines event kinds that advertise live spaces and the participation of pubkeys in them. A <strong>live activity</strong> is a stream, a talk, or a meeting that happens now or soon. The event that advertises it lists the title, the media URL, the status, and the participants.</p>60 <p>Five kinds work together. Kind <code>30311</code> advertises a <strong>live streaming event</strong>. Kind <code>1311</code> carries a <strong>live chat message</strong> for that stream. Kind <code>30312</code> defines a persistent <strong>meeting space</strong>. Kind <code>30313</code> schedules a <strong>meeting</strong> inside a space. Kind <code>10312</code> signals <strong>room presence</strong> of one listener.</p>61 <p>The advertising events are addressable events, as defined in <a href="01.html">NIP-01</a>. The owner updates one event in place while the activity runs. Viewers subscribe once and watch the state change.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>The streamer does not send video over Nostr. The <code>streaming</code> tag carries a normal media URL, for example an HLS <code>.m3u8</code> playlist. Nostr carries only the metadata, the chat, and the presence.</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 190" role="img" aria-label="A host updates one kind 30311 event on a relay; viewers subscribe to it and publish kind 1311 chat messages that reference 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="93" text-anchor="middle">Host</text>73 <text class="d-note" x="65" y="110" text-anchor="middle">mgmt client</text>74 <rect class="d-actor" x="225" y="70" width="110" height="50" rx="8"/>75 <text class="d-actor-label" x="280" y="93" text-anchor="middle">Relay</text>76 <text class="d-note" x="280" y="110" text-anchor="middle">kind 30311</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="93" text-anchor="middle">Viewer</text>79 <text class="d-note" x="495" y="110" text-anchor="middle">player + chat</text>80 <path class="d-msg d-flow" d="M122,84 L223,84"/>81 <path class="d-msg blue d-flow" d="M337,84 L438,84"/>82 <path class="d-msg d-flow" d="M438,106 L337,106"/>83 <text class="d-label" x="172" y="60" text-anchor="middle">30311 updates</text>84 <text class="d-label" x="388" y="60" text-anchor="middle">REQ / EVENT</text>85 <text class="d-label" x="388" y="140" text-anchor="middle">1311 chat ("a" tag)</text>86 <circle r="4" fill="#f26a00">87 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,84 L223,84"/>88 </circle>89 <circle r="4" fill="#2e5f9e">90 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M337,84 L438,84"/>91 </circle>92 </svg>93 </div>94 <figcaption>Fig. 53-1 — <b>Live activity flow.</b> The host updates one addressable event. Viewers subscribe to it and send chat messages that point back to it.</figcaption>95 </figure>9697 <h2 class="bar" id="spec"><span class="num">2</span> Live Streaming Event (kind 30311)</h2>98 <p>Kind <code>30311</code> is the "Live Streaming Event". It is an addressable event. Its tags advertise the content and the participants of a live stream. The owner updates the event constantly as participants join and leave.</p>99100 <div class="crt">101 <div class="titlebar">Wire format - kind 30311</div>102<pre>{103 <span class="k">"kind"</span>: 30311,104 <span class="k">"tags"</span>: [105 [<span class="s">"d"</span>, <span class="c"><unique identifier></span>],106 [<span class="s">"title"</span>, <span class="c"><name of the event></span>],107 [<span class="s">"summary"</span>, <span class="c"><description></span>],108 [<span class="s">"image"</span>, <span class="c"><preview image url></span>],109 [<span class="s">"t"</span>, <span class="s">"hashtag"</span>],110 [<span class="s">"streaming"</span>, <span class="c"><url></span>],111 [<span class="s">"recording"</span>, <span class="c"><url></span>], <span class="c">// edited video, added after the end</span>112 [<span class="s">"starts"</span>, <span class="c"><unix timestamp, seconds></span>],113 [<span class="s">"ends"</span>, <span class="c"><unix timestamp, seconds></span>],114 [<span class="s">"status"</span>, <span class="c"><planned | live | ended></span>],115 [<span class="s">"current_participants"</span>, <span class="c"><number></span>],116 [<span class="s">"total_participants"</span>, <span class="c"><number></span>],117 [<span class="s">"p"</span>, <span class="s">"91cf9..4e5ca"</span>, <span class="s">"wss://provider1.com/"</span>, <span class="s">"Host"</span>, <span class="c"><proof></span>],118 [<span class="s">"p"</span>, <span class="s">"14aeb..8dad4"</span>, <span class="s">"wss://provider2.com/nostr"</span>, <span class="s">"Speaker"</span>],119 [<span class="s">"p"</span>, <span class="s">"612ae..e610f"</span>, <span class="s">"ws://provider3.com/ws"</span>, <span class="s">"Participant"</span>],120 [<span class="s">"relays"</span>, <span class="s">"wss://one.com"</span>, <span class="s">"wss://two.com"</span>, <span class="c">...</span>],121 [<span class="s">"pinned"</span>, <span class="c"><event id of pinned live chat message></span>]122 ],123 <span class="k">"content"</span>: <span class="s">""</span>124}</pre>125 </div>126127 <div class="tscroll"><table class="ref">128 <caption>Tag reference - kind 30311</caption>129 <tr><th>Tag</th><th>Value</th><th>Rule</th></tr>130 <tr><td class="btn">d</td><td>unique identifier</td><td>Use a distinct <code>d</code> tag for each activity. All other tags are optional.</td></tr>131 <tr><td class="btn">title</td><td>string</td><td>Name of the event.</td></tr>132 <tr><td class="btn">summary</td><td>string</td><td>Description of the event.</td></tr>133 <tr><td class="btn">image</td><td>URL</td><td>Preview image.</td></tr>134 <tr><td class="btn">t</td><td>hashtag</td><td>Topic hashtag. May repeat.</td></tr>135 <tr><td class="btn">streaming</td><td>URL</td><td>Where the live media plays.</td></tr>136 <tr><td class="btn">recording</td><td>URL</td><td>The edited video, placed once the activity is over.</td></tr>137 <tr><td class="btn">starts</td><td>unix seconds</td><td>Start time. Update it when the status changes to <code>live</code>.</td></tr>138 <tr><td class="btn">ends</td><td>unix seconds</td><td>End time. Update it when the status changes from <code>live</code>.</td></tr>139 <tr><td class="btn">status</td><td>keyword</td><td>One of <code>planned</code>, <code>live</code>, <code>ended</code>.</td></tr>140 <tr><td class="btn">current_participants</td><td>number</td><td>Participants active now.</td></tr>141 <tr><td class="btn">total_participants</td><td>number</td><td>Participants over the whole activity.</td></tr>142 <tr><td class="btn">p</td><td>pubkey, relay, role, proof</td><td>A participant. The relay entry may be empty. See the role and proof rules below.</td></tr>143 <tr><td class="btn">relays</td><td>URL list</td><td>Preferred relays for the activity. One tag holds many URLs.</td></tr>144 <tr><td class="btn">pinned</td><td>event id</td><td>A pinned kind <code>1311</code> live chat message. May repeat.</td></tr>145 </table></div>146147 <p>Each <code>p</code> tag SHOULD carry a displayable marker name for the current role of the user in the event. Examples are <code>Host</code>, <code>Speaker</code>, and <code>Participant</code>. The relay information MAY be empty.</p>148 <p>Providers SHOULD keep the participant list small, for example under 1000 users. When the limit is reached, providers SHOULD select which participants get named in the event. Clients should not expect a comprehensive list. Once the activity ends, the owner can delete the event, or update it to summarize the activity and provide async content such as the recording.</p>149 <p>Clients are expected to subscribe to kind <code>30311</code> events in general, or for given follow lists and statuses. Clients MAY display participants' roles in activities, and access points to join the activity. Live activity management clients are expected to update kind <code>30311</code> constantly during the event. Clients MAY treat a <code>status=live</code> event as <code>ended</code> after one hour without any update. The <code>starts</code> and <code>ends</code> timestamps SHOULD be updated when the status changes to and from <code>live</code>.</p>150 <p>Link to the activity with the <a href="19.html">NIP-19</a> <code>naddr</code> code along with the <code>a</code> tag. This is a MUST.</p>151152 <figure class="diagram">153 <div class="frame">154 <svg viewBox="0 0 560 130" role="img" aria-label="Status lifecycle: planned goes to live, live goes to ended; a live event with no update for one hour may be treated as ended">155 <rect class="d-actor" x="20" y="35" width="120" height="44" rx="8"/>156 <text class="d-actor-label" x="80" y="62" text-anchor="middle">planned</text>157 <rect class="d-actor" x="220" y="35" width="120" height="44" rx="8"/>158 <text class="d-actor-label" x="280" y="62" text-anchor="middle">live</text>159 <rect class="d-actor" x="420" y="35" width="120" height="44" rx="8"/>160 <text class="d-actor-label" x="480" y="62" text-anchor="middle">ended</text>161 <path class="d-msg" d="M142,57 L217,57"/>162 <path class="d-msg" d="M342,57 L417,57"/>163 <text class="d-label" x="180" y="30" text-anchor="middle">update starts</text>164 <text class="d-label" x="380" y="30" text-anchor="middle">update ends</text>165 <text class="d-note" x="280" y="105" text-anchor="middle">No update for 1 hour while live? Clients MAY treat the event as ended.</text>166 </svg>167 </div>168 <figcaption>Fig. 53-2 — <b>Status lifecycle.</b> The owner moves the status forward and refreshes <code>starts</code> and <code>ends</code> at each change.</figcaption>169 </figure>170171 <h2 class="bar" id="proof"><span class="num">3</span> Proof of Agreement to Participate</h2>172 <p>An event owner can name any pubkey as a participant. The named user may not know. A malicious owner could add large account holders to lure their followers into a trap. The <strong>proof</strong> field defends against this.</p>173 <p>The owner adds the proof as the 5th term of a <code>p</code> tag. To build the proof, follow these steps. Take the complete <code>a</code> tag value of the event: <code>kind:pubkey:dTag</code>. Hash it with SHA256. Sign the hash with the participant's private key. Encode the signature in hex.</p>174 <div class="crt">175 <div class="titlebar">Proof recipe</div>176<pre><span class="c">a_tag = </span><span class="s">"30311:<owner pubkey>:<d value>"</span>177<span class="c">proof = hex( sign_<participant privkey>( sha256(a_tag) ) )</span>178[<span class="s">"p"</span>, <span class="c"><participant pubkey></span>, <span class="c"><relay></span>, <span class="s">"Speaker"</span>, <span class="c"><proof></span>]</pre>179 </div>180 <p>Clients MAY display a participant only if the proof is available. Or clients MAY display a participant without proof as "invited".</p>181182 <h2 class="bar" id="chat"><span class="num">4</span> Live Chat Message (kind 1311)</h2>183 <p>Kind <code>1311</code> is the live chat's channel message. It is a regular event. Clients MUST include the <code>a</code> tag of the activity. An <code>e</code> tag denotes the direct parent message this post replies to.</p>184 <div class="crt">185 <div class="titlebar">Wire format - kind 1311</div>186<pre>{187 <span class="k">"kind"</span>: 1311,188 <span class="k">"tags"</span>: [189 [<span class="s">"a"</span>, <span class="s">"30311:<activity author pubkey>:<d identifier>"</span>, <span class="c"><optional relay url></span>]190 ],191 <span class="k">"content"</span>: <span class="s">"Zaps to live streams is beautiful."</span>192}</pre>193 </div>194 <p><code>q</code> tags MAY be used when the <code>content</code> cites other events with <a href="21.html">NIP-21</a> URIs:</p>195 <div class="crt">196 <div class="titlebar">Citation tag</div>197<pre>[<span class="s">"q"</span>, <span class="c"><event-id> or <event-address></span>, <span class="c"><relay-url></span>, <span class="c"><pubkey-if-a-regular-event></span>]</pre>198 </div>199 <p>Hosts may pin one or more live chat messages. To pin, the host updates the <code>pinned</code> tags in the kind <code>30311</code> live event.</p>200201 <div class="box tech">202 <span class="tag">Tech Note</span>203 <p>A 2025-02 revision removed reply markers from live chat and added <code>q</code> tags. Yet the source's kind <code>1311</code> example still ends its <code>a</code> tag with a <code>"root"</code> marker, and the kind <code>10312</code> presence template does the same. Expect both marked and unmarked <code>a</code> tags in the wild.</p>204 </div>205206 <h2 class="bar" id="spaces"><span class="num">5</span> Meeting Spaces (kind 30312)</h2>207 <p>A meeting space contains one or more video or audio rooms. Users join a room and take part in the streaming. Kind <code>30312</code> "Space Host" is an addressable event. It defines the configuration and the properties of one virtual interactive space. Each space has a unique identifier and can host multiple events and meetings.</p>208 <div class="crt">209 <div class="titlebar">Wire format - kind 30312</div>210<pre>{211 <span class="k">"kind"</span>: 30312,212 <span class="k">"tags"</span>: [213 [<span class="s">"d"</span>, <span class="c"><unique identifier></span>], <span class="c">// Required: room identifier</span>214 [<span class="s">"room"</span>, <span class="c"><name of the room></span>], <span class="c">// Required: display name</span>215 [<span class="s">"summary"</span>, <span class="c"><description></span>], <span class="c">// Optional</span>216 [<span class="s">"image"</span>, <span class="c"><preview image url></span>], <span class="c">// Optional</span>217 [<span class="s">"status"</span>, <span class="c"><open | private | closed></span>], <span class="c">// Required: accessibility</span>218 [<span class="s">"service"</span>, <span class="c"><url></span>], <span class="c">// Required: URL to access the room</span>219 [<span class="s">"endpoint"</span>, <span class="c"><url></span>], <span class="c">// Optional: API endpoint for status/info</span>220 [<span class="s">"t"</span>, <span class="c"><hashtag></span>], <span class="c">// Optional: may repeat</span>221 [<span class="s">"p"</span>, <span class="c"><pubkey></span>, <span class="c"><url></span>, <span class="c"><role></span>, <span class="c"><proof></span>], <span class="c">// Required: at least one provider</span>222 [<span class="s">"relays"</span>, <span class="c"><url></span>, <span class="c"><url></span>, <span class="c">...</span>] <span class="c">// Optional: preferred relays</span>223 ],224 <span class="k">"content"</span>: <span class="s">""</span> <span class="c">// usually empty, may contain additional metadata</span>225}</pre>226 </div>227 <p>Space rules:</p>228 <ul>229 <li>The status MUST be <code>open</code>, <code>private</code>, or <code>closed</code>. Closed means the room is not in operation.</li>230 <li>The space MAY specify an access control policy for private rooms, for example invite-only or payment required.</li>231 <li>The space MAY persist when not in use.</li>232 <li>The space MUST have at least one provider with the <code>Host</code> role.</li>233 <li>The space MAY have multiple providers with different roles.</li>234 </ul>235 <div class="tscroll"><table class="ref">236 <caption>Provider roles (p tags)</caption>237 <tr><th>Role</th><th>Capability</th></tr>238 <tr><td class="btn">Host</td><td>Full room management capabilities.</td></tr>239 <tr><td class="btn">Moderator</td><td>Room moderation capabilities.</td></tr>240 <tr><td class="btn">Speaker</td><td>Allowed to present and speak.</td></tr>241 </table></div>242 <p>The optional proof field in a provider <code>p</code> tag verifies the role, as in §3.</p>243244 <figure class="diagram">245 <div class="frame">246 <svg viewBox="0 0 560 200" role="img" aria-label="A kind 30312 space is referenced by kind 30313 meetings and by kind 10312 presence events through a tags">247 <rect class="d-actor" x="200" y="15" width="160" height="50" rx="8"/>248 <text class="d-actor-label" x="280" y="38" text-anchor="middle">Space 30312</text>249 <text class="d-note" x="280" y="55" text-anchor="middle">d = room id</text>250 <rect class="d-actor" x="20" y="130" width="150" height="50" rx="8"/>251 <text class="d-actor-label" x="95" y="153" text-anchor="middle">Meeting 30313</text>252 <text class="d-note" x="95" y="170" text-anchor="middle">planned / live / ended</text>253 <rect class="d-actor" x="205" y="130" width="150" height="50" rx="8"/>254 <text class="d-actor-label" x="280" y="153" text-anchor="middle">Meeting 30313</text>255 <text class="d-note" x="280" y="170" text-anchor="middle">another event</text>256 <rect class="d-actor" x="390" y="130" width="150" height="50" rx="8"/>257 <text class="d-actor-label" x="465" y="153" text-anchor="middle">Presence 10312</text>258 <text class="d-note" x="465" y="170" text-anchor="middle">one listener</text>259 <path class="d-msg d-flow" d="M95,128 C110,95 190,70 225,67"/>260 <path class="d-msg d-flow" d="M280,128 L280,68"/>261 <path class="d-msg blue d-flow" d="M465,128 C450,95 370,70 335,67"/>262 <text class="d-label" x="120" y="85" text-anchor="middle">"a" 30312:pk:room</text>263 <text class="d-label" x="445" y="85" text-anchor="middle">"a" + "root"</text>264 </svg>265 </div>266 <figcaption>Fig. 53-3 — <b>Space structure.</b> Meetings and presence events point at the parent space with <code>a</code> tags.</figcaption>267 </figure>268269 <h2 class="bar" id="meetings"><span class="num">6</span> Meeting Room Events (kind 30313)</h2>270 <p>Kind <code>30313</code> represents a scheduled or ongoing meeting within a room. It is an addressable event. It MUST reference its parent room.</p>271 <div class="crt">272 <div class="titlebar">Wire format - kind 30313</div>273<pre>{274 <span class="k">"kind"</span>: 30313,275 <span class="k">"tags"</span>: [276 [<span class="s">"d"</span>, <span class="c"><event unique identifier></span>], <span class="c">// Required</span>277 [<span class="s">"a"</span>, <span class="s">"30312:<pubkey>:<room-id>"</span>, <span class="s">"wss://nostr.example.com"</span>], <span class="c">// Required: parent space, 'd' from 30312</span>278 [<span class="s">"title"</span>, <span class="c"><meeting title></span>], <span class="c">// Required</span>279 [<span class="s">"summary"</span>, <span class="c"><description></span>], <span class="c">// Optional</span>280 [<span class="s">"image"</span>, <span class="c"><preview image url></span>], <span class="c">// Optional</span>281 [<span class="s">"starts"</span>, <span class="c"><unix timestamp></span>], <span class="c">// Required</span>282 [<span class="s">"ends"</span>, <span class="c"><unix timestamp></span>], <span class="c">// Optional</span>283 [<span class="s">"status"</span>, <span class="c"><planned | live | ended></span>], <span class="c">// Required</span>284 [<span class="s">"total_participants"</span>, <span class="c"><number></span>], <span class="c">// Optional: total registered</span>285 [<span class="s">"current_participants"</span>, <span class="c"><number></span>], <span class="c">// Optional: currently active</span>286 [<span class="s">"p"</span>, <span class="c"><pubkey></span>, <span class="c"><url></span>, <span class="c"><role></span>] <span class="c">// Optional: participant with role</span>287 ],288 <span class="k">"content"</span>: <span class="s">""</span> <span class="c">// usually empty, may contain additional metadata</span>289}</pre>290 </div>291 <p>Meeting rules:</p>292 <ul>293 <li>The meeting MUST reference its parent room.</li>294 <li>The meeting MUST have a status: <code>planned</code>, <code>live</code>, or <code>ended</code>.</li>295 <li>The meeting MUST have a start time.</li>296 <li>The meeting MAY track participant counts.</li>297 <li>The meeting MAY include participant roles specific to the event.</li>298 </ul>299 <p>Meeting management follows the live streaming pattern. Clients SHOULD update the event status regularly while it is live. A meeting without updates for one hour MAY be considered ended. The <code>starts</code> and <code>ends</code> timestamps SHOULD be updated when the status changes.</p>300301 <div class="box tech">302 <span class="tag">Tech Note</span>303 <p>The source text says the meeting "MUST reference its parent room using the d tag". But in the wire format the <code>d</code> tag holds the meeting's own identifier. The parent reference is the <code>a</code> tag <code>30312:<pubkey>:<room-id></code>, whose last segment is the <code>d</code> value of the space. Follow the <code>a</code> tag form shown above.</p>304 </div>305306 <h2 class="bar" id="presence"><span class="num">7</span> Room Presence (kind 10312)</h2>307 <p>Kind <code>10312</code> signals the presence of a listener in a room. It is a replaceable event. Because the relay keeps only the latest event per pubkey, a user can indicate presence in only one room at a time.</p>308 <div class="crt">309 <div class="titlebar">Wire format - kind 10312</div>310<pre>{311 <span class="k">"kind"</span>: 10312,312 <span class="k">"tags"</span>: [313 [<span class="s">"a"</span>, <span class="c"><room a tag></span>, <span class="c"><relay hint></span>, <span class="s">"root"</span>],314 [<span class="s">"hand"</span>, <span class="s">"1"</span>] <span class="c">// hand raised flag</span>315 ]316}</pre>317 </div>318 <p>The presence event SHOULD be updated at regular intervals. Clients SHOULD filter out presence events older than a given time window. The <code>hand</code> tag with value <code>"1"</code> means the listener raises a hand.</p>319320 <div class="box warn">321 <span class="tag">Warning!</span>322 <p>The source calls kind <code>10312</code> a "regular replaceable event". In <a href="01.html">NIP-01</a> terms it is a plain replaceable event: the range 10000-19999. Do not confuse it with a regular event. The relay keeps only the newest one per pubkey.</p>323 </div>324325 <h2 class="bar" id="examples"><span class="num">8</span> Worked Examples</h2>326 <p>The first example is a real live stream advertisement. The status is <code>live</code> and the <code>streaming</code> tag points at an HLS playlist.</p>327 <div class="crt">328 <div class="titlebar">Live stream - kind 30311</div>329<pre>{330 <span class="k">"id"</span>: <span class="s">"57f28dbc264990e2c61e80a883862f7c114019804208b14da0bff81371e484d2"</span>,331 <span class="k">"pubkey"</span>: <span class="s">"1597246ac22f7d1375041054f2a4986bd971d8d196d7997e48973263ac9879ec"</span>,332 <span class="k">"created_at"</span>: 1687182672,333 <span class="k">"kind"</span>: 30311,334 <span class="k">"tags"</span>: [335 [<span class="s">"d"</span>, <span class="s">"demo-cf-stream"</span>],336 [<span class="s">"title"</span>, <span class="s">"Adult Swim Metalocalypse"</span>],337 [<span class="s">"summary"</span>, <span class="s">"Live stream from IPTV-ORG collection"</span>],338 [<span class="s">"streaming"</span>, <span class="s">"https://adultswim-vodlive.cdn.turner.com/live/metalocalypse/stream.m3u8"</span>],339 [<span class="s">"starts"</span>, <span class="s">"1687182672"</span>],340 [<span class="s">"status"</span>, <span class="s">"live"</span>],341 [<span class="s">"t"</span>, <span class="s">"animation"</span>],342 [<span class="s">"t"</span>, <span class="s">"iptv"</span>],343 [<span class="s">"image"</span>, <span class="s">"https://i.imgur.com/CaKq6Mt.png"</span>]344 ],345 <span class="k">"content"</span>: <span class="s">""</span>,346 <span class="k">"sig"</span>: <span class="s">"5bc7a60f5688effa5287244a24768cbe0dcd854436090abc3bef172f7f5db141…"</span>347}</pre>348 </div>349 <p>A viewer replies in the live chat. The <code>a</code> tag binds the message to the stream above:</p>350 <div class="crt">351 <div class="titlebar">Live chat message - kind 1311</div>352<pre>{353 <span class="k">"id"</span>: <span class="s">"97aa81798ee6c5637f7b21a411f89e10244e195aa91cb341bf49f718e36c8188"</span>,354 <span class="k">"pubkey"</span>: <span class="s">"3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24"</span>,355 <span class="k">"created_at"</span>: 1687286726,356 <span class="k">"kind"</span>: 1311,357 <span class="k">"tags"</span>: [358 [<span class="s">"a"</span>, <span class="s">"30311:1597246ac22f7d1375041054f2a4986bd971d8d196d7997e48973263ac9879ec:demo-cf-stream"</span>, <span class="s">""</span>, <span class="s">"root"</span>]359 ],360 <span class="k">"content"</span>: <span class="s">"Zaps to live streams is beautiful."</span>,361 <span class="k">"sig"</span>: <span class="s">"997f62ddfc0827c121043074d50cfce7a528e978c575722748629a4137c45b75…"</span>362}</pre>363 </div>364 <p>The second example is a meeting space with one live meeting inside it. The session shows the owner publishing both, and a listener marking presence. Orange lines go to the relay. Blue lines come from the relay.</p>365 <div class="crt">366 <div class="titlebar">Session transcript - wss://nostr.example.com</div>367<pre><span class="c">-- Owner publishes the space --</span>368<span class="send">→ ["EVENT", {"kind":30312,"tags":[["d","main-conference-room"],369 ["room","Main Conference Hall"],["summary","Our primary conference space"],370 ["image","https://example.com/room.jpg"],["status","open"],371 ["service","https://meet.example.com/room"],["endpoint","https://api.example.com/room"],372 ["t","conference"],["p","f7234bd4c139…76e9ca","wss://nostr.example.com/","Owner"],373 ["p","14aeb..8dad4","wss://provider2.com/","Moderator"],374 ["relays","wss://relay1.com","wss://relay2.com"]],"content":"", …}]</span>375<span class="recv">← ["OK", "a01f83cc…", true, ""]</span>376377<span class="c">-- Owner publishes the meeting inside the space --</span>378<span class="send">→ ["EVENT", {"kind":30313,"tags":[["d","annual-meeting-2025"],379 ["a","30312:f7234bd4c139…76e9ca:main-conference-room","wss://nostr.example.com"],380 ["title","Annual Company Meeting 2025"],["summary","Yearly company-wide meeting"],381 ["image","https://example.com/meeting.jpg"],["starts","1676262123"],382 ["ends","1676269323"],["status","live"],["total_participants","180"],383 ["current_participants","175"],["p","91cf9..4e5ca","wss://provider1.com/","Speaker"]],384 "content":"", …}]</span>385<span class="recv">← ["OK", "b7c20d1e…", true, ""]</span>386387<span class="c">-- A listener signals presence and raises a hand --</span>388<span class="send">→ ["EVENT", {"kind":10312,"tags":[389 ["a","30312:f7234bd4c139…76e9ca:main-conference-room","wss://nostr.example.com","root"],390 ["hand","1"]],"content":"", …}]</span>391<span class="recv">← ["OK", "c93aa1f0…", true, ""]</span></pre>392 </div>393394 <h2 class="bar" id="history"><span class="num">9</span> Version History</h2>395 <p>NIP-53 started as "Live Activities" for streaming and chat. A 2025 addendum grew it into full meeting spaces with presence. Notable changes, newest first:</p>396 <ul class="patchnotes">397 <li class="minor"><span class="ver">2026</span><span class="when">2026-06</span>Housekeeping: code fences relabeled and NIP files renamed for clarity.</li>398 <li class="minor"><span class="ver">2025</span><span class="when">2025-09</span>Text refinements, formatting fixes, and typo cleanup.</li>399 <li><span class="ver">2025</span><span class="when">2025-06</span>Addendum: added meeting spaces (kind 30312), meeting room events (kind 30313), and room presence (kind 10312).</li>400 <li><span class="ver">2025</span><span class="when">2025-02</span>Live chat: removed reply markers and added <code>q</code> citation tags. Added optional <code>pinned</code> chat messages to kind 30311.</li>401 <li class="minor"><span class="ver">2024</span><span class="when">2024-08</span>Terminology: "parameterized replaceable event" became "addressable event"; JSON reformatting and small nitpicks.</li>402 <li class="minor"><span class="ver">2023</span><span class="when">2023-07</span>Fixed the event kind in the chat example days after launch.</li>403 <li><span class="ver">Origin</span><span class="when">2023-07-08</span>Vitor Pamplona proposed "NIP-53 Live Activities" with kinds 30311 and 1311 and the proof of participation.</li>404 </ul>405406 <div class="credits">407 <h3 class="cardhead">Original Proposal - Credits</h3>408 <table>409 <tr><td>Author</td><td>Vitor Pamplona</td></tr>410 <tr><td>First commit</td><td>2023-07-08 — “NIP-53 Live Activities” (<a href="https://github.com/nostr-protocol/nips/pull/498">PR #498</a>)</td></tr>411 <tr><td>Status</td><td>draft - optional</td></tr>412 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/53.md">53.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/53.md">full change history</a></td></tr>413 </table>414 </div>415416 <h2 class="bar"><span class="num">10</span> See Also</h2>417 <ul>418 <li><a href="01.html">NIP-01</a> — addressable and replaceable event classes, the <code>a</code> tag, and the base protocol.</li>419 <li><a href="19.html">NIP-19</a> — the <code>naddr</code> code that MUST be used to link to a live activity.</li>420 <li><a href="21.html">NIP-21</a> — <code>nostr:</code> URIs cited by <code>q</code> tags in live chat.</li>421 <li><a href="10.html">NIP-10</a> — the <code>e</code> tag reply convention that live chat borrows for parent messages.</li>422 <li><a href="52.html">NIP-52</a> — calendar events; schedule a future activity, then go live with this NIP.</li>423 </ul>424 </div>425426 <aside>427 <div class="cartridge">428 <div class="inner">429 <h3 class="cardhead">Spec Card</h3>430 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>431 <dl>432 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span></dd>433 <dt>Defines</dt><dd>live stream - live chat - spaces - meetings - presence - proof of participation</dd>434 <dt>Kinds</dt><dd>1311 regular - 10312 replaceable - 30311/30312/30313 addressable</dd>435 <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></dd>436 <dt>Transport</dt><dd>WebSocket for events - media via streaming URLs</dd>437 <dt>Crypto</dt><dd>proof = hex Schnorr sig of sha256(a tag)</dd>438 <dt>First commit</dt><dd>2023-07-08</dd>439 <dt>Last updated</dt><dd>2026-06-13</dd>440 </dl>441 </div>442 </div>443 </aside>444 </main>445446 <nav class="navbtns">447 <a href="52.html">◀ NIP-52: Calendar Events</a>448 <a href="54.html">NIP-54: Wiki ▶</a>449 </nav>450451 <footer class="pagefoot">452 <a href="../index.html">Nostr Protocol Manual</a>453 <span class="pageno">NIP 53 / F4</span>454 </footer>455</div>456457<script src="../assets/webmcp.js" defer></script>458</body>459</html>