1 Overview
A client needs to know things about a relay before it trusts it. Does the relay accept large events? Does it require payment? Which NIPs does it support? This NIP answers those questions.
A relay may publish a relay information document. This is a JSON object that describes the relay. Clients fetch it with a plain HTTP request, at the exact same URI they use for the relay's WebSocket connection.
The document is optional field by field. A relay fills in only what it wants to share. A client must ignore any field it does not recognize, so the format can grow without breaking old clients.
Think of this document as a relay's box art and spec sheet. Read it before you connect, so your client can set expectations for message size, payment, and authentication ahead of time.
2 Fetching the Document
A relay exposes one WebSocket URI, as defined in NIP-01. The information document lives at that same URI. A client asks for it with an ordinary HTTP or HTTPS request, not a WebSocket upgrade.
The client sets one required header:
| Header | Value | Purpose |
|---|---|---|
| Accept | application/nostr+json | Tells the relay this is a request for the information document, not a WebSocket upgrade. |
When a relay receives a matching request, it should return the JSON document below.
{
"name": <string identifying the relay>
"description": <string with detailed information>
"banner": <link to a banner image, .jpg or .png>
"icon": <link to a square icon image>
"pubkey": <administrative contact pubkey>
"self": <relay's own pubkey>
"contact": <administrative alternate contact>
"supported_nips": <list of NIP numbers supported by the relay>
"software": <string identifying relay software, a URL>
"version": <string version identifier>
"terms_of_service": <link to a terms of service document>
}
Any field may be omitted. A client must ignore any field in the response it does not understand. This keeps old clients working when new fields are added later.
A relay must accept CORS requests. It must send the Access-Control-Allow-Origin, Access-Control-Allow-Headers, and Access-Control-Allow-Methods headers. Without these, a web-based client cannot fetch the document from a browser.
3 Top-Level Fields
Ten fields describe the relay itself, its operator, and its software. All are optional strings, URLs, or a pubkey, unless noted otherwise.
| Field | Type | Rule |
|---|---|---|
| name | string | Short relay name for client UI. Keep it under 30 characters, or a client may truncate it. |
| description | string | Plain-text detail about the relay. Use no markup and no line-wrap formatting. Separate paragraphs with a blank line. No length limit. |
| banner | URL | Link to a banner image, in .jpg or .png format. Shows the relay's brand to non-technical users. |
| icon | URL | Link to a compact icon image. Used in tight UI spaces, such as a relay-list view. A square image is recommended. |
| pubkey | hex pubkey, 64 chars | Administrative contact. A client may send this pubkey an encrypted direct message (NIP-17) to report abuse, file a bug, or ask for help. The operator has no obligation to reply. |
| self | hex pubkey, 64 chars | The relay's own identity, kept separate from its administrator. The relay may respond using events published under this key. |
| contact | string | Alternate contact, for the same purpose as pubkey. Should be a URI, such as a mailto: or https: link. A Nostr DM to pubkey is the preferred method. |
| supported_nips | array of integers | NIP numbers the relay implements, for example [1, 9, 11]. Do not advertise NIPs that are client-side only. Clients may ignore this field. |
| software | URL | Link to the relay software's project homepage. |
| version | string | Software version or commit identifier. The format is defined by the relay implementation. |
| terms_of_service | URL | Link to a terms-of-service document. |
pubkey vs. self vs. contact
These three fields look similar but answer different questions. pubkey identifies a human administrator to message. self identifies the relay software acting as its own Nostr identity. contact is a fallback address, such as an email link, for when a Nostr DM is not practical.
4 Server Limitations
The limitation object lists practical limits the relay enforces. A client should expect a request that exceeds these limits to be rejected or to fail immediately.
| Field | Type | Rule |
|---|---|---|
| max_message_length | integer | Max bytes of incoming JSON the relay will decode and act on. Measured on the UTF-8 serialized string, from [ to ]. This is also the WebSocket frame size limit, and it caps the maximum event size. |
| max_subscriptions | integer | Max number of active subscriptions on one connection. An authenticated client with a paid relationship to the relay may get a higher limit. |
| max_limit | integer | The relay clamps every filter's limit value to this number, usually silently. Narrow the filter's time range to check for more results beyond it. |
| max_subid_length | integer | Max length of a subscription ID string. |
| max_event_tags | integer | Max number of elements in an event's tags array. |
| max_content_length | integer | Max Unicode characters in an event's content field. After JSON encoding the byte count may be larger, and max_message_length still applies. |
| min_pow_difficulty | integer | Minimum proof-of-work difficulty (NIP-13) required on new events. The relay rejects events below this difficulty. |
| auth_required | boolean | The relay requires NIP-42 authentication before a new connection may do anything else. Even when false, specific actions may still require it. |
| payment_required | boolean | The relay requires payment before a new connection may perform any action. |
| restricted_writes | boolean | The relay requires some condition before it accepts events — for example a pubkey allow-list, or a specific kind. Set this only when clients are expected to know the policy in advance. Ordinary anti-spam heuristics do not qualify. |
| created_at_lower_limit | integer | Lower bound accepted for an event's created_at timestamp. |
| created_at_upper_limit | integer | Upper bound accepted for an event's created_at timestamp. |
| default_limit | integer | Number of events the relay returns for a filter sent without a limit attribute. |
Earlier drafts of this NIP also defined retention, relay_countries, language_tags, a content-classification tags field, and posting_policy. A 2026-02-14 revision, titled in the source history "partially remove bloat that no one cares about," dropped all five from the specification. The current 11.md does not define them, so this manual does not document them as active fields. See §7 Version History.
5 Pay-to-Relay
A relay that requires payment may publish its fee schedule so clients can display it.
| Field | Type | Rule |
|---|---|---|
| payments_url | URL | Page where a user can pay the relay. |
| fees.admission | array of {amount, unit} | One-time cost to join the relay. |
| fees.subscription | array of {amount, unit, period} | Recurring cost. period is the billing interval, in seconds. |
| fees.publication | array of {kinds, amount, unit} | Cost to publish specific event kinds. kinds lists the kind numbers the fee applies to. |
{
"payments_url": "https://relay.example.com/payments",
"fees": {
"admission": [{ "amount": 1000000, "unit": "msats" }],
"subscription": [{ "amount": 5000000, "unit": "msats", "period": 2592000 }],
"publication": [{ "kinds": [4], "amount": 100, "unit": "msats" }]
}
}
6 Worked Example
The transcript below shows a full round trip: the HTTP request with the required header, and the JSON response. Orange lines go to the relay. Blue lines come from the relay.
-- Client requests the information document -- → GET / HTTP/1.1 → Host: relay.example.com → Accept: application/nostr+json -- Relay responds -- ← HTTP/1.1 200 OK ← Content-Type: application/nostr+json ← Access-Control-Allow-Origin: * ← Access-Control-Allow-Headers: * ← Access-Control-Allow-Methods: GET ← ← { "name": "wine relay", "description": "A paid nostr relay for wine enthusiasts and everyone else.", "pubkey": "4918eb332a41b71ba9a74b1dc64276cfff592e55107b93baae38af3520e5597", "contact": "wino@relay.example.com", "supported_nips": [1, 2, 4, 9, 11, 40, 42, 50, 70, 77], "software": "https://git.example.com/relay-software", "version": "0.3.3", "terms_of_service": "https://relay.example.com/terms", "limitation": { "max_message_length": 524288, "max_subscriptions": 50, "max_limit": 1000, "max_subid_length": 71, "max_event_tags": 4000, "auth_required": false, "payment_required": true, "restricted_writes": true, "created_at_lower_limit": 94608000, "created_at_upper_limit": 300 }, "payments_url": "https://relay.example.com/invoices", "fees": { "admission": [{ "amount": 18888000, "unit": "msats" }] } }
A relay with a smaller feature set may return far fewer fields. This response is still valid:
{
"name": "a small free relay",
"pubkey": "52b4a076bcbbbdc3a1aefa3735816cf74993b1b8db202b01c883c58be7fad8b",
"software": "NFDB",
"supported_nips": [1, 2, 9, 11, 40],
"version": "1.0.0",
"limitation": { "payment_required": false, "auth_required": false }
}
7 Version History
Notable changes to NIP-11, newest first:
- 20262026-06-13Reformatted every code fence in the document from
jsonctoyaml, repo-wide. - 20262026-02-14Removed
retention,relay_countries,language_tags, the content-classificationtagsfield, andposting_policyas unused "bloat." - 20252025-11-17Added the
selffield, letting a relay maintain an identity independent from its administrator. - 20252025-04-21Added
terms_of_service, alongside a privacy-policy field later removed in the 2026-02-14 cleanup. - 20252025-04-13Removed an older max-filters mechanism; added
max_limitanddefault_limit, and refreshed the worked examples. - 20242024-11-04Added the
bannerfield, and renamed the earlierimagefield toicon. - 20232023-11-18Added
restricted_writestolimitation, and clarified it excludes ordinary anti-spam heuristics. - 20232023-08-20Removed a
min_prefixmention after prefix search was dropped from NIP-01; addedcreated_atlower/upper limits tolimitation. - 20232023-03-18nostr.wine proposed the extensions that became
limitationandfees: server limits and a pay-to-relay fee schedule. - 20222022-11-23Made CORS support mandatory: relays must answer CORS preflight requests.
- Origin2022-05-01fiatjaf published the first version in the newly migrated
nostr-protocol/nipsrepository.
Original Proposal - Credits
| Author | fiatjaf |
| First commit | 2022-05-01 — “migrate nips from main nostr repo.” |
| Status | draft optional — a relay may implement it; nothing in NIP-01 requires it |
| Source | 11.md on GitHub - full change history |
8 See Also
- NIP-01 — defines the WebSocket URI this document is fetched from, and the base event/filter protocol it describes.
- NIP-13 — proof of work; source of the difficulty number in
min_pow_difficulty. - NIP-17 — private direct messages; how a client reaches the relay operator at its
pubkeyfield. - NIP-42 — client authentication; what
auth_requiredis asking for. - NIP-65 — relay list metadata; how a user tells others which relays to use, a separate concern from what one relay reports about itself.
- NIP-86 — relay management API; a read/write control channel, compared to this read-only information document.