Skip to main content
Nostr

Nostr

Active

Nostr (Notes and Other Stuff Transmitted by Relays) is a censorship-resistant decentralized protocol for social publishing. Every user has a cryptographic keypair (secp256k1); every note is a JSON event signed by the user's private key. Clients connect to multiple relays (WebSocket servers) to publish and subscribe to events. No central server, no accounts – identity is purely cryptographic.

NostrNIP-01Relaysecp256k1Censorship-resistant2020
Event Kinds

In one line

Nostr (NIPs, community spec) is a decentralized protocol where every event is a JSON object signed with a secp256k1 private key. Clients connect to relays (WebSocket servers) to publish events (kind 1 = short text note) and subscribe with filters (authors, kinds, tags, since/until). No accounts, no federation protocol – identity is just a public key. Client-relay wire protocol is defined in NIP-01: 3 client messages (EVENT, REQ, CLOSE) and 5 relay messages (EVENT, OK, EOSE, CLOSED, NOTICE).

Quick Reference

FieldSizeDescription
Identitysecp256k1 keypairA Nostr identity is just a public/private key pair. Public key is the user ID (npub encoding). Private key signs all events (nsec encoding). No accounts, no servers needed to 'register'.
EventJSON objectEvery piece of content is a signed JSON event: {id, pubkey, created_at, kind, tags, content, sig}. The id is SHA-256 of the serialized fields. sig is Schnorr signature over id using privkey.
KindintegerEvent type. kind 0 = metadata (profile), kind 1 = short text note, kind 3 = contact list, kind 4 = encrypted DM (deprecated), kind 6 = repost, kind 7 = reaction. Range 10000–19999 for replaceable, 20000–29999 for ephemeral.
Relaywss:// WebSocketA server that accepts and serves events. Clients connect to multiple relays for redundancy. Relays may require payment (NIP-42) or invitation. wss:// is standard; ws:// for local testing.
NIP-01 messages3 + 5 message typesClient sends: EVENT (publish), REQ (subscribe with filter), CLOSE (unsubscribe). Relay sends: EVENT (matching event), OK (accepted/rejected), EOSE (end of stored events), CLOSED (subscription terminated), NOTICE (informational).
FiltersJSON subscriptionREQ subscription filter: {ids, authors, kinds, #e (event tags), #p (pubkey tags), since, until, limit}. Multiple filters in one REQ are OR'd. Multiple REQ subscriptions on one connection are independent.
bech32 encodingnpub/nsec/note/naddrNIP-19 bech32-encoded identifiers. npub = public key (for sharing profiles), nsec = private key (keep secret), note = event id, naddr = replaceable event address, nevent = event with relay hint.
ZapsNIP-57Lightning Network Bitcoin micropayments sent as Nostr events. A zap request (kind 9734) is sent to the recipient's Lightning address, and the zap receipt (kind 9735) is published to relays. Enables tipping creators natively.

Key Characteristics

Cryptographic identity

No account required. Generate a keypair offline. Publish anywhere. No server can revoke your identity because identity is a cryptographic key, not a server-granted account.

No guaranteed delivery

Nostr has no delivery guarantees. Publish to more relays for better reach. Relays may drop events, go offline, or reject events. Clients must manage multi-relay publishing themselves.

Bitcoin-native

Nostr was designed alongside the Bitcoin/Lightning ecosystem. Zaps (NIP-57) enable Lightning tips. LNURL-pay and Nostr Wallet Connect (NIP-47) integrate Lightning payments natively.

Relay independence

A user's events exist wherever relays have stored them. Users can migrate to new relays, republish lost events, and cannot be deplatformed unless every relay drops them simultaneously.

Message Format

Request
http
// NIP-01 client messages (WebSocket JSON arrays)

// EVENT: publish a signed event
["EVENT", {
  "id": "sha256-of-serialized-content",
  "pubkey": "hex-public-key",
  "created_at": 1700000000,
  "kind": 1,
  "tags": [
    ["e", "reply-to-event-id", "wss://relay.damus.io"],
    ["p", "mentioned-pubkey"]
  ],
  "content": "Hello Nostr!",
  "sig": "schnorr-signature-over-id"
}]

// REQ: subscribe with filter
["REQ", "sub-id-1", {
  "authors": ["pubkey1", "pubkey2"],
  "kinds": [1, 6],
  "since": 1700000000,
  "limit": 50
}]

// CLOSE: unsubscribe
["CLOSE", "sub-id-1"]
Response
http
// Relay messages

// EVENT: matching event from subscription
["EVENT", "sub-id-1", {
  "id": "abc...",
  "pubkey": "def...",
  "created_at": 1700000001,
  "kind": 1,
  "content": "Reply to your note!",
  "sig": "..."
}]

// OK: publish acknowledgement
["OK", "event-id", true, ""]  // accepted
["OK", "event-id", false, "blocked: content policy violation"]

// EOSE: end of stored events, real-time begins
["EOSE", "sub-id-1"]

// CLOSED: relay terminated subscription
["CLOSED", "sub-id-1", "rate-limited: too many requests"]

// NOTICE: informational message
["NOTICE", "This relay requires NIP-42 authentication"]

Implementations

linuxsince nostr-tools (JavaScript), python-nostr, nostr-rs (Rust), NDK (Nostr Dev Kit). Relay: strfry (C++), nostream (TypeScript), nostr-rs-relay (Rust)available
macossince Damus (macOS native, also iOS). Nostrudel web client. Same libraries as Linux.available
windowssince Nostrudel (web), Iris.to (web), nostr-tools JavaScript library.available
iossince Damus (primary iOS client), Primal, Nostur, Yana.available
androidsince Amethyst (primary Android client), Primal, Yana.available