Files
marco/doc/nostr/nip-place-photos.md
Râu Cao 95961e680f
All checks were successful
CI / Lint (push) Successful in 31s
CI / Test (push) Successful in 58s
Add rationale for kind numbers
2026-04-22 15:37:45 +04:00

5.1 KiB

NIP-XX: Place Photos and Media

draft optional

Abstract

This NIP defines a standardized event format for sharing photos, videos, and other visual media tied to specific real-world locations (e.g., OpenStreetMap POIs).

While NIP-68 (Picture-first feeds) caters to general visual feeds, this NIP specifically targets map-based applications, travel logs, and location directories by mandating strict entity identifiers (i tags) and spatial indexing (g tags).

Event Kind

kind: 360

Content

The .content of the event SHOULD generally be empty. If a user wishes to provide a detailed description for a place, clients SHOULD encourage them to create a Place Review event (kind: 30360) instead.

Tags

This NIP relies on existing Nostr tag conventions to link media to places and provide inline metadata.

Required Tags

1. i — Entity Identifier

Identifies the exact place the media depicts using an external identifier (as defined in NIP-73). OpenStreetMap data is the default:

["i", "osm:node:123456"]
  • For OSM POIs, <type> MUST be one of: node, way, relation.

2. g — Geohash

Used for spatial indexing and discovery. Events MUST include at least one high-precision geohash. To optimize for map-based discovery across different zoom levels, clients SHOULD include geohashes at multiple resolutions:

["g", "thrr"]        // coarse (~city)
["g", "thrrn5"]      // medium (~1km)
["g", "thrrn5k"]     // fine (~150m)
["g", "thrrn5kxyz"]  // exact

3. imeta — Inline Media Metadata

An event MUST contain exactly one imeta tag representing a single media item. The primary url MAY also be appended to the event's .content for backwards compatibility with clients that do not parse imeta tags.

Clients SHOULD include alt (accessibility descriptions), dim (dimensions), m (MIME type), thumb (URL to a smaller thumbnail image), and blurhash where possible. Clients MAY also include fallback URLs if the media is hosted on multiple servers.

[
  "imeta",
  "url https://blossom.example.com/8e2e28a503fa37482de5b0959ee38b2bb4de4e0a752db24c568981c2ab410260.jpg",
  "m image/jpeg",
  "dim 1440x1920",
  "alt A steaming bowl of ramen on a wooden table at the restaurant.",
  "fallback https://mirror.example.com/8e2e28a503fa37482de5b0959ee38b2bb4de4e0a752db24c568981c2ab410260.jpg",
  "thumb https://example.com/7a1f592f6ea8e932b1de9568285b01851e4cf708466b0a03010b91e92c6c8135.jpg",
  "blurhash eVF$^OI:${M{o#*0-nNFxakD-?xVM}WEWB%iNKxvR-oetmo#R-aen$"
]

Optional Tags

  • t: Hashtags for categorization (e.g., ["t", "food"], ["t", "architecture"]).
  • content-warning: If the media contains NSFW or sensitive imagery.
  • published_at: Unix timestamp of when the photo was originally taken or published.

Example Event

{
  "id": "<32-bytes hex>",
  "pubkey": "<32-bytes hex>",
  "created_at": 1713205000,
  "kind": 360,
  "content": "",
  "tags": [
    ["i", "osm:node:987654321"],
    ["g", "xn0m"],
    ["g", "xn0m7h"],
    ["g", "xn0m7hwq"],

    [
      "imeta",
      "url https://blossom.example.com/a9c84e183789a74288b8e05d04cc61230e74f386925a953e6b29f957e8cc3a61.jpg",
      "m image/jpeg",
      "dim 1920x1920",
      "alt A close-up of spicy miso ramen with chashu pork, soft boiled egg, and scallions.",
      "fallback https://mirror.example.com/a9c84e183789a74288b8e05d04cc61230e74f386925a953e6b29f957e8cc3a61.jpg",
      "thumb https://example.com/c5a528e20235e16cc1c18090b8f04179de76288ea4e410b0fcb8d1487e416a2d.jpg",
      "blurhash UHI=0o~q4T-o~q%MozM{x]t7RjRPt7oKkCWB"
    ],

    ["t", "ramen"],
    ["t", "food"]
  ]
}

Rationale

Kind 360

Easy to remember as a 360-degree view of places.

Why not use NIP-68 (Picture-first feeds)?

NIP-68 is designed for general-purpose social feeds (like Instagram). Place photos require strict guarantees about what entity is being depicted to be useful for map clients, directories, and review aggregators. By mandating the i tag for POI linking and the g tag for spatial querying, this kind ensures interoperability for geo-spatial applications without cluttering general picture feeds with mundane POI images (like photos of storefronts or menus).

Separation from Place Reviews

Reviews (kind 30360) and media have different lifecycles and data models. A user might upload 10 photos of a park without writing a review, or write a detailed review without attaching photos. Keeping them as separate events allows clients to query imeta attachments for a specific i tag to quickly build a photo gallery for a place, regardless of whether a review was attached.

Single Photo per Event

Restricting events to a single imeta attachment (one photo per event) is an intentional design choice. Batching photos into a single event forces all engagement (likes, zaps) to apply to the entire batch, rendering granular tagging and sorting impossible. Single-photo events enable per-photo engagement, fine-grained categorization (e.g., tagging one photo as "food" and another as "menu"), and richer sorting algorithms based on individual photo popularity.