7.1 KiB
NIP-XX: Place Reviews
Abstract
This NIP defines a standardized event format for decentralized place reviews using Nostr. Reviews are tied to real-world locations (e.g. OpenStreetMap POIs) via tags, and include structured, multi-aspect ratings, a binary recommendation signal, and optional contextual metadata.
The design prioritizes:
- Small event size
- Interoperability across clients
- Flexibility for different place types
- Efficient geospatial querying using geohashes
Event Kind
kind: 30315 (suggested; subject to coordination)
Tags
Additional tags MAY be included by clients but are not defined by this specification.
This NIP reuses and builds upon existing Nostr tag conventions:
itag: see NIP-73 (External Content Identifiers)gtag: geohash-based geotagging (community conventions)
Where conflicts arise, this NIP specifies the behavior for review events.
Required
i — Entity Identifier
Identifies the reviewed place using an external identifier. OpenStreetMap data is the default:
["i", "osm:<type>:<id>"]
Requirements:
- For OSM POIs,
<type>MUST be one of:node,way,relation
Examples:
["i", "osm:node:123456"]
["i", "osm:way:987654"]
Geospatial Tags
g — Geohash
Geohash tags are used for spatial indexing and discovery.
Requirements
- Clients MUST include at least one high-precision geohash (length ≥ 9)
Recommendations
Clients SHOULD include geohashes at the following resolutions:
- length 4 — coarse (city-scale discovery)
- length 6 — medium (default query level, ~1 km)
- length 7 — fine (neighborhood, ~150 m)
Example:
["g", "thrr"]
["g", "thrrn5"]
["g", "thrrn5k"]
["g", "thrrn5kxyz"]
Querying
Geospatial queries are performed using the g tag.
- Clients SHOULD query using a single geohash precision level per request
- Clients MAY include multiple geohash values in a filter to cover a bounding box
- Clients SHOULD limit the number of geohash values per query (e.g. ≤ 30)
- Clients MAY reduce precision or split queries when necessary
Note: Other queries (e.g. fetching reviews for a specific place) are performed using the i tag and are outside the scope of geospatial querying.
Content (JSON)
The event content MUST be valid JSON matching the following schema.
Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["version", "ratings"],
"additionalProperties": false,
"properties": {
"version": {
"type": "integer",
"const": 1
},
"ratings": {
"type": "object",
"required": ["quality"],
"additionalProperties": false,
"properties": {
"quality": { "$ref": "#/$defs/score" },
"value": { "$ref": "#/$defs/score" },
"experience": { "$ref": "#/$defs/score" },
"accessibility": { "$ref": "#/$defs/score" },
"aspects": {
"type": "object",
"minProperties": 1,
"maxProperties": 20,
"additionalProperties": { "$ref": "#/$defs/score" },
"propertyNames": {
"pattern": "^[a-z][a-z0-9_]{1,31}$"
}
}
}
},
"recommend": {
"type": "boolean"
},
"familiarity": {
"type": "string",
"enum": ["low", "medium", "high"],
"description": "User familiarity: low = first visit; medium = occasional; high = frequent"
},
"context": {
"type": "object",
"additionalProperties": false,
"properties": {
"visited_at": {
"type": "integer",
"minimum": 0
},
"duration_minutes": {
"type": "integer",
"minimum": 0,
"maximum": 1440
},
"party_size": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
}
},
"review": {
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "string",
"maxLength": 1000
},
"language": {
"type": "string",
"pattern": "^[a-z]{2}(-[A-Z]{2})?$"
}
}
}
},
"$defs": {
"score": {
"type": "integer",
"minimum": 1,
"maximum": 10
}
}
}
Example
Restaurant Review Event
Tags
[
["i", "osm:node:123456"],
["g", "thrr"],
["g", "thrrn5"],
["g", "thrrn5k"],
["g", "thrrn5kxyz"]
]
Content
{
"version": 1,
"ratings": {
"quality": 9,
"value": 8,
"experience": 9,
"accessibility": 7,
"aspects": {
"food": 9,
"service": 6,
"ambience": 8,
"wait_time": 5
}
},
"recommend": true,
"familiarity": "medium",
"context": {
"visited_at": 1713200000,
"duration_minutes": 90,
"party_size": 2
},
"review": {
"text": "Excellent food with bold flavors. Service was a bit slow, but the atmosphere made up for it.",
"language": "en"
}
}
Semantics
Ratings
- Scores are integers from 1 to 10
qualityis required and represents the core evaluation of the place- Other fields are optional and context-dependent
Aspects
- Free-form keys allow domain-specific ratings
- Clients MAY define and interpret aspect keys
- Clients SHOULD reuse commonly established aspect keys where possible
Recommendation Signal
The recommend field represents a binary verdict:
true→ user recommends the placefalse→ user does not recommend the place
Clients SHOULD strongly encourage users to provide this value.
Familiarity
Represents user familiarity with the place:
low→ first visit or limited exposuremedium→ occasional visitshigh→ frequent or expert-level familiarity
Clients MAY use this signal for weighting during aggregation.
Context
Optional metadata about the visit.
visited_atis a Unix timestampduration_minutesrepresents time spentparty_sizeindicates group size
Interoperability
This specification defines a content payload only.
- In Nostr: place identity is conveyed via tags
- In other protocols (e.g. ActivityPub, AT Protocol): identity MUST be mapped to the equivalent field (e.g.
object)
Content payloads SHOULD NOT include place identifiers.
Rationale
No Place Field in Content
Avoids duplication and inconsistency with tags.
Multi-Aspect Ratings
Separates concerns (e.g. quality vs service), improving signal quality.
Recommendation vs Score
Binary recommendation avoids averaging pitfalls and improves ranking.
Familiarity
Provides a human-friendly proxy for confidence without requiring numeric input.
Geohash Strategy
Multiple resolutions balance:
- efficient querying
- small event size
- early-stage discoverability
Future Work
- Standardized aspect vocabularies
- Reputation and weighting models
- Indexing/aggregation services
- Cross-protocol mappings
Security Considerations
- Clients SHOULD validate all input
- Malicious or spam reviews may require external moderation or reputation systems
Copyright
This NIP is public domain.