1 Overview
Instant messengers of the 2000s had a status line: "away", "busy", "listening to...". This NIP brings that feature to Nostr. A user publishes a short status event. Clients show the status next to the username on posts and profiles.
A status is an addressable event of kind:30315, as defined in NIP-01. The d tag holds the status type. A relay keeps only the latest event per pubkey, kind, and d value. A new status therefore replaces the old one of the same type automatically.
A status can expire on its own. The event is optionally expiring: add an expiration tag (see NIP-40) and the status goes stale at that timestamp. A music status expires when the track ends. No cleanup event is needed.
Think of each d value as one status slot. The general slot and the music slot live side by side. Updating one slot does not touch the other.
d value is a slot. The relay keeps the latest event per slot. Readers always get the current status.2 The Status Event (kind 30315)
The event named "User Status" uses kind:30315. The content is the status text. The d tag names the status type.
{
"kind": 30315,
"content": <status text, may contain emoji>,
"tags": [
["d", <status type, e.g. "general" or "music">],
["r", <URL, optional>],
["expiration", <unix timestamp, optional>]
]
}
| Tag | Required | Rule |
|---|---|---|
| d | yes | The status type. Selects the addressable slot per NIP-01. |
| r | optional | Links the status to a URL. |
| p | optional | Links the status to a profile (pubkey). |
| e | optional | Links the status to a note (event id). |
| a | optional | Links the status to an addressable event. |
| expiration | optional | Unix timestamp when the status stops being valid. See NIP-40. |
A status MAY include one r, p, e, or a tag. The tag turns the status into a link. Example: a "in a meeting" status can carry an r tag with the meeting URL.
Status types
The d tag value is the status type. This NIP defines two common types:
| Type | Meaning | Expiry |
|---|---|---|
| general | A general status: "Working", "Hiking", "Out of office". | Optional. |
| music | The track the user listens to right now. A live "now playing" stream. | Set to the time when the track stops playing. |
Clients can use any other d value as a custom status type. This NIP does not define those types.
Content rules
- The
contentis the status text. - The
contentMAY include emoji, or NIP-30 custom emoji. - An empty
contentstring clears the status. The client should stop showing it.
Source issues, reported as found. (1) Both JSON examples in the source have a trailing comma after the tags array, so they are not valid JSON as printed. (2) The music example spells the Beastie Boys track as "Intergalatic" instead of "Intergalactic". (3) The source says the event is "optionally expiring" and uses an expiration tag but never cites NIP-40, which defines that tag.
3 Status Lifecycle
A status has three exits. A newer event with the same d value replaces it. Its expiration timestamp passes. Or an event with empty content clears it.
4 Client Behavior
Clients MAY display the status next to the username on posts or on profiles. The status gives live user information at a glance.
To read statuses, subscribe with a filter on kind:30315 and the authors you follow. Ignore statuses whose expiration timestamp is in the past. Ignore statuses with empty content.
The source lists these use cases:
- A calendar app updates your
generalstatus when you are in a meeting. - Nostr Nests updates your
generalstatus with a link to the nest when you join. - A music streaming service updates your
musicstatus while you listen. - A podcast app updates your
musicstatus with a link so others can listen too. - A client reads the system media player and updates the
musicstatus.
Expiry is cooperative. A relay that implements NIP-40 can drop expired statuses, but clients must still check the expiration tag themselves. Do not show a "now playing" line from last week.
5 Worked Example
Alice sets a general status with a link, streams a track as her music status, and later clears the general status. The transcript shows the full session. Orange lines go to the relay. Blue lines come from the relay.
-- Alice sets her general status -- → ["EVENT", {"kind":30315, "pubkey":"a1ce55...", "created_at":1692840000, "content":"Sign up for nostrasia!", "tags":[["d","general"], ["r","https://nostr.world"]], "id":"7d1f04...", "sig":"9b21ac..."}] ← ["OK", "7d1f04...", true, ""] -- Alice's player sets a music status that expires with the track -- → ["EVENT", {"kind":30315, "pubkey":"a1ce55...", "created_at":1692845400, "content":"Intergalatic - Beastie Boys", "tags":[["d","music"], ["r","spotify:search:Intergalatic%20-%20Beastie%20Boys"], ["expiration","1692845589"]], "id":"c04b9e...", "sig":"31d7f0..."}] ← ["OK", "c04b9e...", true, ""] -- Bob's client fetches Alice's statuses -- → ["REQ", "status", {"kinds":[30315], "authors":["a1ce55..."]}] ← ["EVENT", "status", {"kind":30315, "content":"Sign up for nostrasia!", ...}] ← ["EVENT", "status", {"kind":30315, "content":"Intergalatic - Beastie Boys", ...}] ← ["EOSE", "status"] -- Later Alice clears the general slot: empty content -- → ["EVENT", {"kind":30315, "pubkey":"a1ce55...", "created_at":1692850000, "content":"", "tags":[["d","general"]], "id":"e83a11...", "sig":"04c2b8..."}] ← ["OK", "e83a11...", true, ""] -- Bob's client sees the empty content and stops showing the status --
6 Version History
NIP-38 started life two days early as "NIP-315", named after its kind number. Notable changes, newest first:
- 20252025-08Fixed heading levels in the document.
- 20242024-08Renamed "parameterized replaceable event" to "addressable event" across the repository, following the NIP-01 terminology change.
- 20242024-05Moved the content rules (emoji, empty string clears the status) into the Live Statuses section.
- 2023-242023-2024Removed the author list; JSON and header formatting cleanups.
- 20232023-08Added the content description: emoji and NIP-30 custom emoji allowed, empty content clears the status.
- 20232023-08Renamed NIP-315 to NIP-38.
- Origin2023-08-23William Casarin published "NIP-315: User Statuses" with kind 30315.
Original Proposal - Credits
| Author | William Casarin |
| First commit | 2023-08-23 — “NIP-315: User Statuses” |
| Status | draft - optional |
| Source | 38.md on GitHub - full change history |