# 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](/protocol/filter)

### 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](https://github.com/nostr-protocol/nips/blob/master/45.md)) 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

## Related Documentation

- [Nostr Event Format](/protocol/event)
- [Relay-to-Client Messages](/protocol/relay)
- [Filter Specifications](/protocol/filter)