1 Overview
A web bookmark is a saved reference to one web page. This NIP defines kind:39701 for web bookmarks. Each bookmark is one event. The bookmarked URI lives in the event's d tag.
Kind 39701 sits in the addressable range of NIP-01. A relay keeps only the latest event per pubkey + kind + d value. A user can therefore edit a bookmark. The user publishes a new event with the same d value, and the old version goes away.
Because the d value is the URI itself, clients can query bookmarks by URI. One #d filter returns every user's bookmark of the same page. This turns private bookmarking into a shared, social index of the web.
Do not confuse this NIP with the bookmark lists of NIP-51. A NIP-51 list stores many references inside one event. A NIP-B0 bookmark is one standalone event per URI, with its own description, topics, and comments.
d value and gets both.2 The Bookmark Event
A web bookmark is a normal signed event with kind:39701. The content field holds a detailed description of the bookmark. The description can be an empty string. The d tag is required. All other tags are optional metadata.
{
"kind": 39701,
"content": <description of the bookmark, may be "">,
"tags": [
["d", <URI of the bookmarked page>], // required
["published_at", <unix seconds, string>], // optional
["title", <title of the bookmark>], // optional
["t", <topic>], ... // optional, repeatable
],
// plus the standard id, pubkey, created_at, sig fields
}
| Field | Rule |
|---|---|
| kind | Always 39701. Addressable per NIP-01: relays keep the latest event per pubkey + kind + d value. |
| content | A detailed description of the web bookmark. An empty string is allowed. |
| tags | Must contain one d tag. May contain the metadata tags of §4. |
3 The d Tag: One URI per Bookmark
The d tag value is the URI of the bookmarked page. One rule shapes the value. If the scheme is https, omit all characters before the hostname. Drop https:// and start the value at the hostname. For any other scheme, keep the URI as it is.
https://alice.blog/post → "alice.blog/post" // https scheme dropped http://old.example/page → "http://old.example/page" gemini://caps.example/doc → "gemini://caps.example/doc"
This rule makes the d value predictable. Clients query web bookmark events by the d tag. A filter such as {"kinds": [39701], "#d": ["alice.blog/post"]} returns every bookmark of that page, from every user, on that relay.
d value edits the bookmark.The spec defines no URI normalization beyond dropping the https:// prefix. It does not say how to treat trailing slashes, www. prefixes, query strings, or fragments. Two clients can derive different d values for the same page, and those bookmarks will not match in a #d query. The spec also does not state which HTML link attribute the title tag maps to.
4 Metadata Tags
Metadata fields can be added to the event as tags when necessary. This NIP names three:
| Tag | Value | Purpose |
|---|---|---|
| t | topic string | A tag or hashtag: a topic about which the event might be of relevance. Repeat the tag for each topic. |
| published_at | unix seconds, stringified | The timestamp of the first time the bookmark was published. Later edits keep this value. |
| title | title string | A title for the bookmark. It can serve as an attribute for the HTML link element. |
5 Replies and Comments
Replies to a kind:39701 bookmark must use kind:1111 comment events, as defined in NIP-22. Do not reply with plain kind-1 notes. The NIP-22 comment carries scope tags that point back to the bookmark's address, so threads stay attached to the bookmark even after edits.
6 Worked Example
Alice bookmarks a blog post at https://alice.blog/post. The scheme is https, so the d value starts at the hostname. She adds a title, two topics, and a first-publication timestamp.
{
"kind": 39701,
"id": "d7a92714f81d0f712e715556aee69ea6da6bfb287e6baf794a095d301d603ec7",
"pubkey": "2729620da105979b22acfdfe9585274a78c282869b493abfa4120d3af2061298",
"created_at": 1738869705,
"tags": [
// required tags
["d", "alice.blog/post"],
// optional tags
["published_at", "1738863000"],
["title", "Blog insights by Alice"],
["t", "post"],
["t", "insight"]
],
"content": "A marvelous insight by Alice about the nature of blogs and posts.",
"sig": "36d34e6448fe0223e9999361c39c492a208bc423d2fcdfc2a3404e04df7c22dc65bbbd62dbe8a4373c62e4d29aac285b5aa4bb9b4b8053bd6207a8b45fbd0c98"
}
A reader now queries the relay for every bookmark of that page. Later, Alice edits her description. She republishes with the same d value, and the relay replaces the old event.
-- Alice publishes the bookmark -- → ["EVENT", {"kind":39701, "id":"d7a92714…", "tags":[["d","alice.blog/post"], …], …}] ← ["OK", "d7a92714…", true, ""] -- a reader looks the page up by its d value -- → ["REQ", "bm", {"kinds":[39701], "#d":["alice.blog/post"]}] ← ["EVENT", "bm", {"kind":39701, "pubkey":"2729620d…", "content":"A marvelous insight…", …}] ← ["EOSE", "bm"] -- Alice edits: same d value, newer created_at -- → ["EVENT", {"kind":39701, "id":"4c01afe2…", "created_at":1738900000, "tags":[["d","alice.blog/post"], ["published_at","1738863000"], …], "content":"Updated notes on Alice's post.", …}] ← ["OK", "4c01afe2…", true, ""] // relay now serves only this version
7 Version History
NIP-B0 is young and small. Its one substantive revision fixed how schemes are handled in the d value. Notable changes, newest first:
- 20262026-07Fixed the URI scheme ambiguity: only the
httpsscheme is omitted from thedvalue; other schemes stay verbatim. A misapplied suggestion from the same change was corrected the same day. - 2025-262025-08Wording cleanup and code-fence relabeling passes.
- 20252025-04Renamed to the uppercase
B0.mdfilename shortly after merge. - Origin2025-04-24Sebastian Hagens proposed
kind:39701web bookmarks in PR #1849.
Original Proposal - Credits
| Author | Sebastian Hagens |
| First commit | 2025-04-24 — “adding more info / requirements for using kind 39701 for web bookmarks (NIP-B0)” (PR #1849) |
| Status | draft - optional |
| Source | B0.md on GitHub - full change history |
8 See Also
- NIP-01 — addressable events, the
dtag, and#dfilters that this NIP relies on. - NIP-22 —
kind:1111comments; the mandatory reply format for bookmarks. - NIP-51 — bookmark lists (
kind:10003); many references in one event, instead of one event per URI. - NIP-73 — external content IDs; another way to reference web URLs from events.