This document provides detailed descriptions of all standard NIPs from the nostr-protocol/nips repository.
Status: Mandatory for all implementations
The foundational NIP that defines the entire Nostr protocol.
Events are the only object type in Nostr. Structure:
{
"id": "<32-bytes lowercase hex>",
"pubkey": "<32-bytes lowercase hex>",
"created_at": "<unix timestamp>",
"kind": "<integer>",
"tags": [["<key>", "<value>", ...]],
"content": "<string>",
"sig": "<64-bytes hex>"
}
Event ID Calculation:
[0, pubkey, created_at, kind, tags, content]Signature:
All communication happens over WebSocket.
Client Messages:
["EVENT", <event>] - Publish event["REQ", <subscription_id>, <filter>, ...] - Subscribe["CLOSE", <subscription_id>] - UnsubscribeRelay Messages:
["EVENT", <subscription_id>, <event>] - Send event["OK", <event_id>, <accepted>, <message>] - Command result["EOSE", <subscription_id>] - End of stored events["CLOSED", <subscription_id>, <message>] - Forced close["NOTICE", <message>] - Human-readable noticeFilter object fields (all optional):
ids: List of event IDs (prefix match)authors: List of pubkeys (prefix match)kinds: List of event kinds#<single-letter>: Tag queriessince: Unix timestamp (events after)until: Unix timestamp (events before)limit: Maximum events to returnA filter matches if ALL conditions are met. Within arrays, conditions are ORed.
0: Metadata (user profile)1: Text note2: Recommend relay (deprecated)Status: Widely implemented
Defines event kind 3 for user contact lists (following lists).
Format:
{
"kind": 3,
"tags": [
["p", "<pubkey>", "<relay-url>", "<petname>"]
],
"content": "<relay-list-json>"
}
Characteristics:
p tag is a followed userUsage:
Status: Optional
Allows embedding OpenTimestamps proofs in events.
Format:
{
"tags": [
["ots", "<base64-ots-proof>"]
]
}
Used to prove an event existed at a specific time via Bitcoin blockchain timestamps.
Status: Deprecated (use NIP-44)
Event kind 4 for encrypted private messages.
Encryption:
Format:
{
"kind": 4,
"tags": [
["p", "<recipient-pubkey>"]
],
"content": "<encrypted-content>"
}
Security Issues:
Status: Widely implemented
Allows verification of identity via domain names (like email addresses).
Format: name@domain.com
Implementation:
"nip05": "alice@example.com" to metadata (kind 0)/.well-known/nostr.json:{
"names": {
"alice": "<hex-pubkey>"
},
"relays": {
"<hex-pubkey>": ["wss://relay1.com", "wss://relay2.com"]
}
}
Benefits:
Status: Optional
Derives Nostr keys from BIP39 mnemonic phrases.
Derivation Path: m/44'/1237'/0'/0/0
Benefits:
Status: Browser extension standard
Defines browser API for Nostr key management.
API Methods:
window.nostr.getPublicKey(): Promise<pubkey>
window.nostr.signEvent(event): Promise<signedEvent>
window.nostr.getRelays(): Promise<{[url]: {read: boolean, write: boolean}}>
window.nostr.nip04.encrypt(pubkey, plaintext): Promise<ciphertext>
window.nostr.nip04.decrypt(pubkey, ciphertext): Promise<plaintext>
Usage:
Status: Core convention
Defines how to mention users and events in notes.
Format:
p or e tags for mentions#[index]{
"kind": 1,
"tags": [
["p", "<pubkey>", "<relay>"],
["e", "<event-id>", "<relay>"]
],
"content": "Hello #[0], check out #[1]"
}
Clients replace #[0], #[1] with user-friendly displays.
Status: Widely implemented
Event kind 5 requests deletion of events.
Format:
{
"kind": 5,
"tags": [
["e", "<event-id-to-delete>"],
["e", "<another-event-id>"]
],
"content": "Reason for deletion (optional)"
}
Behavior:
Status: Core threading standard
Conventions for e and p tags in threaded conversations.
Markers:
root: The root event of the threadreply: Direct parent being replied tomention: Mentioned but not replied toFormat:
{
"kind": 1,
"tags": [
["e", "<root-event-id>", "<relay>", "root"],
["e", "<parent-event-id>", "<relay>", "reply"],
["e", "<mentioned-event-id>", "<relay>", "mention"],
["p", "<author1-pubkey>"],
["p", "<author2-pubkey>"]
]
}
Best Practices:
Status: Standard
HTTP endpoint for relay metadata.
Implementation:
application/nostr+jsonResponse Example:
{
"name": "Example Relay",
"description": "A Nostr relay",
"pubkey": "<admin-pubkey>",
"contact": "admin@example.com",
"supported_nips": [1, 2, 9, 11, 12, 15, 16, 20, 22],
"software": "git+https://github.com/...",
"version": "1.0.0",
"limitation": {
"max_message_length": 16384,
"max_subscriptions": 20,
"max_filters": 100,
"max_limit": 5000,
"max_subid_length": 100,
"min_prefix": 4,
"max_event_tags": 100,
"max_content_length": 8196,
"min_pow_difficulty": 30,
"auth_required": false,
"payment_required": false
},
"relay_countries": ["US", "CA"],
"language_tags": ["en", "es"],
"tags": ["adult-content", "no-spam"],
"posting_policy": "https://example.com/policy",
"payments_url": "https://example.com/pay",
"fees": {
"admission": [{"amount": 5000000, "unit": "msats"}],
"subscription": [{"amount": 1000000, "unit": "msats", "period": 2592000}],
"publication": []
},
"icon": "https://example.com/icon.png"
}
Usage:
Status: Core functionality
Extends filtering to support any single-letter tag.
Syntax: #<letter>: [<value>, ...]
Examples:
{
"#t": ["bitcoin", "nostr"],
"#p": ["pubkey1", "pubkey2"],
"#e": ["eventid1"]
}
Matches events with specified tag values.
Status: Spam prevention
Requires computational work for event publication.
Implementation:
nonce tag: ["nonce", "<number>", "<target-difficulty>"]Example:
{
"tags": [
["nonce", "12345", "20"]
],
"id": "00000abcd..." // 20+ leading zero bits
}
Difficulty Levels:
Relays can require minimum PoW for acceptance.
Status: Convenience
Adds subject tag for event titles/subjects.
Format:
{
"tags": [
["subject", "My Post Title"]
]
}
Used for long-form content, discussions, emails-style messages.
Status: Core protocol
Relay sends EOSE after sending all stored events matching a subscription.
Format: ["EOSE", <subscription_id>]
Usage:
Status: Event lifecycle
Defines three event categories:
- Immutable - All versions kept - Examples: notes, reactions
- Only latest kept - Same author + kind → replace - Examples: metadata, contacts
- Not stored - Forwarded once - Examples: typing indicators, presence
- Replaced based on d tag
- Same author + kind + d-tag → replace
- Examples: long-form posts, product listings
Status: Social feature
Event kind 6 for reposting/sharing events.
Format:
{
"kind": 6,
"tags": [
["e", "<reposted-event-id>", "<relay>"],
["p", "<original-author-pubkey>"]
],
"content": "" // or reposted event JSON
}
Generic Repost (kind 16):
Status: Widely implemented
Human-readable encodings for Nostr entities.
Formats:
- npub1xyz...
- Safer to share than hex
- nsec1xyz...
- Never share publicly
- note1xyz...
- Links to specific events
- Includes pubkey + relay URLs - Better discovery
- Includes event ID + relay URLs + author - Reliable event fetching
- Includes kind + pubkey + d-tag + relays - For parameterized replaceable events
Usage:
Status: Core protocol
Defines OK message format from relays.
Format: ["OK", <event_id>, <accepted>, <message>]
Examples:
["OK", "abc123...", true, ""]
["OK", "def456...", false, "invalid: signature verification failed"]
["OK", "ghi789...", false, "pow: difficulty too low"]
["OK", "jkl012...", false, "rate-limited: slow down"]
Common Rejection Prefixes:
duplicate: - Event already receivedpow: - Insufficient proof of workblocked: - Pubkey or content blockedrate-limited: - Too many requestsinvalid: - Event validation failederror: - Server errorStatus: Standard linking
Defines nostr: URI scheme for deep linking.
Format:
nostr:npub1...nostr:note1...nostr:nevent1...nostr:nprofile1...nostr:naddr1...Usage:
Status: Relay policy
Relays may reject events with timestamps too far in past/future.
Recommendations:
Status: Blog/article support
Event kind 30023 for long-form content (articles, blogs).
Format:
{
"kind": 30023,
"tags": [
["d", "<unique-identifier>"],
["title", "Article Title"],
["summary", "Brief description"],
["published_at", "<unix-timestamp>"],
["t", "tag1"], ["t", "tag2"],
["image", "https://..."]
],
"content": "Markdown content..."
}
Characteristics:
d tag)Status: Widely implemented
Event kind 7 for reactions to events (likes, emoji reactions).
Format:
{
"kind": 7,
"tags": [
["e", "<reacted-event-id>"],
["p", "<event-author-pubkey>"],
["k", "<reacted-event-kind>"]
],
"content": "+" // or emoji
}
Content Values:
+: Like/upvote-: Dislike (discouraged)Client Display:
Status: Advanced delegation
Allows delegating event signing to another key.
Use Cases:
Implementation:
Status: Convenience
Shortcuts for mentioning entities inline.
Format:
nostr:npub1... → user mentionnostr:note1... → event referencenostr:nevent1... → event with contextClients render as clickable links.
Status: Channel support
Event kinds for public chat channels.
Event Kinds:
40: Create channel41: Set channel metadata42: Create message43: Hide message44: Mute userChannel Creation (kind 40):
{
"kind": 40,
"content": "{\"name\": \"Bitcoin\", \"about\": \"Discussion\", \"picture\": \"url\"}"
}
Channel Message (kind 42):
{
"kind": 42,
"tags": [
["e", "<channel-id>", "<relay>", "root"]
],
"content": "Hello channel!"
}
Status: Core feature
Event kinds 30000-39999 are replaceable by d tag.
Format:
{
"kind": 30000,
"tags": [
["d", "<identifier>"]
]
}
Replacement Rule:
d = ""Coordinate Reference:
<kind>:<pubkey>:<d-value>
Use Cases:
Status: Content moderation
Tags for marking sensitive/NSFW content.
Format:
{
"tags": [
["content-warning", "nudity"],
["content-warning", "violence"]
]
}
Clients can hide/blur until user confirms.
Status: Identity verification
Links Nostr identity to external platforms.
Format (in kind 0 metadata):
{
"kind": 0,
"content": "{\"identities\": [{\"platform\": \"github\", \"username\": \"alice\", \"proof\": \"url\"}]}"
}
Supported Platforms:
Status: Ephemeral content
Tag for auto-expiring events.
Format:
{
"tags": [
["expiration", "<unix-timestamp>"]
]
}
Relays should delete event after expiration time.
Status: Access control
Relays can require client authentication.
Flow:
["AUTH", "<challenge>"]22242 event:{
"kind": 22242,
"tags": [
["relay", "<relay-url>"],
["challenge", "<challenge-string>"]
],
"created_at": <now>
}
["AUTH", <signed-event>]Benefits:
Status: Modern encryption
Improved encryption replacing NIP-04.
Algorithm:
Security Improvements:
Format:
<version-byte><encrypted-payload>
Base64 encode for content field.
Status: Statistics
Request for event counts matching filters.
Client Request:
["COUNT", <subscription_id>, <filters>]
Relay Response:
["COUNT", <subscription_id>, {"count": 123, "approximate": false}]
Usage:
Status: Remote signer protocol
Protocol for remote key management and signing.
Architecture:
Use Cases:
Status: Lightning integration
Protocol for connecting Lightning wallets to Nostr apps.
Commands:
pay_invoiceget_balanceget_infomake_invoicelookup_invoiceEnables in-app Lightning payments.
Status: Optional
Full-text search in filter queries.
Format:
{
"search": "bitcoin nostr"
}
Implementation:
Status: Curation
Event kinds for various list types.
List Kinds:
30000: Categorized people list30001: Categorized bookmarks10000: Mute list10001: Pin listFormat:
{
"kind": 30000,
"tags": [
["d", "my-list"],
["p", "<pubkey>", "<relay>", "<petname>"],
["t", "<category>"]
]
}
Status: Moderation
Event kind 1984 for reporting content.
Format:
{
"kind": 1984,
"tags": [
["e", "<event-id>", "<relay>"],
["p", "<pubkey>"],
["report", "spam"] // or "nudity", "profanity", "illegal", "impersonation"
],
"content": "Additional details"
}
Used by relays and clients for moderation.
Status: Widely implemented
Protocol for Lightning tips with proof.
Flow:
9734)9735)Zap Request (kind 9734):
{
"kind": 9734,
"tags": [
["p", "<recipient-pubkey>"],
["amount", "<millisats>"],
["relays", "relay1", "relay2"],
["e", "<event-id>"] // if zapping event
]
}
Zap Receipt (kind 9735): Published by LNURL provider, proves payment.
Status: Reputation system
Award and display badges (achievements, credentials).
Event Kinds:
30008: Badge definition30009: Profile badges8: Badge awardBadge Definition:
{
"kind": 30008,
"tags": [
["d", "badge-id"],
["name", "Badge Name"],
["description", "What this means"],
["image", "url"],
["thumb", "thumbnail-url"]
]
}
Status: Critical for routing
Event kind 10002 for user's relay preferences.
Format:
{
"kind": 10002,
"tags": [
["r", "wss://relay1.com"],
["r", "wss://relay2.com", "write"],
["r", "wss://relay3.com", "read"]
]
}
Usage:
Best Practice:
Status: Application storage
Event kind 30078 for arbitrary app data.
Format:
{
"kind": 30078,
"tags": [
["d", "<app-name>:<data-key>"]
],
"content": "<encrypted-or-public-data>"
}
Use Cases:
Status: Annotation
Event kind 9802 for highlighting content.
Format:
{
"kind": 9802,
"tags": [
["e", "<event-id>"],
["context", "surrounding text..."],
["a", "<article-coordinate>"]
],
"content": "highlighted portion"
}
Like a highlighter pen for web content.
Status: App discovery
Advertise and discover apps that handle specific event kinds.
Format (kind 31989):
{
"kind": 31989,
"tags": [
["k", "1"], // handles kind 1
["web", "https://app.com/<bech32>"],
["ios", "app-scheme://<bech32>"],
["android", "app-package://<bech32>"]
]
}
Kind 31990: User's preferred handlers
Status: File sharing
Event kind 1063 for file metadata.
Format:
{
"kind": 1063,
"tags": [
["url", "https://..."],
["m", "image/jpeg"], // MIME type
["x", "<sha256-hash>"],
["size", "123456"],
["dim", "1920x1080"],
["magnet", "magnet:..."],
["blurhash", "..."]
],
"content": "Description"
}
Use Cases:
Status: File hosting
HTTP API for file uploads/downloads.
Endpoints:
GET /.well-known/nostr/nip96.json - Server infoPOST /upload - Upload fileDELETE /delete - Delete fileUpload Response:
Returns kind 1063 event data for the file.
Status: API authentication
Use Nostr events for HTTP API auth.
Flow:
27235 event with: - u tag: API URL
- method tag: HTTP method
Authorization: Nostr <base64-event> headerBenefits: