Skip to content

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:

  1. EVENT - Publishing events to the relay
  2. REQ - Requesting events and subscribing to updates
  3. CLOSE - Ending a subscription
  4. COUNT - 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