Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sandwichfarm/nostr-watch/llms.txt

Use this file to discover all available pages before exploring further.

NIP-66 defines three event kinds that together describe the relay monitoring lifecycle. Monitors announce themselves with kind 10166, report per-relay status with kind 30166, and record state changes over time with kind 1066. These events are signed by the monitor’s private key, giving consumers cryptographic proof of who observed what and when.
KindNIP-01 typePurposed tag
10166ReplaceableMonitor announcement — declares a monitor’s existence and capabilitiesmonitor pubkey
30166Parameterized replaceableRelay status — current health and metadata for one relayrelay URL
1066RegularRelay status delta — append-only history entrynone

Kind 10166 — Monitor Announcement

A monitor publishes kind 10166 to announce itself on the Nostr network. It declares which checks it performs, how often, and on which networks. This event is replaceable — a monitor publishes one event and updates it when its configuration changes. Only the latest version per monitor pubkey is kept.
{
  "kind": 10166,
  "pubkey": "<monitor-pubkey>",
  "content": "",
  "tags": [
    ["frequency", "3600"],
    ["n", "clearnet"],
    ["c", "open"],
    ["c", "read"],
    ["c", "write"],
    ["c", "ssl"],
    ["c", "dns"],
    ["timeout", "open", "5000"],
    ["timeout", "read", "5000"],
    ["timeout", "write", "5000"]
  ]
}
The content field is always an empty string for kind 10166.

Tags

TagExample valueDescription
frequency3600Check interval in seconds
nclearnetNetwork covered — clearnet, tor, or i2p (one tag per network)
copenCheck type performed — open, read, write, ssl, dns, geo, info (one tag per type)
timeoutopen, 5000Timeout in ms for the named check (multi-value tag)
k30166Event kinds published by this monitor
gu4pruydGeohash of the monitor’s physical location

When to use it

Query kind 10166 events to discover active monitors and understand their coverage. The frequency tag tells you how often to expect fresh data. Compare multiple monitors’ c tag sets to understand which check types are covered.
// Discover all monitors
const monitorFilter = { kinds: [10166] }

// Parse a monitor's capabilities from its event
function parseMonitor(event) {
  const frequency = event.tags.find(t => t[0] === 'frequency')?.[1]
  const networks = event.tags.filter(t => t[0] === 'n').map(t => t[1])
  const checks = event.tags.filter(t => t[0] === 'c').map(t => t[1])
  return { pubkey: event.pubkey, frequency: Number(frequency), networks, checks }
}

Kind 30166 — Relay Status

A monitor publishes kind 30166 to report the current status of a specific relay. One event exists per (relay URL, monitor pubkey) pair — the d tag is the relay URL, making this a parameterized replaceable event. When a monitor publishes a new status check for a relay, it replaces the previous one for that relay/monitor pair. The content field contains the relay’s NIP-11 info document as a JSON string (if the relay supports NIP-11). Always parse and validate this separately — it is self-reported by the relay operator, not verified by the monitor.
{
  "kind": 30166,
  "pubkey": "<monitor-pubkey>",
  "content": "{\"supported_nips\":[1,11,42],\"software\":\"strfry\",\"version\":\"1.0.0\"}",
  "tags": [
    ["d", "wss://relay.damus.io"],
    ["r", "wss://relay.damus.io"],
    ["n", "clearnet"],
    ["R", "!auth"],
    ["R", "!payment"],
    ["R", "!pow"],
    ["rtt-open", "120"],
    ["rtt-read", "85"],
    ["rtt-write", "95"],
    ["N", "1"],
    ["N", "11"],
    ["N", "42"],
    ["s", "strfry"],
    ["l", "draft7", "nip66.draft"]
  ]
}

Tags

