1 Overview
Nostr identifiers live inside Nostr apps. The rest of the world runs on links. This NIP standardizes one common URI scheme, nostr:, so any program can link to a Nostr entity. The goal is maximum interoperability and openness in the network.
A nostr: URI is a prefix plus one NIP-19 bech32 identifier. A webpage can link to a profile. An email can link to an event. An operating system can route the click to the user's preferred Nostr client. No app needs to know which client the user prefers.
The NIP also defines the reverse direction. An HTML page can declare, with standard <link> tags, that its content or its author also exists on Nostr. Section 3 covers this.
Register your client as the system handler for the nostr: scheme. Then every nostr: link on the web becomes a door into your app. Users click once and land on the right profile or event.
nostr: link travels from webpage to handler to client. The client decodes the identifier and fetches the entity.2 The URI Scheme
The scheme is nostr:. The identifier that comes after the colon is expected to be the same as an identifier defined in NIP-19, except nsec. A private key must never appear in a link.
nostr:<NIP-19 bech32 identifier, any prefix except nsec>
| Prefix | Points to | Allowed? |
|---|---|---|
| npub | a public key | Yes. |
| nprofile | a profile, with relay hints | Yes. |
| nevent | an event, with relay hints | Yes. |
| naddr | an addressable event coordinate | Yes. |
| note | a bare event id | Not excluded by the text. See the Tech Note below. |
| nsec | a private key | Never. The one explicit exclusion. |
The source spec lists these example URIs:
-- a public key -- nostr:npub1sn0wdenkukak0d9dfczzeacvhkrgz92ak56egt7vdgzn8pv2wfqqhrjdv9 -- a profile with relay hints -- nostr:nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p -- an event with relay hints -- nostr:nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm
Never build a nostr: URI around an nsec identifier. A URI is made to be shared. A shared nsec is a leaked private key, and the account it controls is lost.
The spec excludes only nsec. It does not exclude note. Yet a 2026-03 edit removed all note1 mentions from the document. So nostr:note1… is not forbidden by the text, but the spec no longer shows it. Prefer nevent, which carries relay hints. The spec also gives no rule for unknown or malformed identifiers; handling is left to the client.
3 Linking HTML Pages to Nostr Entities
Some content exists in two mediums at once. For example, a web server exposes Markdown articles as HTML pages and also as kind:30023 events, served under itself as a relay or through some other relay. Standard HTML <link> tags bind the two copies together. The href of each tag is a nostr: URI.
| rel value | Associates the page with | Typical href |
|---|---|---|
| alternate | the Nostr event that carries the same content | nostr:naddr1… or another event identifier |
| me | the Nostr profile of the page's owner | nostr:nprofile1… or nostr:npub1… |
| author | the Nostr profile of the page's author | nostr:nprofile1… or nostr:npub1… |
Use rel="alternate" when the same content is served via the two mediums. Use rel="me" or rel="author" to assign authorship of a webpage to a Nostr profile. A crawler or a browser extension reads these tags and offers the Nostr version of the page or its author.
rel="alternate" and its Nostr author with rel="me" or rel="author".4 Worked Examples
The first block is the spec's own example of a page that serves the same article as a kind:30023 event. The naddr identifier names the addressable event coordinate.
<head> <link rel="alternate" href="nostr:naddr1qqyrzwrxvc6ngvfkqyghwumn8ghj7enfv 96x5ctx9e3k7mgzyqalp33lewf5vdq847t6te0wvnags0gs0mu72kz8938tn24wlfze6qc yqqq823cph95ag" /> </head>
The second block assigns authorship of a webpage to a Nostr profile. The rel="me" and rel="author" relations work the same way; the spec shows rel="me".
<head> <link rel="me" href="nostr:nprofile1qyxhwumn8ghj7mn0wvhxcmmvqyd8wumn8ghj7 un9d3shjtnhv4ehgetjde38gcewvdhk6qpq80cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j 4s3evf6u64th6gkwswpnfsn" /> </head>
The third block shows the client side. The client receives a nostr: URI from the OS handler. It decodes the NIP-19 payload, reads the relay hints, and fetches the entity with a normal NIP-01 subscription.
-- OS hands the client: nostr:nevent1qqstna2yre… -- -- client decodes: id = 5c83…, relays = wss://relay.example.com -- → ["REQ", "uri1", {"ids":["5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]}] ← ["EVENT", "uri1", {"id":"5c83da77af1d…", "kind":1, "content":"…", …}] ← ["EOSE", "uri1"] → ["CLOSE", "uri1"] -- client renders the event --
5 Version History
NIP-21 is short and stable. It gained one major feature since birth: the HTML link associations. Notable changes, newest first:
- 20262026-03Removed all mentions of
note1identifiers from the examples. - 20252025-05Added the HTML
<link>associations:rel="alternate"for events,rel="me"andrel="author"for profiles. - 20232023-05Renamed the feature from "URL scheme" to "URI scheme".
- 2023+2023-2025Housekeeping: author list removed, links made relative, markup fixes.
- Origin2023-01fiatjaf added NIP-21, the
nostr:url scheme.
Original Proposal - Credits
| Author | fiatjaf |
| First commit | 2023-01-24 — “add NIP-21, `nostr:` url scheme.” |
| Status | draft - optional — implement it to make your entities linkable |
| Source | 21.md on GitHub - full change history |
6 See Also
- NIP-19 — defines the bech32 identifiers that follow the
nostr:prefix. - NIP-01 — the base protocol; how a client fetches the entity a URI names.
- NIP-23 —
kind:30023long-form articles, the spec's example forrel="alternate". - NIP-27 — how
nostr:URIs appear inside eventcontentas text mentions. - NIP-05 — another bridge between the web and Nostr identities, via DNS names.