Step 1 of 6
An unknown kind shows up
Your social client sees, say, a kind 30023 article it can't render. Instead of a dead end, it can look for an app that handles that kind.
NIP-89
DraftEvents
When your app meets an event kind it can't show, it can find an app that can: apps announce which kinds they handle (31990) and people recommend them (31989).
Edit the form or the JSON: both stay in sync, the badge says whether the result is valid, and tapping any field explains it.
How the parts connect: Find an app for a kind
Not signed yet · Demo keys only. These personas' secret keys are public on purpose.
Select any field in the form or the JSON to see what it does.
Step 1 of 6
Your social client sees, say, a kind 30023 article it can't render. Instead of a dead end, it can look for an app that handles that kind.
Handler URLs are filled with NIP-19 entities (nevent, naddr, nprofile…).
Data vending machines announce the job kinds they serve with kind 31990.
Until a handler opens, clients show the event's alt text from NIP-31.
latest and next tags point at nsite manifests for web apps.
Ecash mints use the same announce-and-recommend pattern.
Specification text is quoted in English from the nostr-protocol/nips repository. Our explanations and the interface are translated. Source on GitHub at commit 0046368
This NIP describes kind:31989 and kind:31990: a way to discover applications that can handle unknown event-kinds.
Nostr's discoverability and transparent event interaction is one of its most interesting/novel mechanics. This NIP provides a simple way for clients to discover applications that handle events of a specific kind to ensure smooth cross-client and cross-kind interactions.
There are three actors to this workflow:
kind:31990, detailing how apps should redirect to itkind:31989kind:31989 and, based on results, queries for kind:31990{
"kind": 31989,
"pubkey": <recommender-user-pubkey>,
"tags": [
["d", <supported-event-kind>],
["a", "31990:app1-pubkey:<d-identifier>", "wss://relay1", "ios"],
["a", "31990:app2-pubkey:<d-identifier>", "wss://relay2", "web"]
],
// other fields...
}
The d tag in kind:31989 is the supported event kind this event is recommending.
Multiple a tags can appear on the same kind:31989.
The second value of the tag SHOULD be a relay hint. The third value of the tag SHOULD be the platform where this recommendation might apply.
{
"kind": 31990,
"pubkey": "<application-pubkey>",
"content": "<optional-kind:0-style-metadata>",
"tags": [
["d", <random-id>],
["k", <supported-event-kind>],
["latest", "35128:<application-pubkey>:<site-d-identifier>", "wss://relay1"],
["next", "35128:<application-pubkey>:<next-site-d-identifier>", "wss://relay1"],
["web", "https://..../a/<bech32>", "nevent"],
["web", "https://..../p/<bech32>", "nprofile"],
["web", "https://..../e/<bech32>"],
["ios", ".../<bech32>"]
],
// other fields...
}
content is an optional metadata-like stringified JSON object, as described in NIP-01. This content is useful when the pubkey creating the kind:31990 is not an application. If content is empty, the kind:0 of the pubkey should be used to display application information (e.g. name, picture, web, LUD16, etc.)k tags' value is the event kind that is supported by this kind:31990.
Using a k tag(s) (instead of having the kind of the d tag) provides:k tags can exist in the same event if the application supports more than one event kind and their handler URLs are the same.kind:31990 events SHOULD include latest and next tags referencing related nsite manifests when applicable. These tags use the same shape as an a tag: the second element is <kind>:<pubkey>:<d-tag> and the third element is an optional relay hint. latest SHOULD reference the current site manifest for the application, while next SHOULD reference the next site manifest intended for rollout or upgrade.bech32 in a URL MUST be replaced by clients with the NIP-19-encoded entity that should be loaded by the application.Multiple tags might be registered by the app, following NIP-19 nomenclature as the second value of the array.
A tag without a second value in the array SHOULD be considered a generic handler for any NIP-19 entity that is not handled by a different tag.
When publishing events, clients MAY include a client tag. Identifying the client that published the note. This tag is a tuple of name, address identifying a handler event and, a relay hint for finding the handler event. This has privacy implications for users, so clients SHOULD allow users to opt-out of using this tag.
{
"kind": 1,
"tags": [
["client", "My Client", "31990:app1-pubkey:<d-identifier>", "wss://relay1"]
]
// other fields...
}
A user A who uses a non-kind:1-centric nostr app could choose to announce/recommend a certain kind-handler application.
When user B sees an unknown event kind, e.g. in a social-media centric nostr client, the client would allow user B to interact with the unknown-kind event (e.g. tapping on it).
The client MIGHT query for the user's and the user's follows handler.
kind:31337-handlerUser A might be a user of Zapstr, a kind:31337-centric client (tracks). Using Zapstr, user A publishes an event recommending Zapstr as a kind:31337-handler.
{
"kind": 31989,
"tags": [
["d", "31337"],
["a", "31990:1743058db7078661b94aaf4286429d97ee5257d14a86d6bfa54cb0482b876fb0:abcd", <relay-url>, "web"]
],
// other fields...
}
kind:31337-handlerUser B might see in their timeline an event referring to a kind:31337 event (e.g. a kind:1 tagging a kind:31337).
User B's client, not knowing how to handle a kind:31337 might display the event using its alt tag (as described in NIP-31). When the user clicks on the event, the application queries for a handler for this kind:
["REQ", <id>, { "kinds": [31989], "#d": ["31337"], "authors": [<user>, <users-contact-list>] }]
User B, who follows User A, sees that kind:31989 event and fetches the a-tagged event for the app and handler information.
User B's client sees the application's kind:31990 which includes the information to redirect the user to the relevant URL with the desired entity replaced in the URL.
kind:31989Alternatively, users might choose to query directly for kind:31990 for an event kind. Clients SHOULD be careful doing this and use spam-prevention mechanisms or querying high-quality restricted relays to avoid directing users to malicious handlers.
["REQ", <id>, { "kinds": [31990], "#k": [<desired-event-kind>], "authors": [...] }]