1NIP-672======34EOSE Completeness Hint5----------------------67`draft` `optional`89This NIP extends the `EOSE` message defined in [NIP-01](01.md) with an optional third element that signals the client that the relay has sent every stored event matching the subscription's filters.1011## Motivation1213`EOSE` as defined in NIP-01 signals the boundary between stored and real-time events. It does not tell the client whether there are more stored events the relay chose not to send. Relays commonly enforce an internal cap (e.g. 500 events per filter) that is independent of the client's `limit`. Clients today guess completeness by comparing the number of events received to the `limit` they requested:1415- If fewer than `limit` events arrive, assume completion.16- Otherwise, issue another `REQ` with `until` set to the oldest received event's `created_at`, and repeat.1718This heuristic has two well-known problems:19201. When the relay's internal cap is lower than the client's `limit` (e.g. cap 300, client asks for 500), the client receives 300 events and incorrectly concludes the result is complete, silently missing data.212. When the total number of matching events happens to equal the relay's cap, the client cannot tell and must issue an additional `REQ` just to observe zero results. A relay that caps at 300 events will always be queried at least twice for any subscription that exhausts the cap.2223A single extra field on `EOSE` removes this ambiguity.2425## Specification2627A relay that implements this NIP MAY append a third element to the `EOSE` message: an array of hint strings.2829```30["EOSE", <subscription_id>, [<hint>, ...]]31```3233Currently three hint values are defined:3435- `"finish"`: the relay has sent every stored event matching the subscription's filters. The client SHOULD NOT paginate this subscription further.36- `"more"`: the relay holds more matching stored events than it has sent. The client SHOULD paginate to retrieve them. A relay MAY send this hint, but is not required to, since detecting whether more events exist is not cheap on every storage backend.37- `"auth"`: the relay may have more stored events matching the subscription's filters if the user performs `AUTH` ([NIP-42](42.md)). Relays MUST ensure an `AUTH` message (containing a challenge) is sent _before_ the `EOSE` containing an `"auth"` hint.3839The array MAY carry multiple hints simultaneously, and MAY be empty. Clients MUST ignore unknown hint values without error.4041Their presence is definitive; their absence is not. When a relay omits the third element, or sends neither `"finish"` nor `"more"`, the client SHOULD paginate using `until = oldest received event's created_at` as usual.4243Clients that do not implement this NIP will ignore the extra element, as JSON arrays with trailing elements are accepted by conforming parsers and existing implementations index `EOSE` by position. Relays that do not implement this NIP continue to send `EOSE` with two elements and clients fall back to the legacy heuristic described above.4445The hint refers only to stored events. It has no effect on the real-time delivery of new events, which continues under the regular NIP-01 rules until the client sends `CLOSE` or the relay sends `CLOSED`.4647Future revisions of this NIP may define additional hint values. Implementations SHOULD accept unknown hint values without error and treat them as if absent.4849## Semantics around `created_at` ties5051When a relay does not send `"finish"`, multiple events may share the oldest `created_at` value in the response. Clients paginating with `until = oldest_created_at` risk missing events that share that timestamp. Relays SHOULD, when possible, advance the internal cursor so that all events with the boundary `created_at` are included in one response, emitting `"finish"` only when there are no older events remaining.5253## Relay advertisement5455Relays implementing this NIP SHOULD include `67` in the `supported_nips` field of their [NIP-11](11.md) document.5657## Examples5859Relay has sent every matching stored event:6061```62["REQ", "sub2", {"ids": ["abcd..."]}]63["EVENT", "sub2", {...}]64["EOSE", "sub2", ["finish"]]65```6667Relay has more matching events:6869```70["REQ", "sub2b", {"authors": ["abcd..."], "kinds": [1]}]71["EVENT", "sub2b", {...}]72... (300 events total)73["EOSE", "sub2b", ["more"]]74```7576Relay has more matching events that require authentication:7778```79["REQ", "sub2b", {"authors": ["abcd..."], "kinds": [1]}]80["EVENT", "sub4", {...}]81["AUTH", "challenge..."]82["EOSE", "sub4", ["auth", "finish"]]83```