Appearance
Client-to-Relay Messages
This document describes the message formats that Nostr clients send to relays. These messages are sent over a WebSocket connection established by the client to the relay.
Overview
Clients send JSON arrays to relays through the WebSocket connection. Each message starts with a verb that identifies the type of message being sent. According to NIP-01, there are three primary message types that clients send to relays:
EVENT
- Publishing events to the relayREQ
- Requesting events and subscribing to updatesCLOSE
- Ending a subscriptionCOUNT
- Requesting a count of events instead of the events themselves
Message Format Details
EVENT Message
The EVENT
message is used to publish new events to a relay.
Format:
json
["EVENT", <event JSON object>]
Example:
json
["EVENT", {
"id": "4376c65d2f232afbe9b882a35baa4f6fe8667c4e684749af565f981833ed3eed",
"pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93",
"created_at": 1673557174,
"kind": 1,
"tags": [["e", "3da979448d9ba263864c4d6f14984c423a3838364ec255f03c7904b1ae77f206"], ["p", "bf2376e17ba4ec269d10fcc996a4746b451152be9031fa48e74553dde5526bce"]],
"content": "Responding to a post by someone",
"sig": "908a15e46fb4d8675bab026fc230a0e3542bfade63da02d542fb78b2a8513fcd0092619a2c8c1221e581946e0191f2af505dfdf8657a414dbca329186f009262"
}]
When a client sends an EVENT
message, the relay should respond with an OK
message indicating whether it accepted the event.
REQ Message
The REQ
message is used to request events from a relay and subscribe to new events that match specified filters.
Format:
json
["REQ", <subscription_id>, <filters1>, <filters2>, ...]
Example:
json
["REQ", "my-sub", {"kinds": [1], "authors": ["6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"], "limit": 10}]
Key components of the REQ
message:
<subscription_id>
is an arbitrary, non-empty string (max 64 characters) that identifies this subscription.<filtersX>
are JSON objects that determine what events will be returned in the subscription.
A relay will respond to a REQ
message by sending EVENT
messages for all matching events, followed by an EOSE
(End of Stored Events) message. After that, any new events received by the relay that match the filters will be sent to the client in real-time.
Filter Objects
Filter objects in a REQ
message can include the following attributes:
json
{
"ids": ["<event_id>", ...],
"authors": ["<pubkey>", ...],
"kinds": [<kind_number>, ...],
"#<single-letter>": ["<tag_value>", ...],
"since": <unix_timestamp>,
"until": <unix_timestamp>,
"limit": <max_events>
}
- Multiple conditions within a single filter are combined with AND logic
- Multiple filters in a single
REQ
are combined with OR logic - For detailed filter information, see the filter documentation
CLOSE Message
The CLOSE
message is used to end a subscription.
Format:
json
["CLOSE", <subscription_id>]
Example:
json
["CLOSE", "my-sub"]
Upon receiving a CLOSE
message, the relay should stop sending events for the specified subscription ID.
COUNT Message
The COUNT
message (defined in NIP-45) is used to request a count of events matching certain filters, rather than the events themselves.
Format:
json
["COUNT", <subscription_id>, <filters1>, <filters2>, ...]
Example:
json
["COUNT", "counter-1", {"kinds": [1], "#t": ["bitcoin"], "since": 1673557174}]
The relay responds with a COUNT
message containing the number of events that match the filters.
Client Implementation Considerations
Connection Management
- Clients SHOULD establish a single WebSocket connection to each relay and use it for all subscriptions
- Relays MAY limit the number of connections from specific IPs or clients
Subscription Management
- Use unique subscription IDs for different queries
- To replace an existing subscription, send a new
REQ
with the same subscription ID - When you no longer need a subscription, send a
CLOSE
message to free up relay resources
Error Handling
- Clients should be prepared to handle
NOTICE
messages from relays - Clients should monitor for
CLOSED
messages, which indicate a relay has terminated a subscription - If a relay closes a connection, clients should implement appropriate reconnection strategies
Event Caching
- Clients should consider caching received events to reduce bandwidth usage and improve performance
- When reconnecting to a relay, clients can use the
since
filter parameter with a timestamp of their most recent event