Chapter 12 - Core
12
Nostr Implementation Possibility - Hex № 12

Generic Tag Queries

This chapter is closed. NIP-12 once defined generic single-letter tag filters. That rule is now part of the core protocol in NIP-01.

Merged

1 Overview

NIP-12 was a short extension to the filter object. NIP-01 already let a client query events by the e tag or the p tag. NIP-12 opened this up. A client could query by any single-letter tag, using a filter key such as "#r" or "#t".

Relays only indexed tags whose name was a single letter, a-z or A-Z. This kept relay indexes small. Applications were free to use longer tag names for their own data without forcing every relay to index them.

Merged

NIP-12 is closed and carries no separate rules of its own anymore. Every rule it defined now lives in NIP-01, section 3 (Tags) and section 5 (Client ↔ Relay Messages). Read this page for history, then read NIP-01 for the current spec.

2 What NIP-12 Defined

NIP-12 stated three rules, restated here in Simplified Technical English:

  • A filter key that starts with #, followed by one letter, is a tag query. Example: "#r".
  • The value of a tag-query key must be an array of strings. A matching event needs only one tag value in common with the filter.
  • Relays index only single-letter tag names. Longer tag names are stored with the event but are not queryable. Tag names are case-sensitive: "#t" and "#T" are different queries.

NIP-12 also listed motivating use cases: an r tag for referencing a URL, a g tag for a geohash, and a t tag for a hashtag. It did not standardize any specific tag name for any purpose.

Where It Lives Now

NIP-01 absorbed all of this. Its Tags section explains that relays index every tag whose name is one English letter, and shows the filter shape {"#e": [<event id>]} as the general pattern. Its Filters section lists "#<letter>" directly inside the filter object. There is no remaining behavior that is specific to NIP-12; it is now an ordinary part of the base protocol.

3 Historical Example

This is the filter example NIP-12 originally used to explain generic tag queries. It still works exactly like this under NIP-01 today.

Example - filter with a generic tag query
{
  "kinds": [1],
  "#r": ["foo", "bar"]
}

This filter matches any kind-1 event with an r tag whose value is "foo" or "bar".

4 Version History

  • Closed2023-08-13Merged into NIP-01 along with NIP-16, NIP-20, and NIP-33 (PR #703). All four were already "final, mandatory" — folding them into the root spec meant a client or relay only had to read one document to reach baseline compliance.
  • 20232023-11-15Repo-wide cleanup removed the per-file author badge from the now-stub page.
  • 20232023-07-09jiftechnify clarified that tag names are case-sensitive.
  • 20222022-07-10fiatjaf restricted indexing to single-letter tags only, to keep relay indexes small.
  • Origin2022-05-01fiatjaf published NIP-12, authored with scsibug, in the newly migrated nostr-protocol/nips repository.

Original Proposal - Credits

Authorsscsibug, fiatjaf
First commit2022-05-01 — “migrate nips from main nostr repo.”
Statusfinal mandatory — merged, no longer a standalone document
Source12.md on GitHub - full change history

5 See Also

  • NIP-01 — the current, canonical home of generic tag queries and the full filter object.
  • NIP-16 — event treatment (kind ranges), merged the same day as NIP-12.
  • NIP-20 — command results, merged the same day as NIP-12.
  • NIP-33 — addressable events, merged the same day as NIP-12.