TagExample valueDescription
dwss://relay.damus.ioRelay URL — addressable identifier for parameterized replaceability
rwss://relay.damus.ioRelay URL (queryable via #r tag filter)
nclearnetNetwork type: clearnet, tor, or i2p
R!authRelay capability/requirement flag (see R tag convention below)
rtt-open120Round-trip time in ms for WebSocket open check
rtt-read85Round-trip time in ms for read check
rtt-write95Round-trip time in ms for write check
N42Supported NIP number — one tag per NIP
k1Supported event kind — one tag per kind, maximum 21
p<hex-pubkey>Relay operator pubkey (from NIP-11 pubkey field)
sstrfryRelay software name (from NIP-11 software field)
LISO-639-1Label namespace declaration (NIP-32)
len, ISO-639-1Label value in the declared namespace
ldraft7, nip66.draftNIP-66 draft version label

The R tag convention

The R tag encodes relay capability flags. A value without a ! prefix means the flag is active; a value with a ! prefix means it is not active.
ValueMeaning
openRelay accepted a WebSocket connection
readRelay responded to a REQ subscription
writeRelay accepted an EVENT message
sslTLS certificate is valid
authRelay requires NIP-42 authentication
paymentRelay requires payment to use
powRelay requires proof of work
!authRelay does not require authentication
!paymentRelay does not require payment
!powRelay does not require proof of work

When to use it

Kind 30166 is the primary event kind for relay intelligence. Query it filtered by relay URL, network, or supported NIPs to build relay selection logic.
// Get current status for a specific relay from all monitors
const relayFilter = {
  kinds: [30166],
  '#d': ['wss://relay.damus.io']
}

// Get all clearnet relay statuses
const clearnetFilter = {
  kinds: [30166],
  '#n': ['clearnet']
}

// Get open relays not requiring auth or payment
const openRelayFilter = {
  kinds: [30166],
  '#R': ['!auth', '!payment']
}

// Get relays supporting NIP-42
const nip42Filter = {
  kinds: [30166],
  '#N': ['42']
}

// Get relays running strfry
const strfryFilter = {
  kinds: [30166],
  '#s': ['strfry']
}
Tag filters use string values in REQ messages, even for numeric tags. Use '#N': ['42'] (string) to match ["N", "42"], not '#N': [42] (number).

Kind 1066 — Relay Status Delta

Kind 1066 is an append-only log recording relay status changes over time. Unlike kind 30166 (which replaces the previous event for each relay/monitor pair), kind 1066 events accumulate and are used for historical analysis and trend detection. Kind 1066 uses a subset of kind 30166 tags. Only the tags that changed since the last status event are included — it is a diff, not a snapshot.
// Get recent status changes for a relay (last 24 hours)
const deltaFilter = {
  kinds: [1066],
  '#r': ['wss://relay.damus.io'],
  since: Math.floor(Date.now() / 1000) - 86400
}

Tags used in kind 1066

TagDescription
rThe relay URL this delta applies to
RChanged requirement/capability flags
rtt-openChanged open RTT
rtt-readChanged read RTT
rtt-writeChanged write RTT
NChanged NIP support

When to use it

Query kind 1066 events to build historical timelines: when relays went offline, latency trends over time, software version changes, and NIP support changes. Combine with kind 30166 for a complete picture — use 30166 for current state and 1066 for history.

How the kinds relate to each other

Kind 10166

Monitor announces itself. Published once per monitor, updated when configuration changes. Tells you who is watching.

Kind 30166

Relay status snapshot. One event per (relay, monitor) pair, replaced on every check. Tells you the current state.

Kind 1066

State change delta. Append-only, accumulates over time. Tells you what changed and when.
A typical workflow:
  1. Query kind 10166 to discover which monitors are active and how often they check
  2. Query kind 30166 for current relay status, filtered by relay URL, network, or NIP support
  3. Aggregate kind 30166 events across multiple monitors to get consensus values (or use the REST API / CVM which does this for you)
  4. Query kind 1066 to build history charts or detect degradation patterns
The REST API and CVM tools aggregate kind 30166 events from multiple monitors automatically. Use raw NIP-66 queries when you need per-monitor attribution, signature verification, or historical trend data from kind 1066.

Build docs developers (and LLMs) love