Chapter 94 - Media
94
Nostr Implementation Possibility - Hex № 94

File Metadata

One event kind that describes a shared file: where it lives, what it is, and how to verify it. The building block for filesharing clients.

1 Overview

This NIP lets a user describe a file in a signed event. The event does not carry the file. It carries metadata: a download URL, a MIME type, hashes, and optional preview data.

With this metadata, relays can filter and organize shared files in any way they choose. Clients can then build many kinds of filesharing experiences on top of the same events.

The audience is narrow on purpose. "Social" clients that render kind:1 notes (NIP-10) are not expected to support this NIP. Longform clients that render kind:30023 articles (NIP-23) are not expected to support it either. For media attached inside notes, use the imeta tag from NIP-92 instead.

Hint!

Think of a kind 1063 event as a library index card. The card names the book, the shelf, and a fingerprint of the book. The book itself sits somewhere else — on an HTTP server, or in a torrent swarm.

Uploader File server Relay Viewer upload file EVENT 1063 REQ / EVENT GET url
Fig. 94-1 — Metadata and file travel apart. The relay only sees the kind 1063 index card. The file server holds the bytes.

2 The Kind 1063 Event

This NIP defines one event kind: 1063. It is a regular event, so relays store all of them (NIP-01). The content field holds a description of the file content — a caption. All file data lives in tags:

Event template - kind 1063
{
  "kind": 1063,
  "tags": [
    ["url", <string with URI of file>],
    ["m", <MIME type>],
    ["x", <Hash SHA-256>],
    ["ox", <Hash SHA-256>],
    ["size", <size of file in bytes>],
    ["dim", <size of file in pixels>],
    ["magnet", <magnet URI>],
    ["i", <torrent infohash>],
    ["blurhash", <value>],
    ["thumb", <string with thumbnail URI>, <Hash SHA-256>],
    ["image", <string with preview URI>, <Hash SHA-256>],
    ["summary", <excerpt>],
    ["alt", <description>]
  ],
  "content": "<caption>",
  // other fields per NIP-01...
}

3 Tag Reference

The tag list below is the full set this NIP defines. The first four tags carry the core identity of the file. The rest are optional helpers for previews, transports, and accessibility.

Kind 1063 tags
TagRequiredValue
urlyesThe URL to download the file.
myesA string that indicates the data type of the file. Use the MIME types format. The value should be lowercase, for example image/webp.
xyesThe SHA-256 hash of the file, as a hex-encoded string.
oxyesThe SHA-256 hash of the original file, before any transformation done by the upload server. Hex-encoded string.
sizeoptionalThe size of the file in bytes.
dimoptionalThe size of the file in pixels, in the form <width>x<height>, for example 800x600.
magnetoptionalA URI to a magnet file.
ioptionalThe torrent infohash.
blurhashoptionalThe blurhash string. The client shows it while it loads the file.
thumboptionalThe URL of a thumbnail with the same aspect ratio.
imageoptionalThe URL of a preview image with the same dimensions.
summaryoptionalA text excerpt.
altoptionalA description for accessibility.
fallbackoptionalZero or more fallback file sources, for the case when url fails. Add one fallback tag per source.
serviceoptionalThe service type that serves the file, for example NIP-96.
Tech Note

The source spec is inconsistent in two places. First, the tag list describes thumb and image as plain URLs, but the event template adds a second <Hash SHA-256> element to both tags without explaining it. Second, the event template omits the fallback and service tags, even though the tag list defines them. Treat the tag list as the complete reference.

Two hashes: x and ox

Upload servers often transform files. They may strip metadata, re-encode an image, or compress a video. The result has a new hash. This NIP keeps both fingerprints:

  • x — the hash of the file as it is served now. Use it to verify a download.
  • ox — the hash of the original file, before the server transformed it. Use it to match the file the uploader had.

To verify a file: download it from url, hash the bytes with SHA-256, and compare with x. If the download fails, try each fallback source in turn.

GET url file bytes sha256 digest compare == x tag? on failure: retry with a fallback source
Fig. 94-2 — Verify, then trust. The x hash proves the download matches the event. The fallback tags keep the file reachable.

