clone

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

main
nip.guide / site / nips / 99.html
99.html 19.3K
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-99 - Classified Listings — Nostr Instruction Manual</title>7<meta name="description" content="NIP-99: classified listings on Nostr. Kind 30402 addressable events for goods, services, and offers, with structured metadata tags. 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 99 - Commerce</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="99">99</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 99</div>50 <h1>Classified Listings</h1>51 <p class="sub">One addressable event that puts anything up for sale or offer: goods, services, jobs, rentals, giveaways, or personals.</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 <strong>classified listing</strong> is a public offer. It can list a physical good, a service, a work opportunity, a rental, a free giveaway, or a personal ad. This NIP defines <code>kind:30402</code>, an addressable event that describes one listing. The event carries enough structured metadata to make the listing useful to clients.</p>60 <p>The <code>.pubkey</code> field of a listing is the party that creates the listing. The event structure is very similar to <a href="23.html">NIP-23</a> long-form content events. Because the event is addressable (see <a href="01.html">NIP-01</a>), the seller can edit the listing later. The relay keeps only the latest version per <code>pubkey</code> + <code>kind</code> + <code>d</code> tag value.</p>61 <p><a href="15.html">NIP-15</a> defines a strictly structured marketplace. NIP-99 emerged as a simpler and more flexible alternative. For interoperable e-commerce on top of NIP-99, the spec points to an extension proposal by GammaMarkets. The extension standardizes the e-commerce use case and keeps the base spec lightweight.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>Think of NIP-99 as the corkboard at the general store. One pin, one card, one price. NIP-15 is the full cash register in the back. Pick the card first; upgrade only when you need carts and checkout.</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 190" role="img" aria-label="Seller publishes a kind 30402 listing to relays; buyer clients query by kind and tag and browse the listing">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">Seller</text>73 <text class="d-note" x="65" y="110" text-anchor="middle">client</text>74 <rect class="d-actor" x="225" y="20" width="110" height="44" rx="8"/>75 <text class="d-actor-label" x="280" y="47" text-anchor="middle">Relay 1</text>76 <rect class="d-actor" x="225" y="126" width="110" height="44" rx="8"/>77 <text class="d-actor-label" x="280" y="153" text-anchor="middle">Relay 2</text>78 <rect class="d-actor" x="440" y="70" width="110" height="50" rx="8"/>79 <text class="d-actor-label" x="495" y="93" text-anchor="middle">Buyer</text>80 <text class="d-note" x="495" y="110" text-anchor="middle">client</text>81 <path class="d-msg d-flow" d="M122,84 C170,70 180,52 223,44"/>82 <path class="d-msg d-flow" d="M122,106 C170,120 180,138 223,146"/>83 <path class="d-msg blue d-flow" d="M337,44 C380,52 390,70 438,84"/>84 <path class="d-msg blue d-flow" d="M337,146 C380,138 390,120 438,106"/>85 <text class="d-label" x="160" y="48" text-anchor="middle">kind 30402</text>86 <text class="d-label" x="402" y="48" text-anchor="middle">REQ {"kinds":[30402]}</text>87 <circle r="4" fill="#f26a00">88 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,84 C170,70 180,52 223,44"/>89 </circle>90 <circle r="4" fill="#2e5f9e">91 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M337,44 C380,52 390,70 438,84"/>92 </circle>93 </svg>94 </div>95 <figcaption>Fig. 99-1 — <b>Listing flow.</b> The seller publishes one addressable listing. Buyers query relays by kind and tag.</figcaption>96 </figure>9798 <h2 class="bar" id="spec"><span class="num">2</span> Listing Events</h2>99 <p>This NIP defines two kinds. Both are addressable events with the same structure:</p>100 <div class="tscroll"><table class="ref">101 <caption>Kinds defined by this NIP</caption>102 <tr><th>Kind</th><th>Name</th><th>Purpose</th></tr>103 <tr><td class="btn">30402</td><td>Classified listing</td><td>A published listing. Describes any product, service, or other thing for sale or offer.</td></tr>104 <tr><td class="btn">30403</td><td>Draft / inactive listing</td><td>Saves a draft or inactive listing. Same structure as <code>kind:30402</code>.</td></tr>105 </table></div>106 <p>The <code>.content</code> field is a description of what is offered and by whom. Write it as one string in Markdown syntax. The <code>.pubkey</code> field is the party that creates the listing.</p>107108 <figure class="diagram">109 <div class="frame">110 <svg viewBox="0 0 560 150" role="img" aria-label="Lifecycle: a draft listing as kind 30403 becomes a published kind 30402 with status active, then status sold">111 <rect class="d-actor" x="15" y="45" width="150" height="56" rx="8"/>112 <text class="d-actor-label" x="90" y="70" text-anchor="middle">kind 30403</text>113 <text class="d-note" x="90" y="88" text-anchor="middle">draft / inactive</text>114 <rect class="d-actor" x="215" y="45" width="150" height="56" rx="8"/>115 <text class="d-actor-label" x="290" y="70" text-anchor="middle">kind 30402</text>116 <text class="d-note" x="290" y="88" text-anchor="middle">status: active</text>117 <rect class="d-actor" x="415" y="45" width="130" height="56" rx="8"/>118 <text class="d-actor-label" x="480" y="70" text-anchor="middle">kind 30402</text>119 <text class="d-note" x="480" y="88" text-anchor="middle">status: sold</text>120 <path class="d-msg d-flow" d="M167,73 L212,73"/>121 <path class="d-msg d-flow" d="M367,73 L412,73"/>122 <text class="d-label" x="190" y="38" text-anchor="middle">publish</text>123 <text class="d-label" x="390" y="38" text-anchor="middle">edit</text>124 <text class="d-note" x="280" y="132" text-anchor="middle">Addressable: each edit replaces the previous version with the same d tag value.</text>125 </svg>126 </div>127 <figcaption>Fig. 99-2 — <b>Listing lifecycle.</b> Draft as <code>kind:30403</code>, publish as <code>kind:30402</code>, mark as sold with the <code>status</code> tag.</figcaption>128 </figure>129130 <h2 class="bar" id="metadata"><span class="num">3</span> Metadata Tags</h2>131 <p>Structured metadata lives in the tags array. The following tags are standardized. Clients SHOULD include them. Other tags may be added as necessary.</p>132133 <div class="tscroll"><table class="ref">134 <caption>Standardized metadata tags</caption>135 <tr><th>Tag</th><th>Value</th><th>Rule</th></tr>136 <tr><td class="btn">title</td><td>string</td><td>A title for the listing.</td></tr>137 <tr><td class="btn">summary</td><td>string</td><td>A short tagline or summary for the listing.</td></tr>138 <tr><td class="btn">published_at</td><td>string</td><td>The unix timestamp, in seconds, of the first time the listing was published. Converted to a string.</td></tr>139 <tr><td class="btn">location</td><td>string</td><td>The location of the listing.</td></tr>140 <tr><td class="btn">price</td><td>array</td><td>The price of the thing being listed. See the price format below.</td></tr>141 <tr><td class="btn">status</td><td>string</td><td>Optional. The status of the listing. SHOULD be either <code>active</code> or <code>sold</code>.</td></tr>142 </table></div>143144 <div class="tscroll"><table class="ref">145 <caption>Other useful tags</caption>146 <tr><th>Tag</th><th>Value</th><th>Rule</th></tr>147 <tr><td class="btn">t</td><td>string</td><td>A category, keyword, or hashtag of relevance for the listing. Use one <code>t</code> tag per keyword.</td></tr>148 <tr><td class="btn">image</td><td>URL + dimensions</td><td>An image of the listing, whether included in the Markdown content or not. Clients SHOULD use <code>image</code> tags as described in <a href="58.html">NIP-58</a>. This lets clients display images in carousel format more easily.</td></tr>149 <tr><td class="btn">g</td><td>geohash</td><td>A geohash for a more precise location.</td></tr>150 </table></div>151152 <h3>The price tag</h3>153 <p>The <code>price</code> tag is an array with two to four elements:</p>154 <div class="crt">155 <div class="titlebar">Price tag format</div>156<pre>[<span class="s">"price"</span>, <span class="c">&lt;number&gt;</span>, <span class="c">&lt;currency&gt;</span>, <span class="c">&lt;frequency&gt;</span>]</pre>157 </div>158 <ul>159 <li><code>price</code> is the name of the tag.</li>160 <li><code>&lt;number&gt;</code> is the amount in numeric format, but included in the tag as a string.</li>161 <li><code>&lt;currency&gt;</code> is the currency unit in 3-character ISO 4217 format, or an ISO 4217-like currency code such as <code>btc</code> or <code>eth</code>.</li>162 <li><code>&lt;frequency&gt;</code> is optional. It describes recurring payments. It SHOULD be in noun format: hour, day, week, month, year, and so on.</li>163 </ul>164 <div class="crt">165 <div class="titlebar">Price examples</div>166<pre>[<span class="s">"price"</span>, <span class="s">"50"</span>, <span class="s">"USD"</span>] <span class="c">$50, one-time payment</span>167[<span class="s">"price"</span>, <span class="s">"15"</span>, <span class="s">"EUR"</span>, <span class="s">"month"</span>] <span class="c">€15 per month</span>168[<span class="s">"price"</span>, <span class="s">"50000"</span>, <span class="s">"GBP"</span>, <span class="s">"year"</span>] <span class="c">£50,000 per year</span></pre>169 </div>170171 <div class="box tech">172 <span class="tag">Tech Note</span>173 <p>Two oddities in the source spec. First, the <code>image</code> tag format is defined in <a href="58.html">NIP-58</a>, the Badges NIP — an unusual home for a general-purpose image tag. Second, in the spec's own example event, <code>published_at</code> (<code>1296962229</code>, year 2011) predates <code>created_at</code> (<code>1675642635</code>, year 2023). Treat those values as placeholders. The e-commerce extension is also an external document outside the NIPs repository.</p>174 </div>175176 <h2 class="bar" id="examples"><span class="num">4</span> Worked Example</h2>177 <p>The event below lists an item for 100 USD in NYC. The <code>d</code> tag makes the event addressable, so the seller can edit it later. The <code>e</code> and <code>a</code> tags reference a related event and a related article, as defined in <a href="01.html">NIP-01</a>. The Markdown content may embed <code>nostr:</code> links.</p>178179 <div class="crt">180 <div class="titlebar">Example - kind 30402 listing</div>181<pre>{182 <span class="k">"kind"</span>: 30402,183 <span class="k">"created_at"</span>: 1675642635,184 <span class="k">"content"</span>: <span class="s">"Lorem [ipsum][nostr:nevent1qqst8cujky046…] dolor sit amet,185 consectetur adipiscing elit…\n\nRead more at nostr:naddr1qqzkjurnw4ksz…"</span>,186 <span class="k">"tags"</span>: [187 [<span class="s">"d"</span>, <span class="s">"lorem-ipsum"</span>],188 [<span class="s">"title"</span>, <span class="s">"Lorem Ipsum"</span>],189 [<span class="s">"published_at"</span>, <span class="s">"1296962229"</span>],190 [<span class="s">"t"</span>, <span class="s">"electronics"</span>],191 [<span class="s">"image"</span>, <span class="s">"https://url.to.img"</span>, <span class="s">"256x256"</span>],192 [<span class="s">"summary"</span>, <span class="s">"More lorem ipsum that is a little more than the title"</span>],193 [<span class="s">"location"</span>, <span class="s">"NYC"</span>],194 [<span class="s">"price"</span>, <span class="s">"100"</span>, <span class="s">"USD"</span>],195 [<span class="s">"e"</span>, <span class="s">"b3e392b11f5d4f28321cedd09303a748…"</span>, <span class="s">"wss://relay.example.com"</span>],196 [<span class="s">"a"</span>, <span class="s">"30023:a695f6b60119d9521934a691347d9f78…:ipsum"</span>, <span class="s">"wss://relay.nostr.org"</span>]197 ],198 <span class="k">"pubkey"</span>: <span class="c">"…"</span>,199 <span class="k">"id"</span>: <span class="c">"…"</span>200}</pre>201 </div>202203 <p>Publishing and browsing use the plain <a href="01.html">NIP-01</a> flow. The seller publishes; a buyer filters by kind and category:</p>204 <div class="crt">205 <div class="titlebar">Session transcript - wss://relay.example.com</div>206<pre><span class="c">-- Seller publishes the listing --</span>207<span class="send">→ ["EVENT", {"kind":30402, "tags":[["d","lorem-ipsum"], …], …}]</span>208<span class="recv">← ["OK", "a91f52c3…", true, ""]</span>209210<span class="c">-- Buyer browses electronics listings --</span>211<span class="send">→ ["REQ", "market", {"kinds":[30402], "#t":["electronics"], "limit":20}]</span>212<span class="recv">← ["EVENT", "market", {"kind":30402, "id":"a91f52c3…", …}]</span>213<span class="recv">← ["EOSE", "market"]</span>214215<span class="c">-- Later: seller marks the item as sold (same d tag replaces the event) --</span>216<span class="send">→ ["EVENT", {"kind":30402, "tags":[["d","lorem-ipsum"], ["status","sold"], …], …}]</span>217<span class="recv">← ["OK", "c07de1b8…", true, ""]</span></pre>218 </div>219220 <h2 class="bar" id="history"><span class="num">5</span> Version History</h2>221 <p>NIP-99 started as a classifieds draft by Jeff Gardner in July 2023. The core has stayed stable since. Notable changes, newest first:</p>222 <ul class="patchnotes">223 <li><span class="ver">2025</span><span class="when">2025-07</span>Linked the GammaMarkets e-commerce extension proposal for interoperable market use.</li>224 <li><span class="ver">2024</span><span class="when">2024-08</span>Renamed "parameterized replaceable event" to "addressable event" across the repository.</li>225 <li><span class="ver">2024</span><span class="when">2024-01</span>Added the <code>status</code> tag (<code>active</code> / <code>sold</code>).</li>226 <li class="minor"><span class="ver">2023-26</span><span class="when">various</span>Formatting passes: JSON reformat, relative links, author list removed, list fixes, code-fence style.</li>227 <li><span class="ver">2023</span><span class="when">2023-07-18</span>Renumbered and retitled as NIP-99; price array format settled after review feedback.</li>228 <li><span class="ver">2023</span><span class="when">2023-07-14</span>Added <code>image</code> tags; changed the <code>price</code> tag to array format.</li>229 <li><span class="ver">Origin</span><span class="when">2023-07-13</span>Jeff Gardner published the initial draft for the classifieds NIP.</li>230 </ul>231232 <div class="credits">233 <h3 class="cardhead">Original Proposal - Credits</h3>234 <table>235 <tr><td>Author</td><td>Jeff Gardner</td></tr>236 <tr><td>First commit</td><td>2023-07-13 — “Add initial draft for classifieds NIP”</td></tr>237 <tr><td>Status</td><td>draft - optional — clients pick it up as needed</td></tr>238 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/99.md">99.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/99.md">full change history</a></td></tr>239 </table>240 </div>241242 <h2 class="bar"><span class="num">6</span> See Also</h2>243 <ul>244 <li><a href="01.html">NIP-01</a> — the base protocol; addressable events, the <code>d</code> tag, and the <code>e</code>/<code>a</code> reference tags.</li>245 <li><a href="15.html">NIP-15</a> — the strictly structured Nostr Marketplace; the heavier alternative.</li>246 <li><a href="23.html">NIP-23</a> — long-form content; listings share its event structure and Markdown content.</li>247 <li><a href="58.html">NIP-58</a> — badges; the source of the <code>image</code> tag format used here.</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">optional</span></dd>258 <dt>Defines</dt><dd>classified listings - price/status tags</dd>259 <dt>Kinds</dt><dd>30402 (listing) - 30403 (draft)</dd>260 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="58.html">NIP-58</a> image tags</dd>261 <dt>Content</dt><dd>Markdown string</dd>262 <dt>First commit</dt><dd>2023-07-13</dd>263 <dt>Last updated</dt><dd>2026-06-13</dd>264 </dl>265 </div>266 </div>267 </aside>268 </main>269270 <nav class="navbtns">271 <a href="98.html">◀ NIP-98: HTTP Auth</a>272 <a href="a0.html">NIP-A0: Voice Messages ▶</a>273 </nav>274275 <footer class="pagefoot">276 <a href="../index.html">Nostr Protocol Manual</a>277 <span class="pageno">NIP 99 / F4</span>278 </footer>279</div>280281<script src="../assets/webmcp.js" defer></script>282</body>283</html>