clone

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

main
nip.guide / site / nips / c7.html
c7.html 16.2K
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-C7 - Chats — Nostr Instruction Manual</title>7<meta name="description" content="NIP-C7: chat messages as kind 9 events. Replies with the q tag, quoting other content, and the strict kind-9 chat view rule. 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 C7 - Messaging</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="C7">C7</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № C7</div>50 <h1>Chats</h1>51 <p class="sub">A minimal chat message format: one kind, one reply tag, and one strict rule for what a chat view may fetch.</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 chat is a stream of short messages in time order. This NIP defines the event format for one chat message. It uses a dedicated kind so that chat messages never mix with <a href="10.html">NIP-10</a> text notes.</p>60 <p>The format is small on purpose. A chat message is a <strong>kind 9</strong> event. A reply is another kind 9 event that quotes its parent with a <code>q</code> tag. There is no other structure.</p>61 <p>This NIP began as part of <a href="29.html">NIP-29</a>, the relay-based groups spec. In late 2024 the chat message format moved into its own document. Group chats still use kind 9; NIP-29 adds the group scoping on top.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>Chats are flat and fast. For long, branching discussions use <a href="7d.html">NIP-7D</a> forum threads instead. Both NIPs were split out of <a href="29.html">NIP-29</a> in the same change.</p>66 </div>6768 <h2 class="bar" id="spec"><span class="num">2</span> The Chat Message</h2>69 <p>A chat message is a kind 9 event as defined by <a href="01.html">NIP-01</a>. The <code>content</code> field carries the message text. No tags are required.</p>7071 <div class="crt">72 <div class="titlebar">Wire format - chat message (kind 9)</div>73<pre>{74 <span class="k">"kind"</span>: 9,75 <span class="k">"content"</span>: <span class="s">"GM"</span>,76 <span class="k">"tags"</span>: []77}</pre>78 </div>7980 <div class="tscroll"><table class="ref">81 <caption>Chat message reference</caption>82 <tr><th>Field</th><th>Value</th><th>Rule</th></tr>83 <tr><td class="btn">kind</td><td><code>9</code></td><td>Marks the event as a chat message. Kind 9 is a regular event: relays store all of them.</td></tr>84 <tr><td class="btn">content</td><td>string</td><td>The message text.</td></tr>85 <tr><td class="btn">tags</td><td>array</td><td>Empty for a top-level message. A reply adds one <code>q</code> tag. See §3.</td></tr>86 </table></div>8788 <h2 class="bar" id="replies"><span class="num">3</span> Replies</h2>89 <p>A reply to a kind 9 event is an additional kind 9 event. The reply quotes the parent in two places at once. The <code>content</code> embeds a <a href="21.html">NIP-21</a> <code>nostr:nevent1…</code> pointer to the parent, then the reply text. The <code>tags</code> array carries a <code>q</code> tag with the parent's data.</p>9091 <div class="crt">92 <div class="titlebar">Wire format - reply (kind 9 quoting kind 9)</div>93<pre>{94 <span class="k">"kind"</span>: 9,95 <span class="k">"content"</span>: <span class="s">"nostr:nevent1...\nyes"</span>,96 <span class="k">"tags"</span>: [97 [<span class="s">"q"</span>, <span class="c">&lt;event-id&gt;</span>, <span class="c">&lt;relay-url&gt;</span>, <span class="c">&lt;pubkey&gt;</span>]98 ]99}</pre>100 </div>101102 <div class="tscroll"><table class="ref">103 <caption>The q tag</caption>104 <tr><th>Position</th><th>Element</th><th>Meaning</th></tr>105 <tr><td class="btn">0</td><td><span class="kbd">q</span></td><td>Tag name. Marks a quote of the parent event.</td></tr>106 <tr><td class="btn">1</td><td><code>&lt;event-id&gt;</code></td><td>The <code>id</code> of the parent event, in hex.</td></tr>107 <tr><td class="btn">2</td><td><code>&lt;relay-url&gt;</code></td><td>A relay where the parent event can be found.</td></tr>108 <tr><td class="btn">3</td><td><code>&lt;pubkey&gt;</code></td><td>The <code>pubkey</code> of the parent event's author.</td></tr>109 </table></div>110111 <figure class="diagram">112 <div class="frame">113 <svg viewBox="0 0 560 180" role="img" aria-label="A kind 9 reply points at its kind 9 parent through a q tag and a nostr: pointer in the content">114 <rect class="d-actor" x="20" y="30" width="200" height="60" rx="8"/>115 <text class="d-actor-label" x="120" y="55" text-anchor="middle">kind 9 - parent</text>116 <text class="d-note" x="120" y="74" text-anchor="middle">content: "GM"</text>117 <rect class="d-actor" x="340" y="90" width="200" height="70" rx="8"/>118 <text class="d-actor-label" x="440" y="113" text-anchor="middle">kind 9 - reply</text>119 <text class="d-note" x="440" y="130" text-anchor="middle">content: "nostr:nevent1...\nyes"</text>120 <text class="d-note" x="440" y="146" text-anchor="middle">tags: [["q", id, relay, pubkey]]</text>121 <path class="d-msg d-flow" d="M338,110 C280,100 270,75 224,63"/>122 <text class="d-label" x="285" y="70" text-anchor="middle">q tag</text>123 <circle r="4" fill="#f26a00">124 <animateMotion dur="2.6s" repeatCount="indefinite" path="M338,110 C280,100 270,75 224,63"/>125 </circle>126 </svg>127 </div>128 <figcaption>Fig. C7-1 — <b>Reply structure.</b> The reply is a normal kind 9 event. Its <code>q</code> tag and its <code>nostr:</code> pointer both reference the parent.</figcaption>129 </figure>130131 <h2 class="bar" id="views"><span class="num">4</span> Chat Views and Quoting</h2>132 <p>Some clients render a "chat view": a stream of events in time order. A client that renders a chat view <strong>MUST</strong> fetch only kind 9 events for that stream. This rule keeps every implementation on the same page. If one client mixed other kinds into the stream, users of other clients would miss context.</p>133 <p>Other content types <strong>MAY</strong> still appear in a chat. To include one, quote it inside a kind 9 event. The quoting mechanism follows <a href="18.html">NIP-18</a>: put a <code>nostr:</code> pointer in the <code>content</code> and a <code>q</code> tag in the <code>tags</code>. The kind 9 wrapper enters the stream; the quoted event rides inside it.</p>134135 <figure class="diagram">136 <div class="frame">137 <svg viewBox="0 0 560 190" role="img" aria-label="A chat view fetches only kind 9 events from the relay; a kind 1 note enters the view only when quoted inside a kind 9 event">138 <rect class="d-actor" x="10" y="55" width="120" height="80" rx="8"/>139 <text class="d-actor-label" x="70" y="80" text-anchor="middle">Relay</text>140 <text class="d-note" x="70" y="99" text-anchor="middle">kind 9, kind 9,</text>141 <text class="d-note" x="70" y="115" text-anchor="middle">kind 1, kind 30023</text>142 <rect class="d-actor" x="220" y="65" width="120" height="60" rx="8"/>143 <text class="d-actor-label" x="280" y="90" text-anchor="middle">Filter</text>144 <text class="d-note" x="280" y="109" text-anchor="middle">{"kinds":[9]}</text>145 <rect class="d-actor" x="430" y="30" width="120" height="130" rx="8"/>146 <text class="d-actor-label" x="490" y="55" text-anchor="middle">Chat view</text>147 <text class="d-note" x="490" y="78" text-anchor="middle">kind 9 "GM"</text>148 <text class="d-note" x="490" y="96" text-anchor="middle">kind 9 "yes"</text>149 <text class="d-note" x="490" y="114" text-anchor="middle">kind 9 quoting</text>150 <text class="d-note" x="490" y="130" text-anchor="middle">the kind 1 note</text>151 <path class="d-msg d-flow" d="M132,95 L217,95"/>152 <path class="d-msg blue d-flow" d="M342,95 L427,95"/>153 <text class="d-label" x="175" y="88" text-anchor="middle">REQ</text>154 <text class="d-label" x="385" y="88" text-anchor="middle">kind 9 only</text>155 <circle r="4" fill="#2e5f9e">156 <animateMotion dur="2.6s" repeatCount="indefinite" path="M342,95 L427,95"/>157 </circle>158 </svg>159 </div>160 <figcaption>Fig. C7-2 — <b>The chat view rule.</b> Only kind 9 events enter the stream. Other kinds arrive wrapped in a quoting kind 9 event.</figcaption>161 </figure>162163 <div class="box warn">164 <span class="tag">Warning!</span>165 <p>Do not render kind 1 notes, reposts, or any other kind directly in an ordered chat stream. The MUST rule exists because a mixed stream on one client leaves holes in the same chat on every other client.</p>166 </div>167168 <div class="box tech">169 <span class="tag">Tech Note</span>170 <p>The source spec is minimal and leaves gaps. It defines no tag that scopes a chat message to a room, group, or peer; scoping comes from other NIPs, such as the <a href="29.html">NIP-29</a> <code>h</code> tag. It also does not say whether the <code>&lt;relay-url&gt;</code> and <code>&lt;pubkey&gt;</code> elements of the <code>q</code> tag are optional. Treat them as recommended hints, as in <a href="18.html">NIP-18</a>.</p>171 </div>172173 <h2 class="bar" id="examples"><span class="num">5</span> Worked Example</h2>174 <p>Alice greets a group chat. Bob replies to her message. The session below shows both full events on the wire. Orange lines go to the relay. Blue lines come from the relay.</p>175176 <div class="crt">177 <div class="titlebar">Session transcript - wss://groups.example.com</div>178<pre><span class="c">-- Alice sends a chat message --</span>179<span class="send">→ ["EVENT", {"id":"a41f9dc6…","pubkey":"aa11ce22…","created_at":1750000000,180 "kind":9,"tags":[],"content":"GM","sig":"7be2f0a1…"}]</span>181<span class="recv">← ["OK", "a41f9dc6…", true, ""]</span>182183<span class="c">-- Bob replies, quoting Alice's event --</span>184<span class="send">→ ["EVENT", {"id":"b52e8ab7…","pubkey":"b0bb0b33…","created_at":1750000060,185 "kind":9,186 "tags":[["q","a41f9dc6…","wss://groups.example.com","aa11ce22…"]],187 "content":"nostr:nevent1qqs2g…\nyes","sig":"91c4d7e2…"}]</span>188<span class="recv">← ["OK", "b52e8ab7…", true, ""]</span>189190<span class="c">-- Carol opens the chat view: kind 9 only --</span>191<span class="send">→ ["REQ", "chat", {"kinds":[9], "limit":50}]</span>192<span class="recv">← ["EVENT", "chat", {"id":"b52e8ab7…", "kind":9, "content":"nostr:nevent1qqs2g…\nyes", …}]</span>193<span class="recv">← ["EVENT", "chat", {"id":"a41f9dc6…", "kind":9, "content":"GM", …}]</span>194<span class="recv">← ["EOSE", "chat"]</span></pre>195 </div>196 <p>Carol's client renders the two kind 9 events in time order. It resolves Bob's <code>nostr:nevent1…</code> pointer and shows Alice's message as an inline quote above his reply.</p>197198 <h2 class="bar" id="history"><span class="num">6</span> Version History</h2>199 <p>NIP-C7 is young and short. Its full life fits in two entries, newest first:</p>200 <ul class="patchnotes">201 <li><span class="ver">2026</span><span class="when">2026-05</span>Tightened the chat view rule: clients that render an ordered chat stream must fetch only kind 9 events. Other content types may be quoted inside a kind 9 per <a href="18.html">NIP-18</a>.</li>202 <li><span class="ver">Origin</span><span class="when">2024-11</span>hodlbod broke chats and threads out of <a href="29.html">NIP-29</a>. Kind 9 chat messages became this NIP; threads became <a href="7d.html">NIP-7D</a>.</li>203 </ul>204205 <div class="credits">206 <h3 class="cardhead">Original Proposal - Credits</h3>207 <table>208 <tr><td>Author</td><td>hodlbod</td></tr>209 <tr><td>First commit</td><td>2024-11-21 — “Break out chat and threads from nip 29” (<a href="https://github.com/nostr-protocol/nips/pull/1591">PR #1591</a>)</td></tr>210 <tr><td>Status</td><td>draft - optional — implement it for chat features</td></tr>211 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/C7.md">C7.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/C7.md">full change history</a></td></tr>212 </table>213 </div>214215 <h2 class="bar"><span class="num">7</span> See Also</h2>216 <ul>217 <li><a href="01.html">NIP-01</a> — the base event format and the client-relay flow that kind 9 rides on.</li>218 <li><a href="29.html">NIP-29</a> — relay-based groups; the original home of kind 9 and the source of group scoping.</li>219 <li><a href="7d.html">NIP-7D</a> — forum threads; the sibling NIP split out in the same change.</li>220 <li><a href="18.html">NIP-18</a> — reposts and the quoting mechanism used to embed other kinds in a chat.</li>221 <li><a href="21.html">NIP-21</a> — the <code>nostr:</code> URI scheme used in reply content.</li>222 <li><a href="19.html">NIP-19</a> — the <code>nevent</code> encoding inside those pointers.</li>223 <li><a href="10.html">NIP-10</a> — kind 1 text notes; the format chats deliberately avoid.</li>224 </ul>225 </div>226227 <aside>228 <div class="cartridge">229 <div class="inner">230 <h3 class="cardhead">Spec Card</h3>231 <div class="lights"><span class="led on"></span><span class="led warn"></span><span class="led warn"></span></div>232 <dl>233 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span></dd>234 <dt>Defines</dt><dd>kind 9 chat message - q tag reply - chat view fetch rule</dd>235 <dt>Kind</dt><dd>9 (regular)</dd>236 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="18.html">NIP-18</a> for quotes - <a href="21.html">NIP-21</a> pointers</dd>237 <dt>Transport</dt><dd>WebSocket - JSON arrays</dd>238 <dt>First commit</dt><dd>2024-11-21</dd>239 <dt>Last updated</dt><dd>2026-05-28</dd>240 </dl>241 </div>242 </div>243 </aside>244 </main>245246 <nav class="navbtns">247 <a href="c0.html">◀ NIP-C0: Code Snippets</a>248 <a href="cc.html">NIP-CC: Geocaching Events ▶</a>249 </nav>250251 <footer class="pagefoot">252 <a href="../index.html">Nostr Protocol Manual</a>253 <span class="pageno">NIP C7 / F4</span>254 </footer>255</div>256257<script src="../assets/webmcp.js" defer></script>258</body>259</html>