Skip to Content
DevelopersLive event structure (kind 30311)

Live event structure (kind 30311)

When a stream goes live, a kind 30311 event (NIP-53 ) is published to Nostr.

  • When using Shosho Server, this event is signed and published by the server on behalf of the user.
  • When using a generic RTMP server, the user must publish it themselves. An agent may publish on the user’s behalf.

Anti-patterns

  • Do not publish a 30311 manually if streaming to a Nostr streaming server. The server publishes the event for you. Manual publication results in duplicate live events on the network.
  • Do not forget the host p tag. Shosho links the stream to the user’s profile via a p tag with role host. Without it, the stream will not appear on the user’s profile.
  • Do not forget the d tag. Nostr requires a d tag on all addressable events (kinds 30000-39999). Without it, you can’t reference or update the event later.
  • Do not forget to set status to live when the stream starts. Without it, Shosho and other clients won’t display the stream as active.
  • CRITICAL: Always update status to ended when the stream ends. If you don’t, the stream will appear perpetually live for up to 12 hours until it ages out (see Liveness below). Always publish the ending event to the same relays.

Tag structure

NIP-53 lists d as the only strictly required tag — all others are optional from the protocol’s perspective. The “Shosho needs” column below reflects what Shosho expects to display the stream properly.

TagValueNIP-53Shosho needs
dUnique stream identifierRequiredRequired
titleStream titleOptionalRequired
summaryDescriptionOptionalOptional
imageThumbnail/cover URL (via nostr.build)OptionalOptional
streamingHLS playback URL (.m3u8)OptionalRequired
recordingURL of the edited recording, set after the stream endsOptionalOptional
statuslive, ended, or plannedOptionalRequired
startsUnix timestampOptionalOptional
endsUnix timestampOptionalOptional
pParticipant: ['p', '<hex_pubkey>', '<relay>', '<role>'] — Shosho requires one with role hostOptionalRequired (host)
tHashtagOptionalOptional
relaysSuggested relay URLs for chatOptionalOptional
current_participantsCurrent viewer countOptionalOptional
total_participantsTotal participants seenOptionalOptional
pinnedEvent id of a pinned chat messageOptionalOptional

Host identification

NIP-53 defines p tags as ['p', '<pubkey>', '<relay-url>', '<role>', '<proof>'] where the role is a displayable string (NIP-53 examples use Host, Speaker, Participant). Shosho writes the role in lowercase (host) and reads it case-insensitively, so both host and Host are accepted on read.

In practice you’ll publish:

['p', '<host_hex_pubkey>', '', 'host']

The relay URL slot may be empty. The host tag must be present for Shosho to associate the stream with the host’s profile.

Signer and publication

  • Shosho Server — signs with its own key, includes the user’s pubkey as the host p tag, publishes to the server’s relays.
  • Generic RTMP server — you sign and publish using the user’s key.

Publishing a live event manually (generic server)

nak event -k 30311 \ --content "" \ -t d=my-stream-2024 \ -t title="My Live Stream" \ -t summary="Streaming live!" \ -t streaming=https://your-server.com/stream.m3u8 \ -t status=live \ -t starts=$(date +%s) \ -t 'p=<your_hex_pubkey>;;host' \ --sec <nsec1...> \ wss://relay.damus.io wss://relay.primal.net

Viewing on Shosho

Build the stream’s naddr:

nak encode naddr -k 30311 -d <d-tag> -a <author_hex_pubkey> -r wss://relay.damus.io

View at https://shosho.live/live/<naddr>.

Liveness

Shosho considers a stream live when all of the following are true:

  • status is live
  • the event’s created_at is within the last 12 hours
  • either no ends tag is set, or the ends timestamp is in the future

NIP-53 suggests clients MAY treat status=live events without an update for 1 hour as ended. Shosho’s window is 12 hours — longer than the NIP recommendation, so a stream that goes silent will appear stuck-live longer on Shosho than on a strict NIP-compliant client. This is why the “always publish status: ended” anti-pattern is critical.

Last updated on