# Nostr Kind Ranges and Meanings in Buzz: Complete Technical Reference

> Explore Nostr kind ranges and meanings in Buzz. Understand how these ranges define storage, replacement, and access control with our technical reference.

- Repository: [Block Open Source/buzz](https://github.com/block/buzz)
- Tags: technical-reference
- Published: 2026-08-27

---

**Buzz organizes Nostr events into distinct numeric kind ranges that determine storage semantics, replacement rules, and access control, with all constants and validation logic centralized in [`crates/buzz-core/src/kind.rs`](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs).**

The [block/buzz](https://github.com/block/buzz) repository implements a sophisticated event classification system that extends standard Nostr protocol specifications. Every kind number falls into a specific semantic range that dictates whether the event is **immutable**, **replaceable**, **ephemeral**, or **command-based**, directly impacting how the relay stores, routes, and secures each event.

## Standard NIP Protocol Ranges

### Standard NIP Kinds (0–3, 5, 7, 41)

These core protocol events follow NIP-01 and related specifications. In [`crates/buzz-core/src/kind.rs`](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs), they are defined as immutable baseline types:

- **`KIND_PROFILE` (0)** – Metadata events defined at [line 9](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L9)
- **`KIND_TEXT` (1)** – Short text notes at [line 11](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L11)
- **`KIND_CONTACT` (3)** – Contact lists at [line 13](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L13)

These events are either immutable or follow standard NIP replacement rules.

### Replaceable Range (10,000–19,999)

Events in this range represent **user-owned global state** keyed by `(pubkey, kind)`. When a new event arrives with the same key, it completely replaces the previous version.

Key constants include:
- **`KIND_MUTE_LIST` (10000)** at [line 15](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L15)
- **`KIND_PIN_LIST`, `KIND_RELAY_LIST`, `KIND_BOOKMARK_LIST`** – All following the `KIND_…_LIST` naming convention

These are ideal for lists and settings that should persist as single, updatable records per user.

### Parameterized Replaceable Range (30,000–39,999)

This range uses a composite key of `(pubkey, kind, d_tag)`, allowing multiple replaceable streams per user. The most recent `created_at` timestamp wins for each unique `d_tag`.

The boundaries are defined by `PARAM_REPLACEABLE_KIND_MIN` and `MAX` at [lines 52-54](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L52-L54). Buzz utilizes this extensively for:
- **`KIND_PERSONA` (30175)** at [line 96](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L96)
- **`KIND_TEAM` (30176)** at [line 76](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L76)
- **Push leases (`KIND_PUSH_LEASE` = 30350)** at [line 108](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L108) – Within the sub-range 30378–30500 for author-only encrypted state

## Ephemeral and Real-Time Ranges

### Ephemeral Range (20,000–29,999)

Events in this category **never persist to the Postgres database**. They flow exclusively through Redis pub/sub for real-time scenarios like presence updates and typing indicators.

The boundaries are declared at [lines 56-58](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L56-L58) as `EPHEMERAL_KIND_MIN` and `MAX`. Validation uses the `is_ephemeral` helper function to ensure these events are only forwarded, never stored.

## Buzz-Specific Domain Extensions

### Direct Message Lifecycle (41,000–41,999)

Reserved for DM protocol events including conversation creation and membership management:
- **`KIND_DM_OPEN` (41010)** at [line 106](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L106)
- Add member, hide, and canonical DM creation events

### Agent Job Protocol (43,000–43,999)

Job-control events for automated agents follow a request-response lifecycle:
- **`KIND_JOB_REQUEST` (43001)** at [line 116](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L116)
- `JOB_ACCEPTED`, `JOB_PROGRESS`, `JOB_RESULT`, `JOB_CANCEL`, and `JOB_ERROR`

### Workflow Engine (46,000–46,999)

Workflow execution events support complex automation pipelines:
- **`KIND_WORKFLOW_TRIGGER` (46020)** at [line 158](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L158)
- Step start, completed, failed, approvals, and cancellations

### Git and Repository Management (30,617–30,623)

Supporting NIP-34 Git functionality:
- **`KIND_GIT_REPO_ANNOUNCEMENT` (30617)** at [line 204](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L204)
- Repository state, patches, pull requests, issues, and status events

### Forum and Social Features (45,001–45,003)

Community discussion primitives:
- **`KIND_FORUM_POST` (45001)** at [line 216](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L216)
- Forum votes and comments

### Media and Audit Systems (48,001–48,999 and 49,000–49,999)

Internal diagnostics and upload tracking:
- **`KIND_MEDIA_UPLOAD` (49001)** at [line 200](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L200) – Internal audit entries not visible to clients
- **`KIND_AUDIT_ENTRY` (48001)** at [line 208](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L208) – System diagnostics

## Administration and Moderation Ranges

### Relay Administration Commands (9,030–9,033)

NIP-43 admin commands for workspace and member management. These are identified by the `is_relay_admin_kind` helper at [lines 94-102](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L94-L102) and processed directly by the relay handlers in [`crates/buzz-relay/src/handlers/relay_admin.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/handlers/relay_admin.rs).

### Community Moderation (9,040–9,044)

Direct moderation actions processed as commands rather than stored events:
- Ban, unban, timeout, untimeout, and resolve report
- Validated via `is_moderation_command_kind` at [lines 76-84](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L76-L84)

### Identity Archival (9,035–9,036)

NIP-IA requests for archiving or unarchiving identities, handled by `is_identity_archive_request_kind` at [lines 106-112](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L106-L112).

## Group and Synthetic Ranges

### NIP-29 Group State (39,000–39,003)

Addressable group metadata following NIP-29:
- **`KIND_NIP29_GROUP_METADATA` (39000)** through group admins, members, and roles at [lines 120-128](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L120-L128)

### Channel Window Overlays (39,005–39,006)

Synthetic events injected by bridge services:
- **`KIND_THREAD_SUMMARY` (39005)** at [line 134](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L134)
- Window bounds for UI threading

## Range Validation Helpers

The [`kind.rs`](https://github.com/block/buzz/blob/main/kind.rs) module exports predicate functions that enforce range semantics throughout the codebase:

- **`is_ephemeral`** – Checks against `EPHEMERAL_KIND_MIN`/`MAX` (lines 56-58)
- **`is_replaceable`** – Validates 10,000–19,999 range
- **`is_parameterized_replaceable`** – Validates 30,000–39,999 range
- **`is_moderation_command_kind`** – 9040–9044 range check
- **`is_relay_admin_kind`** – 9030–9033 range check
- **`is_identity_archive_request_kind`** – 9035–9036 range check

These helpers ensure compile-time and runtime consistency for persistence rules and access control gates.

## Practical Implementation Examples

Below are Rust snippets demonstrating how to construct events using the constant definitions from `buzz-core`:

```rust
use buzz_core::kind::*;
use nostr::{EventBuilder, Keys, Kind, Tag};

// Standard profile event (Kind 0)
let keys = Keys::generate();
let profile = EventBuilder::new(Kind::Custom(KIND_PROFILE as u16), r#"{"name":"Alice"}"#)
    .sign_with_keys(&keys)
    .unwrap();

// Replaceable mute list (Kind 10000)
let mute_list = EventBuilder::new(Kind::Custom(KIND_MUTE_LIST as u16), "[]")
    .tags(vec![Tag::parse(["d", "global"]).unwrap()])
    .sign_with_keys(&keys)
    .unwrap();

// Parameterized replaceable persona (Kind 30175)
let persona = EventBuilder::new(Kind::Custom(KIND_PERSONA as u16), r#"{"display_name":"Work Identity"}"#)
    .tags(vec![
        Tag::parse(["d", "professional"]).unwrap(),
        Tag::parse(["shared", "true"]).unwrap(),
    ])
    .sign_with_keys(&keys)
    .unwrap();

// Ephemeral typing indicator (within 20000-29999)
let typing = EventBuilder::new(Kind::Custom(KIND_TYPING_INDICATOR as u16), "")
    .tags(vec![Tag::parse(["h", "channel-uuid"]).unwrap()])
    .sign_with_keys(&keys)
    .unwrap(); // Relay forwards via Redis only, no database storage

// Workflow trigger (Kind 46020)
let trigger = EventBuilder::new(Kind::Custom(KIND_WORKFLOW_TRIGGER as u16), r#"{"workflow_id":"deploy"}"#)
    .sign_with_keys(&keys)
    .unwrap();

```

## Summary

Buzz extends the Nostr protocol with a rigorous kind range taxonomy defined in **[`crates/buzz-core/src/kind.rs`](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs)**:

- **0–41**: Standard immutable and basic replaceable events
- **10,000–19,999**: User global state (replaceable by pubkey+kind)
- **20,000–29,999**: Ephemeral events (Redis-only, no persistence)
- **30,000–39,999**: Parameterized replaceable (versioned by d-tag)
- **41,000–41,999**: Direct message lifecycle
- **43,000–43,999**: Agent job protocol
- **46,000–46,999**: Workflow engine events
- **9,030–9,044**: Relay administration and moderation commands
- **39,000–39,006**: Group state and synthetic overlays
- **45,001–45,003**: Forum posts and voting
- **48,001–49,999**: Audit and media tracking

Helper functions like `is_ephemeral` and `is_parameterized_replaceable` provide runtime guards to enforce these semantics across the relay, client, and agent implementations.

## Frequently Asked Questions

### What is the difference between replaceable and parameterized replaceable kinds in Buzz?

**Replaceable kinds (10,000–19,999)** use `(pubkey, kind)` as a composite key, allowing only one event per kind per user. **Parameterized replaceable kinds (30,000–39,999)** add a `d_tag` to the key, enabling multiple parallel streams per user where each unique `d_tag` value maintains its own replacement history. This allows Buzz to support multiple personas, teams, or workflow states per identity.

### Why do ephemeral kinds (20,000–29,999) never touch the database?

Ephemeral kinds are designed for **real-time, transient data** like typing indicators or presence updates. According to the implementation at [lines 56-58](https://github.com/block/buzz/blob/main/crates/buzz-core/src/kind.rs#L56-L58) of [`kind.rs`](https://github.com/block/buzz/blob/main/kind.rs), these events bypass Postgres entirely and flow only through Redis pub/sub. This prevents database bloat from temporary state while maintaining low-latency broadcasting to connected clients.

### How does Buzz validate that an event is a moderation command versus a regular event?

Moderation commands in the 9,040–9,044 range are identified by the **`is_moderation_command_kind`** helper function (lines 76-84). Unlike standard events that are stored in the database, these are processed as **immediate commands** by the relay handlers in [`crates/buzz-auth/src/handlers/moderation_commands.rs`](https://github.com/block/buzz/blob/main/crates/buzz-auth/src/handlers/moderation_commands.rs), executing actions like ban or timeout without creating a persistent event record accessible to clients.

### Which kind range should developers use for custom agent automation?

For autonomous agent workflows, use the **Agent Job Protocol range (43,000–43,999)** for lifecycle events (request, progress, result), and the **Workflow Engine range (46,000–46,999)** for orchestration events. These ranges are specifically reserved in [`kind.rs`](https://github.com/block/buzz/blob/main/kind.rs) (lines 116 and 158) to ensure agents can communicate job state and trigger complex multi-step workflows without colliding with user content or standard NIP events.