4 Suggested Use Cases

The spec suggests three applications for kind 1063 events:

  • A relay that indexes shared files. For example, a relay that promotes torrents (see NIP-35) through the magnet and i tags.
  • A pinterest-like client. People share their portfolio and inspire others.
  • A simple way to distribute configurations and software updates. The x hash gives integrity for free.

5 Worked Example

Alice uploads a photo to a NIP-96 server. The server strips the EXIF data, so the served file has a new hash. Alice publishes this event:

Example - kind 1063 file metadata event
{
  "id": "7f3b2ac1e0…",
  "pubkey": "a1ce9f00b2…",
  "created_at": 1749821000,
  "kind": 1063,
  "tags": [
    ["url", "https://files.example.com/media/dune-sunset.webp"],
    ["m", "image/webp"],
    ["x", "3d84f2c9…served-file-hash…b7"],
    ["ox", "91c0aa47…original-file-hash…e2"],
    ["size", "482113"],
    ["dim", "1600x900"],
    ["blurhash", "LKO2?U%2Tw=w]~RBVZRi};RPxuwH"],
    ["thumb", "https://files.example.com/thumb/dune-sunset.webp"],
    ["image", "https://files.example.com/prev/dune-sunset.webp"],
    ["summary", "Sunset over the dunes, June trip"],
    ["alt", "Orange sun setting behind sand dunes"],
    ["fallback", "https://mirror.example.org/dune-sunset.webp"],
    ["service", "nip96"]
  ],
  "content": "Sunset over the dunes. Shot on film.",
  "sig": "c44e01f2…"
}

A filesharing client finds the file by its hash. It queries the indexed #x tag, verifies the download, and renders the blurhash while it waits:

Session transcript - wss://files-relay.example.com
-- find every event that describes this exact file --
→ ["REQ", "find", {"kinds":[1063], "#x":["3d84f2c9…b7"]}]
← ["EVENT", "find", {"id":"7f3b2ac1e0…", "kind":1063, …}]
← ["EOSE", "find"]
→ ["CLOSE", "find"]
-- client: GET url, sha256(bytes) == x → render file --

6 Version History

NIP-94 grew from a two-tag draft into the shared vocabulary for file metadata on Nostr. Notable changes, newest first:

  • 20242024-01NIP-96 HTTP file storage integration landed. It defined the upload flow that fills these tags and the ox pre-transformation hash.
  • 20232023-12Removed the aes-256-gcm encryption tag; nobody used it. Encryption now goes through the NIP-44 scheme.
  • 20232023-11The imeta tag arrived (NIP-92), carrying NIP-94 fields inside kind:1 notes. NIP-71 video events reuse the same layout.
  • 20232023-09Big tag expansion: thumb, image, summary, alt, and fallback added. The original-file hash shipped after several revisions as ox.
  • 20232023-09Clarified that m MIME values should be lowercase.
  • 20232023-04Added the dim tag, explained blurhash, and reworded the NIP to remove confusion.
  • 20232023-03Changed kind 1063 to a regular event and aligned the draft with other NIPs after review.
  • Origin2023-03-09frbittencourt created the draft as "NIP 94 and 95". The NIP-95 half (file storage on relays) was never merged.

Original Proposal - Credits

Authorfrbittencourt (Fernando Bittencourt)
First commit2023-03-09 — “create draft NIP 94 and 95”
Statusdraft - optional — only filesharing clients need it
Source94.md on GitHub - full change history

7 See Also

  • NIP-01 — the base event format and tag indexing that kind 1063 relies on.
  • NIP-96 — HTTP file storage servers; the natural upload counterpart, referenced by the service tag.
  • NIP-92 — the imeta tag; carries these same fields inline in notes, for social clients.
  • NIP-71 — video events; reuse the NIP-94 field vocabulary in imeta form.
  • NIP-35 — torrent events; the richer path for the magnet and i use case.
  • NIP-44 — the encryption scheme that replaced the removed aes-256-gcm tag.