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-75 - Zap Goals — Nostr Instruction Manual</title>7<meta name="description" content="NIP-75: zap goals. The kind 9041 fundraising goal event, its amount and relays tags, and how clients tally zaps toward a target. 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 75 - Payments</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="75">75</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 75</div>50 <h1>Zap Goals</h1>51 <p class="sub">A fundraising target as a single event. Supporters zap the goal, and clients tally the receipts against the amount.</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>zap goal</strong> is a fundraising target published as a Nostr event. The creator states a target amount and a description. Supporters contribute by zapping the goal event with the <a href="57.html">NIP-57</a> zap flow. Clients read the zap receipts and show a progress bar toward the target.</p>60 <p>The goal event names the relays that collect its zap receipts. Every zap to the goal goes to those relays. A client can therefore tally the goal from a known, small set of relays. No payment server or crowdfunding platform is needed.</p>61 <p>Goals also attach to other content. A long-form post, a badge, or a live stream can point at a goal with a <code>goal</code> tag. Clients then show the fundraiser next to that content.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>Read <a href="57.html">NIP-57</a> first. This NIP does not define a new payment path. It only defines the target event that existing zaps point at.</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 200" role="img" aria-label="A creator publishes a goal event; supporters send zaps; zap receipts land on the goal's listed relays; a client tallies them into progress">71 <rect class="d-actor" x="10" y="20" width="110" height="50" rx="8"/>72 <text class="d-actor-label" x="65" y="42" text-anchor="middle">Creator</text>73 <text class="d-note" x="65" y="59" text-anchor="middle">kind 9041</text>74 <rect class="d-actor" x="10" y="126" width="110" height="50" rx="8"/>75 <text class="d-actor-label" x="65" y="148" text-anchor="middle">Supporter</text>76 <text class="d-note" x="65" y="165" text-anchor="middle">zap</text>77 <rect class="d-actor" x="225" y="72" width="110" height="50" rx="8"/>78 <text class="d-actor-label" x="280" y="94" text-anchor="middle">Goal relays</text>79 <text class="d-note" x="280" y="111" text-anchor="middle">"relays" tag</text>80 <rect class="d-actor" x="440" y="72" width="110" height="50" rx="8"/>81 <text class="d-actor-label" x="495" y="94" text-anchor="middle">Client</text>82 <text class="d-note" x="495" y="111" text-anchor="middle">tally</text>83 <path class="d-msg d-flow" d="M122,50 C170,58 180,74 223,84"/>84 <path class="d-msg d-flow" d="M122,146 C170,138 180,122 223,112"/>85 <path class="d-msg blue d-flow" d="M337,97 L437,97"/>86 <text class="d-label" x="168" y="52" text-anchor="middle">GOAL</text>87 <text class="d-label" x="168" y="146" text-anchor="middle">ZAP RECEIPTS</text>88 <text class="d-label" x="387" y="90" text-anchor="middle">kind 9735</text>89 <circle r="4" fill="#f26a00">90 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,146 C170,138 180,122 223,112"/>91 </circle>92 <circle r="4" fill="#2e5f9e">93 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M337,97 L437,97"/>94 </circle>95 </svg>96 </div>97 <figcaption>Fig. 75-1 — <b>The tally loop.</b> The goal lists its relays. Zap receipts land there. A client sums them against the target amount.</figcaption>98 </figure>99100 <h2 class="bar" id="spec"><span class="num">2</span> The Goal Event</h2>101 <p>A zap goal is a <code>kind:9041</code> event. This is a regular event under <a href="01.html">NIP-01</a> rules: relays store all goals, and a published goal is not replaceable. The <code>content</code> field holds a human-readable description of the goal.</p>102103 <p>Two tags are <strong>required</strong>:</p>104 <div class="tscroll"><table class="ref">105 <caption>Required tags on kind 9041</caption>106 <tr><th>Tag</th><th>Value</th><th>Rule</th></tr>107 <tr><td class="btn">amount</td><td>integer string</td><td>The target amount in millisats.</td></tr>108 <tr><td class="btn">relays</td><td>one or more relay URLs</td><td>The relays that zaps to this goal go to. Clients tally the goal from these relays. All URLs sit in this one tag.</td></tr>109 </table></div>110111 <div class="crt">112 <div class="titlebar">Wire format - minimal goal event</div>113<pre>{114 <span class="k">"kind"</span>: 9041,115 <span class="k">"tags"</span>: [116 [<span class="s">"relays"</span>, <span class="s">"wss://alicerelay.example.com"</span>, <span class="s">"wss://bobrelay.example.com"</span>, <span class="c">...</span>],117 [<span class="s">"amount"</span>, <span class="s">"210000"</span>]118 ],119 <span class="k">"content"</span>: <span class="s">"Nostrasia travel expenses"</span>,120 <span class="c">// other NIP-01 fields: id, pubkey, created_at, sig</span>121}</pre>122 </div>123124 <p>Three tags are <strong>optional</strong>:</p>125 <div class="tscroll"><table class="ref">126 <caption>Optional tags on kind 9041</caption>127 <tr><th>Tag</th><th>Value</th><th>Rule</th></tr>128 <tr><td class="btn">closed_at</td><td>unix timestamp, seconds</td><td>The tally cutoff. Zap receipts published after this timestamp should not count toward the goal progress.</td></tr>129 <tr><td class="btn">image</td><td>image URL</td><td>An image for the goal.</td></tr>130 <tr><td class="btn">summary</td><td>string</td><td>A brief description, shorter than <code>content</code>.</td></tr>131 </table></div>132133 <div class="crt">134 <div class="titlebar">Wire format - goal event with optional tags</div>135<pre>{136 <span class="k">"kind"</span>: 9041,137 <span class="k">"tags"</span>: [138 [<span class="s">"relays"</span>, <span class="s">"wss://alicerelay.example.com"</span>, <span class="s">"wss://bobrelay.example.com"</span>, <span class="c">...</span>],139 [<span class="s">"amount"</span>, <span class="s">"210000"</span>],140 [<span class="s">"closed_at"</span>, <span class="c"><unix timestamp in seconds></span>],141 [<span class="s">"image"</span>, <span class="c"><image URL></span>],142 [<span class="s">"summary"</span>, <span class="c"><description of the goal></span>]143 ],144 <span class="k">"content"</span>: <span class="s">"Nostrasia travel expenses"</span>,145 <span class="c">// other fields...</span>146}</pre>147 </div>148149 <p>Two more tags <strong>may</strong> appear on the goal:</p>150 <ul>151 <li>An <code>r</code> tag or an <code>a</code> tag. It links the goal to a URL or to an addressable event (see <a href="01.html">NIP-01</a>).</li>152 <li>One or more <code>zap</code> tags from <a href="57.html">NIP-57</a> Appendix G. They split the raised funds across multiple beneficiary pubkeys.</li>153 </ul>154155 <div class="box tech">156 <span class="tag">Tech Note</span>157 <p>Two soft spots in the source spec. First, the <code>closed_at</code> cutoff filters receipts by when they are <em>published</em>, but a zap receipt's <code>created_at</code> is set by the lnurl server, so the exact clock to compare against is not defined. Second, <code>relays</code>, <code>amount</code>, and <code>goal</code> are multi-letter tag names, so relays do not index them under <a href="01.html">NIP-01</a>; a client cannot query "all events for goal X" with a <code>#goal</code> filter and must scan or rely on the <code>e</code> tag in zap requests instead.</p>158 </div>159160 <h2 class="bar" id="linking"><span class="num">3</span> Linking Content to a Goal</h2>161 <p>An addressable event can link to a goal with a <code>goal</code> tag. The tag holds the goal's event id and an optional relay hint:</p>162 <div class="crt">163 <div class="titlebar">Wire format - addressable event pointing at a goal</div>164<pre>{165 <span class="k">"kind"</span>: <span class="c">3xxxx</span>,166 <span class="k">"tags"</span>: [167 [<span class="s">"goal"</span>, <span class="c"><event id></span>, <span class="c"><relay URL (optional)></span>],168 <span class="c">// rest of tags...</span>169 ],170 <span class="c">// other fields...</span>171}</pre>172 </div>173 <p>This makes the goal reusable. One fundraiser can appear on a long-form post, on a badge, and on a live stream at the same time. Each of those events carries the same <code>goal</code> tag.</p>174175 <figure class="diagram">176 <div class="frame">177 <svg viewBox="0 0 560 180" role="img" aria-label="Addressable events point at one goal event with goal tags; the goal splits funds to beneficiary pubkeys with zap tags">178 <rect class="d-actor" x="10" y="14" width="130" height="42" rx="8"/>179 <text class="d-actor-label" x="75" y="40" text-anchor="middle">Long-form post</text>180 <rect class="d-actor" x="10" y="70" width="130" height="42" rx="8"/>181 <text class="d-actor-label" x="75" y="96" text-anchor="middle">Live stream</text>182 <rect class="d-actor" x="10" y="126" width="130" height="42" rx="8"/>183 <text class="d-actor-label" x="75" y="152" text-anchor="middle">Badge</text>184 <rect class="d-actor" x="240" y="66" width="120" height="50" rx="8"/>185 <text class="d-actor-label" x="300" y="88" text-anchor="middle">Goal</text>186 <text class="d-note" x="300" y="105" text-anchor="middle">kind 9041</text>187 <rect class="d-actor" x="440" y="34" width="110" height="42" rx="8"/>188 <text class="d-actor-label" x="495" y="60" text-anchor="middle">Alice</text>189 <rect class="d-actor" x="440" y="106" width="110" height="42" rx="8"/>190 <text class="d-actor-label" x="495" y="132" text-anchor="middle">Bob</text>191 <path class="d-msg d-flow" d="M142,35 C190,42 200,72 237,82"/>192 <path class="d-msg d-flow" d="M142,91 L237,91"/>193 <path class="d-msg d-flow" d="M142,147 C190,140 200,110 237,100"/>194 <path class="d-msg blue d-flow" d="M362,80 C400,74 405,62 437,56"/>195 <path class="d-msg blue d-flow" d="M362,102 C400,108 405,120 437,126"/>196 <text class="d-label" x="188" y="80" text-anchor="middle">goal tag</text>197 <text class="d-label" x="400" y="46" text-anchor="middle">zap tags</text>198 </svg>199 </div>200 <figcaption>Fig. 75-2 — <b>One goal, many surfaces.</b> Content links in with <code>goal</code> tags. Funds split out with <code>zap</code> tags.</figcaption>201 </figure>202203 <h2 class="bar" id="client"><span class="num">4</span> Client Behavior</h2>204 <p>The source NIP sets three client rules:</p>205 <div class="tscroll"><table class="ref">206 <caption>Client rules</caption>207 <tr><th>Level</th><th>Rule</th></tr>208 <tr><td class="btn">MAY</td><td>Display funding goals on user profiles.</td></tr>209 <tr><td class="btn">MUST</td><td>When zapping a goal event, copy the relays from the goal's <code>relays</code> tag into the <code>relays</code> tag of the <a href="57.html">NIP-57</a> zap request.</td></tr>210 <tr><td class="btn">SHOULD</td><td>When zapping an addressable event that carries a <code>goal</code> tag, put the goal's event id in the <code>e</code> tag of the zap request.</td></tr>211 </table></div>212 <div class="box warn">213 <span class="tag">Warning!</span>214 <p>The MUST rule is the whole tally mechanism. If a client zaps a goal but sends the receipt to other relays, the contribution exists on the network yet never shows in the progress bar. Always copy the goal's <code>relays</code> tag into the zap request.</p>215 </div>216 <p>The source lists two use cases. Fundraising clients build the whole experience around kind 9041. Content clients attach goals to events such as long-form posts, badges, or live streams.</p>217218 <h2 class="bar" id="examples"><span class="num">5</span> Worked Example</h2>219 <p>Alice raises 210 000 sats for Nostrasia travel. She publishes a goal. Bob zaps it 21 000 sats. The transcript shows the goal, Bob's zap request, and the receipt that the tally counts.</p>220 <div class="crt">221 <div class="titlebar">Session transcript - goal, zap, tally</div>222<pre><span class="c">-- Alice publishes the goal (target in millisats) --</span>223<span class="send">→ ["EVENT", {"id":"f9a02b6c11…","pubkey":"a1ice9f2…","kind":9041,224 "created_at":1749760000,225 "tags":[["relays","wss://alicerelay.example.com","wss://bobrelay.example.com"],226 ["amount","210000000"],227 ["closed_at","1752400000"],228 ["image","https://example.com/nostrasia.png"],229 ["summary","Help me get to Nostrasia"]],230 "content":"Nostrasia travel expenses","sig":"77ab01fe…"}]</span>231<span class="recv">← ["OK", "f9a02b6c11…", true, ""]</span>232233<span class="c">-- Bob's client builds a NIP-57 zap request for the goal --</span>234<span class="c">-- MUST: relays copied from the goal's "relays" tag --</span>235<span class="send">→ kind 9734 zap request: {"kind":9734,"content":"Godspeed!",236 "tags":[["relays","wss://alicerelay.example.com","wss://bobrelay.example.com"],237 ["amount","21000000"],238 ["e","f9a02b6c11…"],239 ["p","a1ice9f2…"]], …}</span>240241<span class="c">-- Bob pays the invoice; the lnurl server publishes the receipt --</span>242<span class="recv">← ["EVENT", "goalsub", {"kind":9735, "tags":[["e","f9a02b6c11…"],243 ["p","a1ice9f2…"], ["bolt11","lnbc210m…"], ["description","…"]], …}]</span>244245<span class="c">-- tally: 21 000 000 / 210 000 000 millisats = 10% funded --</span></pre>246 </div>247 <p>To render the progress bar, a client subscribes on the goal's relays with a filter such as <code>{"kinds":[9735], "#e":["f9a02b6c11…"]}</code>. It sums the receipt amounts. It drops receipts published after <code>closed_at</code>.</p>248249 <h2 class="bar" id="history"><span class="num">6</span> Version History</h2>250 <p>NIP-75 has stayed close to its original shape. Notable changes, newest first:</p>251 <ul class="patchnotes">252 <li><span class="ver">2024</span><span class="when">2024-09</span>Renamed "parameterized replaceable event" to "addressable event" across the text, matching the <a href="01.html">NIP-01</a> vocabulary change.</li>253 <li><span class="ver">2023</span><span class="when">2023-11</span>Added the optional <code>image</code> and <code>summary</code> tags.</li>254 <li class="minor"><span class="ver">2023</span><span class="when">2023-11</span>JSON reformatting; author lines removed from all NIPs.</li>255 <li><span class="ver">Origin</span><span class="when">2023-09</span>Alejandro proposed Zap Goals in PR #757.</li>256 </ul>257258 <div class="credits">259 <h3 class="cardhead">Original Proposal - Credits</h3>260 <table>261 <tr><td>Author</td><td>Alejandro</td></tr>262 <tr><td>First commit</td><td>2023-09-01 — “NIP-75: Zap Goals (<a href="https://github.com/nostr-protocol/nips/pull/757">#757</a>)”</td></tr>263 <tr><td>Status</td><td>draft - optional</td></tr>264 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/75.md">75.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/75.md">full change history</a></td></tr>265 </table>266 </div>267268 <h2 class="bar"><span class="num">7</span> See Also</h2>269 <ul>270 <li><a href="01.html">NIP-01</a> — the base event format, tag rules, and storage classes that kind 9041 follows.</li>271 <li><a href="57.html">NIP-57</a> — the zap flow: zap requests (kind 9734), zap receipts (kind 9735), and the <code>zap</code> beneficiary tag.</li>272 <li><a href="23.html">NIP-23</a> — long-form posts, a common host for <code>goal</code> tags.</li>273 <li><a href="58.html">NIP-58</a> — badges, another event type that can carry a funding goal.</li>274 <li><a href="53.html">NIP-53</a> — live activities; live streams often attach zap goals.</li>275 </ul>276 </div>277278 <aside>279 <div class="cartridge">280 <div class="inner">281 <h3 class="cardhead">Spec Card</h3>282 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>283 <dl>284 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip">optional</span></dd>285 <dt>Defines</dt><dd>kind 9041 - amount/relays/closed_at/image/summary tags - goal tag</dd>286 <dt>Kind(s)</dt><dd>9041 (regular)</dd>287 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="57.html">NIP-57</a></dd>288 <dt>Payments</dt><dd>Lightning zaps - amounts in millisats</dd>289 <dt>First commit</dt><dd>2023-09-01</dd>290 <dt>Last updated</dt><dd>2026-06-13</dd>291 </dl>292 </div>293 </div>294 </aside>295 </main>296297 <nav class="navbtns">298 <a href="73.html">◀ NIP-73: External Content IDs</a>299 <a href="77.html">NIP-77: Negentropy Syncing ▶</a>300 </nav>301302 <footer class="pagefoot">303 <a href="../index.html">Nostr Protocol Manual</a>304 <span class="pageno">NIP 75 / F4</span>305 </footer>306</div>307308<script src="../assets/webmcp.js" defer></script>309</body>310</html>