1 Overview
A zap goal 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 NIP-57 zap flow. Clients read the zap receipts and show a progress bar toward the target.
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.
Goals also attach to other content. A long-form post, a badge, or a live stream can point at a goal with a goal tag. Clients then show the fundraiser next to that content.
Read NIP-57 first. This NIP does not define a new payment path. It only defines the target event that existing zaps point at.
2 The Goal Event
A zap goal is a kind:9041 event. This is a regular event under NIP-01 rules: relays store all goals, and a published goal is not replaceable. The content field holds a human-readable description of the goal.
Two tags are required:
| Tag | Value | Rule |
|---|---|---|
| amount | integer string | The target amount in millisats. |
| relays | one or more relay URLs | The relays that zaps to this goal go to. Clients tally the goal from these relays. All URLs sit in this one tag. |
{
"kind": 9041,
"tags": [
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", ...],
["amount", "210000"]
],
"content": "Nostrasia travel expenses",
// other NIP-01 fields: id, pubkey, created_at, sig
}
Three tags are optional:
| Tag | Value | Rule |
|---|---|---|
| closed_at | unix timestamp, seconds | The tally cutoff. Zap receipts published after this timestamp should not count toward the goal progress. |
| image | image URL | An image for the goal. |
| summary | string | A brief description, shorter than content. |
{
"kind": 9041,
"tags": [
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", ...],
["amount", "210000"],
["closed_at", <unix timestamp in seconds>],
["image", <image URL>],
["summary", <description of the goal>]
],
"content": "Nostrasia travel expenses",
// other fields...
}
Two more tags may appear on the goal:
- An
rtag or anatag. It links the goal to a URL or to an addressable event (see NIP-01). - One or more
zaptags from NIP-57 Appendix G. They split the raised funds across multiple beneficiary pubkeys.
Two soft spots in the source spec. First, the closed_at cutoff filters receipts by when they are published, but a zap receipt's created_at is set by the lnurl server, so the exact clock to compare against is not defined. Second, relays, amount, and goal are multi-letter tag names, so relays do not index them under NIP-01; a client cannot query "all events for goal X" with a #goal filter and must scan or rely on the e tag in zap requests instead.
3 Linking Content to a Goal
An addressable event can link to a goal with a goal tag. The tag holds the goal's event id and an optional relay hint:
{
"kind": 3xxxx,
"tags": [
["goal", <event id>, <relay URL (optional)>],
// rest of tags...
],
// other fields...
}
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 goal tag.
goal tags. Funds split out with zap tags.4 Client Behavior
The source NIP sets three client rules:
| Level | Rule |
|---|---|
| MAY | Display funding goals on user profiles. |
| MUST | When zapping a goal event, copy the relays from the goal's relays tag into the relays tag of the NIP-57 zap request. |
| SHOULD | When zapping an addressable event that carries a goal tag, put the goal's event id in the e tag of the zap request. |
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 relays tag into the zap request.
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.
5 Worked Example
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.
-- Alice publishes the goal (target in millisats) -- → ["EVENT", {"id":"f9a02b6c11…","pubkey":"a1ice9f2…","kind":9041, "created_at":1749760000, "tags":[["relays","wss://alicerelay.example.com","wss://bobrelay.example.com"], ["amount","210000000"], ["closed_at","1752400000"], ["image","https://example.com/nostrasia.png"], ["summary","Help me get to Nostrasia"]], "content":"Nostrasia travel expenses","sig":"77ab01fe…"}] ← ["OK", "f9a02b6c11…", true, ""] -- Bob's client builds a NIP-57 zap request for the goal -- -- MUST: relays copied from the goal's "relays" tag -- → kind 9734 zap request: {"kind":9734,"content":"Godspeed!", "tags":[["relays","wss://alicerelay.example.com","wss://bobrelay.example.com"], ["amount","21000000"], ["e","f9a02b6c11…"], ["p","a1ice9f2…"]], …} -- Bob pays the invoice; the lnurl server publishes the receipt -- ← ["EVENT", "goalsub", {"kind":9735, "tags":[["e","f9a02b6c11…"], ["p","a1ice9f2…"], ["bolt11","lnbc210m…"], ["description","…"]], …}] -- tally: 21 000 000 / 210 000 000 millisats = 10% funded --
To render the progress bar, a client subscribes on the goal's relays with a filter such as {"kinds":[9735], "#e":["f9a02b6c11…"]}. It sums the receipt amounts. It drops receipts published after closed_at.
6 Version History
NIP-75 has stayed close to its original shape. Notable changes, newest first:
- 20242024-09Renamed "parameterized replaceable event" to "addressable event" across the text, matching the NIP-01 vocabulary change.
- 20232023-11Added the optional
imageandsummarytags. - 20232023-11JSON reformatting; author lines removed from all NIPs.
- Origin2023-09Alejandro proposed Zap Goals in PR #757.
Original Proposal - Credits
| Author | Alejandro |
| First commit | 2023-09-01 — “NIP-75: Zap Goals (#757)” |
| Status | draft - optional |
| Source | 75.md on GitHub - full change history |
7 See Also
- NIP-01 — the base event format, tag rules, and storage classes that kind 9041 follows.
- NIP-57 — the zap flow: zap requests (kind 9734), zap receipts (kind 9735), and the
zapbeneficiary tag. - NIP-23 — long-form posts, a common host for
goaltags. - NIP-58 — badges, another event type that can carry a funding goal.
- NIP-53 — live activities; live streams often attach zap goals.