Buzz runs a NIP-29 relay natively, which means any Nostr client that speaks NIP-29 (relay-based groups) and NIP-42 (authentication) can connect to it directly. You do not need the Buzz desktop or mobile app —Documentation Index
Fetch the complete documentation index at: https://mintlify.com/block/buzz/llms.txt
Use this file to discover all available pages before exploring further.
nak, Chachi, 0xchat, and any other NIP-29 client all work over the standard WebSocket wire protocol.
Connecting to your relay
Point your Nostr client at the relay WebSocket URL:AUTH challenge immediately on connection. Your client must respond with a signed AUTH event before it can send or receive events.
Community domain routing. In a single-relay deployment, the relay URL selects exactly one community — all events are scoped to that community. In a multi-community deployment, each community is served by its own domain or subdomain. The backend derives the community from the HTTP
Host header before handling AUTH, EVENT, REQ, REST, media, git, and search traffic. The Nostr wire format does not grow a tenant tag — your client connects to the right community by connecting to the right URL.NIP-11 relay information
Query the relay’s metadata without a WebSocket connection:Feature compatibility
- Fully supported
- Buzz-only or deferred
These features work with any NIP-29 + NIP-42 compatible client:
| Feature | Kind | Notes |
|---|---|---|
| Group chat | 9 | Requires #h <channel-uuid> tag |
| Reactions | 7 | NIP-25; channel derived from target’s #e — client #h ignored |
| Deletions | 5 | NIP-09; self-authored only; #e required |
| User profiles | 0 | NIP-01 metadata synced to display_name, avatar, about, NIP-05 |
| Group creation | 9007 | Include name tag; optional visibility and channel_type |
| Add user | 9000 | Open: any user (subject to channel_add_policy). Private: owner/admin only |
| Remove user | 9001 | Self-remove allowed (last-owner guard). Others: owner/admin only |
| Edit group metadata | 9002 | name/about: owner/admin. topic/purpose: any member |
| Admin delete event | 9005 | Event author can always delete own; otherwise owner/admin required |
| Group deletion | 9008 | Owner only |
| Leave group | 9022 | Any member; last-owner guard prevents orphaned groups |
| Group metadata | 39000 | Relay-signed; d, name, closed always present |
| Group admins | 39001 | Relay-signed; p tags with owner/admin roles |
| Group members | 39002 | Relay-signed; p tags for all members |
| Membership notifications | 44100/44101 | Added/removed; relay-signed; community-global scope |
| Presence | 20001 | Ephemeral; status string truncated to 128 chars |
| Typing indicators | 20002 | Ephemeral, not stored; via Redis pub/sub |
| NIP-42 authentication | — | Proactive challenge; optional pubkey allowlist |
| NIP-11 relay info | — | GET / with Accept: application/nostr+json |
| NIP-50 search | — | One-shot REQs with "search":"query" → relevance-sorted results → EOSE |
| NIP-10 threads | — | Replies with ["e","<root>","","reply"] create thread_metadata atomically |
| NIP-17 DMs (gift wrap) | 1059 | Ephemeral signing keys accepted; community-globally scoped; delivered via #p filter |
| Blossom media | — | PUT /media/upload (BUD-02), GET /media/{sha256}.{ext} (BUD-01) |
| Join request | 9021 | Open channels only; adds member, emits system message + discovery events |
Sending messages with nak
nak is a CLI tool for sending and subscribing to Nostr events. It’s the fastest way to verify that your relay connection works without a full client.
Pubkey allowlist
WhenBUZZ_PUBKEY_ALLOWLIST=true, NIP-42 connections that authenticate with only a pubkey (no API token) are checked against the pubkey_allowlist table. This lets you open the relay to specific external Nostr identities without granting full access.
Fail-closed. If the database lookup fails, the connection is denied. Users with valid API tokens bypass the allowlist entirely. The auth failure message is a generic
auth-required: verification failed — no allowlist-specific detail is leaked.Group discovery
The relay emits NIP-29 group state events when channels are created, updated, or membership changes. Discovery events are stored channel-scoped, so access control applies — private channel member lists are only visible to members.| Kind | Description | Always-present tags |
|---|---|---|
| 39000 | Group metadata | d=<uuid>, name, closed; about if description non-empty; private if applicable; hidden for DM channels |
| 39001 | Admin list | d=<uuid>, p tags with owner/admin role labels |
| 39002 | Member list | d=<uuid>, p tags for all members |
Live subscriptions don’t receive discovery events. Channel-scoped storage means global subscriptions (
{kinds:[39000]}) won’t receive these via fan-out. Discover groups via historical REQ queries instead. Live push for open-channel discovery is a future enhancement.Membership notifications
The relay emits relay-signed notifications when members are added or removed. These are stored community-globally so agents and clients can subscribe without knowing channel UUIDs in advance.| Kind | Meaning | Scope |
|---|---|---|
| 44100 | Member added (p = target pubkey, h = channel UUID) | Community-global |
| 44101 | Member removed (p = target pubkey, h = channel UUID) | Community-global |
Global REQs that can match p-gated kinds (44100, 44101, 1059) must include a
#p filter where all values match your authenticated pubkey. The relay rejects subscriptions that omit #p or include other pubkeys, preventing eavesdropping on others’ membership changes and DMs. Error: restricted: p-gated events require #p matching your pubkey.Known compatible clients
| Client | Platform | Notes |
|---|---|---|
| nak | CLI | Verified — kind:9, NIP-50 search, NIP-10 threads, group discovery |
| BuzzTestClient | Rust (repo) | Automated E2E — full NIP-29 flow including discovery, reactions, deletions |
| Chachi | Web/Mobile | NDK-based, NIP-29 native — expected to work (not verified in-repo) |
| 0xchat | Mobile | NIP-29 native — expected to work (not verified in-repo) |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
auth-required: verification failed | Pubkey not in allowlist, or NIP-42 auth failed | Add pubkey to pubkey_allowlist; verify NIP-42 challenge/response |
invalid: channel-scoped events must include an h tag | kind:9 sent without #h tag | Include --tag "h=<channel-uuid>" |
invalid: reaction target event not found | Reaction references an unknown event | Ensure the target event exists in the relay before reacting |
| No discovery events in live subscription | Channel is private, or channel-scoped storage blocks global fan-out | Join the channel first; use historical REQ for discovery |
Subscription rejected with restricted: p-gated events... | Global REQ for kind:44100/44101/1059 missing #p filter | Add --tag "p=<your-hex-pubkey>" to the subscription |