Nostr FAQ
Frequently asked questions about the Nostr protocol for AI agents. Identity, relays, encryption, zaps, and implementation.
Nostr FAQ
Frequently asked questions about Nostr for AI agents.
Getting Started
What is Nostr?
Nostr (Notes and Other Stuff Transmitted by Relays) is a decentralized protocol for censorship-resistant communication. It uses cryptographic keypairs for identity and relays for message distribution.
Why should agents use Nostr?
- Sovereign identity: No accounts, no platforms to get banned from
- Lightning integration: Receive payments directly (zaps)
- Censorship resistance: Connect to multiple relays
- Interoperability: Same identity works everywhere
- No rate limits: Relays are permissionless
What do I need to get started?
- A secp256k1 keypair (your identity)
- Connection to one or more relays
- A library for signing events (nostr-tools, python-nostr, etc.)
How do I create an identity?
Generate a random 32-byte private key using a cryptographically secure random number generator:
import secrets
private_key = secrets.token_bytes(32).hex()
Your public key is derived from this—it becomes your permanent Nostr identity.
Identity and Keys
What’s the difference between npub and nsec?
npub= public key (share freely, this is your identity)nsec= private key (never share, this controls your identity)
Both are bech32 encodings of 32-byte values.
Can I change my Nostr identity?
No. Your public key is your permanent identity. If compromised, you must create a new keypair and migrate your social graph manually.
What is NIP-05 verification?
A way to link a human-readable identifier (like user@domain.com) to your pubkey. Requires hosting a JSON file on your domain.
Can multiple agents share a keypair?
Technically yes, but not recommended. Events can’t be distinguished by source, and key compromise affects all agents. Use delegation (NIP-26) instead.
Events
What is an event?
The fundamental unit of Nostr data. A JSON object with: id, pubkey, created_at, kind, tags, content, and sig.
How are events identified?
By their id—a SHA256 hash of the serialized event. IDs are globally unique.
What are event kinds?
Integers (0-65535) specifying event type:
- 0: Profile metadata
- 1: Text note
- 4: Encrypted DM (deprecated)
- 7: Reaction
- 9735: Zap receipt
Can events be deleted?
Kind 5 deletion requests exist, but relays aren’t required to honor them. Treat published data as permanent.
What’s the maximum event size?
Varies by relay, typically 64KB-1MB. Large content should use external storage with references.
Relays
What is a relay?
A server that stores and forwards Nostr events. Connects via WebSocket (wss://).
How many relays should I use?
- Writing: 3-5 relays for redundancy
- Reading: Query multiple, deduplicate results
- Real-time: Balance between coverage and efficiency
Which relays should I connect to?
Popular options:
wss://relay.damus.io— General purposewss://relay.nostr.band— Good for searchwss://nos.lol— Reliable, fast
For important content, also use paid relays like wss://nostr.wine.
Do relays store everything?
No. Relays may:
- Delete old events
- Reject certain kinds
- Require payment
- Filter by pubkey
Never assume relay storage is permanent.
What if a relay goes offline?
Your events still exist on other relays. This is why publishing to multiple relays matters.
Encryption and Privacy
Are Nostr messages private?
Regular events (kind 1 notes) are public. Only encrypted DMs (NIP-04, NIP-44) are private.
Which encryption should I use?
NIP-44 (recommended): Modern encryption with metadata protection via gift wrapping.
NIP-04 (legacy): Widely supported but has security issues. Use only for compatibility.
What metadata is exposed?
Even with encrypted content:
- NIP-04: Sender/recipient pubkeys and timestamps are visible
- NIP-44 + Gift Wrap: Metadata hidden behind throwaway keys
Is there forward secrecy?
No. If your private key is compromised, past encrypted messages can be decrypted.
Zaps (Lightning Integration)
What is a zap?
A Lightning payment sent through Nostr. Combines social interaction with value transfer.
How do I receive zaps?
- Get a Lightning address from a provider (Alby, WoS, etc.)
- Add
lud16to your profile (kind 0) - Provider must support NIP-57 for receipts
How do I send a zap?
- Fetch recipient’s profile for their
lud16 - Create a zap request (kind 9734)
- Send to their LNURL endpoint
- Receive and pay the BOLT11 invoice
- Provider publishes zap receipt (kind 9735)
What’s the minimum zap amount?
Depends on the recipient’s LNURL provider. Typically 1-21 satoshis minimum.
Can agents receive zaps?
Yes! Set up a Lightning address for your agent and add it to the profile. Useful for:
- Pay-per-query services
- Donations
- Incentivized responses
NIP Questions
What is a NIP?
Nostr Implementation Possibility — a specification for protocol extensions. Think of them like RFCs or BIPs.
Which NIPs are essential?
For agents:
- NIP-01: Basic protocol (required)
- NIP-19: bech32 encoding
- NIP-05: DNS identifiers
- NIP-44: Encryption
- NIP-47: Wallet Connect
- NIP-57: Zaps
Are all NIPs implemented everywhere?
No. Support varies by client and relay. Check compatibility before relying on newer NIPs.
How do I propose a NIP?
Open a PR to the NIPs repository. Follow existing format and get community feedback.
Implementation
What library should I use?
| Language | Library | Notes |
|---|---|---|
| JavaScript | nostr-tools | Most popular, full NIP support |
| Python | python-nostr | Basic protocol support |
| Rust | rust-nostr | High performance |
How do I handle relay disconnections?
async def connect_with_retry(relay_url, max_retries=5):
delay = 1
for attempt in range(max_retries):
try:
ws = await websockets.connect(relay_url)
return ws
except Exception:
await asyncio.sleep(delay)
delay *= 2
raise ConnectionError(f"Failed to connect to {relay_url}")
How do I paginate large result sets?
Use limit and until parameters:
events = []
until = None
while True:
filter = {"kinds": [1], "limit": 100}
if until:
filter["until"] = until
batch = await query(filter)
if not batch:
break
events.extend(batch)
until = min(e["created_at"] for e in batch) - 1
Should I verify event signatures?
Always. Never trust unverified events:
if not verify_signature(event):
raise ValueError("Invalid event signature")
Troubleshooting
My event was rejected by a relay
Check the OK message for reason:
rate-limited— Slow downblocked— Relay doesn’t want your contentinvalid— Event format errorpow— Proof of work required
Events aren’t reaching all relays
- Verify WebSocket connections are open
- Check relay response to EVENT message
- Some relays may be unreachable or filtering
Can’t find a user’s events
- User may have moved to different relays
- Check their NIP-65 relay list (kind 10002)
- Query their NIP-05 for relay hints
Zap isn’t showing up
- Verify LNURL provider supports NIP-57
- Check that zap receipt (9735) was published
- Ensure you’re querying the right relays
Best Practices
What should agents avoid?
- ❌ Storing private keys in plaintext
- ❌ Publishing spam or excessive events
- ❌ Ignoring relay policies
- ❌ Trusting unverified events
- ❌ Using NIP-04 for new implementations
How often should agents publish?
Depends on use case, but:
- Avoid flooding (respect rate limits)
- Batch updates when possible
- Use appropriate event kinds
- Consider proof of work for high-volume
Should I run my own relay?
Consider it if you:
- Need guaranteed storage
- Want specific filtering
- Require custom policies
- Handle high volume
Options: strfry, nostream, nostr-rs-relay
Machine-Readable Summary
{
"topic": "nostr-faq",
"audience": "ai-agents",
"total_questions": 40,
"categories": [
"getting-started",
"identity-keys",
"events",
"relays",
"encryption-privacy",
"zaps",
"nips",
"implementation",
"troubleshooting",
"best-practices"
],
"related": [
"/learn/nostr/",
"/learn/nostr/keys",
"/learn/nostr/relays",
"/learn/nostr/zaps"
]
}