nips/32.md
2023-06-13 17:30:26 -07:00

6.6 KiB

NIP-32

Labeling

draft optional author:staab author:gruruya author:s3x-jay

A label is a kind 1985 event that is used to label other entities. This supports a number of use cases:

  • Distributed moderation and content recommendations
  • Reviews and ratings
  • Definition of edges in a graph structure

Label Target

The label event MUST include one or more tags representing the object or objects being labeled: e, p, a, r, or t tags. This allows for labeling of events, people, relays, or topics respectively. As with NIP-01, a relay hint SHOULD be included when using e and p tags.

Label Tag

This NIP introduces a new tag l which denotes a label, and a new L tag which denotes a label namespace. A label MUST include a mark matching an L tag. L tags refer to a tag type within nostr, or a nomenclature external to nostr defined either formally or by convention. Any string can be a namespace, but publishers SHOULD ensure they are unambiguous by using a well-defined namespace (such as an ISO standard) or reverse domain name notation. Some examples:

Namespaces starting with # indicate that the label target should be associated with the label's value. This is a way of attaching standard nostr tags to events, pubkeys, relays, urls, etc.

  • ["l", "footstr", "#t"] - the publisher thinks the given entity should have the footstr topic applied.
  • ["l", "<pubkey>", "#p"] - the publisher thinks the given entity is related to <pubkey>
  • ["l", "D005528", "MeSH"] - "Foot" from NIH's Medical Subject Headings vocabulary
  • ["l", "3173435", "GeoNames"] - Milan, Italy using the GeoNames coding system
  • ["l", "IT-MI", "ISO-3166-2"] - Milano, Italy using ISO 3166-2.
  • ["l", "VI-hum", "com.example.ontology"] - Violence toward a human being as defined by ontology.example.com.
  • ["l", "relay/review", "com.example.ontology"] - the publisher is leaving a review about a relay, as defined by ontology.example.com.

L tags containing the label namespaces MUST be included in order to support searching by namespace rather than by a specific tag. The special ugc ("user generated content") namespace MAY be used when the label content is provided by an end user.

l and L tags MAY be added to other event kinds to support self-reporting. For events with a kind other than 1985, labels refer to the event itself.

Label Annotations

A label tag MAY include a 4th positional element detailing extra metadata about the label in question. This string should be a json-encoded object. Any key MAY be used, but the following are recommended:

  • quality may have a value of 0 to 1. This allows for an absolute, granular scale that can be represented in any way (5 stars, color scale, etc).
  • confidence may have a value of 0 to 1. This indicates the certainty which the author has about their rating.
  • context may be an array of urls (including NIP-21 urls) indicating other context that should be considered when interpreting labels.

Content

Labels should be short, meaningful strings. Longer discussions, such as for a review, or an explanation of why something was labeled the way it was, should go in the event's content field.

Example events

A single event can apply multiple labels to multiple targets to support mass-tagging. Multiple namespaces may be used at the same time.

{
  "kind": 1985,
  "tags": [
    ["e", <id>, <relay_url>],
    ["p", <id>, <relay_url>],
    ["t", "chickens"],
    ["L", "#t"]
    ["L", "ugc"]
    ["L", "com.example.labels"]
    ["l", "chickens", "#t"],
    ["l", "user generated content", "ugc"],
    ["l", "permaculture", "com.example.labels"],
    ["l", "permies", "com.example.labels"],
    ["l", "farming", "com.example.labels"],
  ],
  "content": "",
  ...
}

A suggestion that multiple pubkeys be associated with the permies topic.

{
  "kind": 1985,
  "tags": [
    ["L", "#t"],
    ["l", "permies", "#t"],
    ["p", <pubkey1>, <relay_url>],
    ["p", <pubkey2>, <relay_url>]
  ],
  "content": "",
  ...
}

A review of a relay, as relates to certain topics, including additional dimensions. The author is indicating here that relay_url is related to the bitcoin topic, but they're not very sure that's the case.

{
  "kind": 1985,
  "tags": [
    ["L", "#t"],
    ["l", "bitcoin", "#t", "{\"quality\": 0.7, \"confidence\": 0.2}"],
    ["r", <relay_url>]
  ],
  "content": "I think this relay is mostly just bitcoiners.",
  ...
}

A plain review of a relay.

{
  "kind": 1985,
  "tags": [
    ["L", "com.example.ontology"],
    ["l", "relay/review", "com.example.ontology", "{\"quality\": 0.1}"],
    ["r", <relay_url>]
  ],
  "content": "This relay is full of mean people.",
  ...
}

A more abstract use case: defining an edge in a graph structure, in this case identifying a lightning channel that is open between two pubkeys. This just demonstrates the flexibility this spec provides for overlaying structured metadata on top of nostr.

{
  "kind": 1985,
  "tags": [
    ["L", "my-lightning-nomenclature"],
    ["l", "channel", "my-lightning-nomenclature"],
    ["p", <pubkey1>, <relay_url>],
    ["p", <pubkey2>, <relay_url>]
  ],
  "content": "<channel_id>",
  ...
}

Publishers can self-label by adding l tags to their own non-1985 events.

{
  "kind": 1,
  "tags": [
    ["L", "com.example.ontology"],
    ["l", "IL-frd", "com.example.ontology"]
  ],
  "content": "Send me 100 sats and I'll send you 200 back",
  ...
}

Other Notes

When using this NIP to bulk-label many targets at once, events may be deleted and a replacement may be published. We have opted not to use parameterizable/replaceable events for this due to the complexity in coming up with a standard d tag.

Before creating a vocabulary, explore how your use case may have already been designed and imitate that design if possible. Reverse domain name notation is encouraged to avoid namespace clashes, but for the sake of interoperability all namespaces should be considered open for public use, and not proprietary. In other words, if there is a namespace that fits your use case, use it even if it points to someone else's domain name.

Vocabularies MAY choose to include the namespace in the label, delimited by a : character. This may be preferred when defining more formal vocabularies that should not be confused with another namespace when querying without an L tag. For these vocabularies, all labels SHOULD include the namespace (rather than mixing qualified and unqualified labels).