Community

NIPs

NIP-40: Expiration Timestamp

NIP-40 defines the expiration tag: a timestamp that tells relays and clients when an event needs to be treated as expired, while warning people not to confuse expiry with secrecy.

NIP-40: Expiration Timestamp visual
NIPs Under the hood Events, NIPs, relay behavior and the shared formats apps can trust.
Back to Nostr
NIPs Open NIP map Deep guidesConcepts, NIP pages and source checks BrowseClose
Core protocoldraftoptionalrelay

NIP-40: Expiration Timestamp

NIP40Statusdraft / optional / relayCore tagexpirationTimestampUnix secondsClient ruleignore expired eventsRelay warningmay persist expired data indefinitely

Some events are meant to age out

NIP-40 exists because not every Nostr event needs to feel permanent. A temporary announcement, limited-time offer, draft wrap, live status or short-lived coordination note may be useful for a while and misleading later. The expiration tag gives authors a standard way to say when the event needs to stop being treated as current.

That is different from deletion. Expiration is a time signal. A relay may delete the event, stop returning it, or keep it internally. A client needs to ignore it after the timestamp. The standard gives software a shared cue; it does not give users a privacy guarantee.

This NIP matters because temporary behavior appears in several other parts of the system. NIP-37 recommends expiration for draft wraps. NIP-38 uses expiry for live music status. Other app-specific flows can use the same tag rather than inventing their own time-to-live field.

One tag, a Unix timestamp and a very important warning

The tag shape is ["expiration", "1600000000"], where the value is a Unix timestamp in seconds, matching the style of created_at. Clients need to use relay information, especially supported_nips, to decide whether a relay supports expiration before publishing expiration-dependent events there.

Clients need to ignore expired events. Relays must not send expired events to clients and needs to drop events that are already expired when published. Relays may, however, keep expired messages indefinitely and may not delete them at the exact expiration time.

The warning in the official source is the heart of the standard: expired events can be downloaded by third parties while they are still public. Do not treat expiration as a security feature for private conversations or sensitive content.

A simple tag that depends on relay honesty

NIP-40 entered the visible file history in December 2022 through Thomas's early expiration timestamp work. Later commits adjusted grammar and formatting. In December 2025, a relay-tag-related update touched the broader source history around relay metadata.

The small history matches the small surface area. NIP-40 does not need many event kinds. Its product effect depends on relays and clients treating one tag consistently.

That makes the standard deceptively operational. A user experiences expiration only if relays stop sending stale events and clients hide them. The tag is easy. The behavior around storage and query results is the real implementation.

First visible file work2022-12-15 by ThomasRelay-facing standardClients need to check supported_nips before relying on itOpen Git history

Expiry belongs in both storage and display logic

A client implementing NIP-40 needs to do more than add a tag. It needs to avoid publishing expiration-dependent events to relays that do not advertise support. It needs to hide expired events in feeds, search results and profile surfaces. It needs to also explain to users when expiration is best-effort rather than guaranteed erasure.

A relay implementing NIP-40 needs policy. It can drop expired incoming events, avoid serving expired events and optionally delete stored events after expiration. But the source explicitly allows relays to persist them indefinitely. That means UI copy needs to stay careful.

The useful tests are simple. Publish an event that expires soon, query before and after expiration, test relays with and without support, and inspect whether clients still show cached copies.

Author intentThe expiration tag names when the event needs to no longer be considered current.
Client behaviorClients need to ignore expired events and avoid unsupported relays for expiration-dependent flows.
Relay behaviorRelays must not send expired events, but may persist data indefinitely.
BoundaryExpiration is not encryption, not deletion proof and not a privacy feature.

The danger is selling expiry as disappearance

The first risk is product language. If a button says a post will disappear, users may assume the event cannot be copied. NIP-40 does not support that promise. It supports an expiry timestamp that compliant clients and relays can respect.

The second risk is uneven support. A client may hide an expired event while another relay or archive still returns it. That is normal for an open relay network, but users need the right expectation before they use expiration for anything sensitive.

Read NIP-40 in the wild

NIP-40 gives events an expiration timestamp. It is useful for status, offers, temporary announcements, live rooms and anything that loses meaning after a known time.

Expiration is not deletion. A responsible relay or client may stop serving the event, but copies can remain. Treat it as a display and retention instruction, not a privacy guarantee.

What changes when you actually use it

For you, NIP-40: Expiration Timestamp is felt when an app either behaves predictably or suddenly loses context. The visible symptom may be a missing reply, a broken link, a strange reaction count, an empty result or a relay error that looks like the whole network failed. The official terms draft, relay, expiration are where that visible behavior begins, so the source is not background material; it is the place where the product promise gets its limits.

What changes for builders and operators

For builders, NIP-40: Expiration Timestamp is compatibility discipline. Implement draft, relay, expiration against more than one relay and more than one library, then test malformed, missing and duplicated data. Core standards fail most painfully when the happy path looks fine and the second client exposes the shortcut.

What the official file makes concrete

Inspect draft, relay, expiration because these are the pieces most likely to surface as product behavior.

NIP-40: Expiration Timestamp is a shared contract between independent software. The smallest field can become user-visible when two clients disagree about it.

Where it breaks

The failure mode in NIP-40: Expiration Timestamp is often indirect. Nobody complains about draft, relay, expiration; they complain that the feed is wrong, the reply vanished or the relay behaved strangely. Use the official file to diagnose the hidden cause instead of patching only the visual symptom.

Where this appears outside the markdown

In the ecosystem, NIP-40: Expiration Timestamp is not something most people choose directly. It is the invisible grammar behind clients, relays, crawlers, search tools and archives. When a product team treats draft, relay, expiration as implementation detail only, the mistake eventually reaches the surface as missing history, bad threading or state that cannot be reconstructed after a client switch.

The nearby-standard trap

The nearby-standard trap in NIP-40: Expiration Timestamp is assuming the base layer solves the higher-level feature. This NIP may define the common grammar, but publishing, wallets, moderation, media or groups still need their own constraints. Read NIP-01 and the adjacent source links to see where the base contract ends and the product-specific promise begins.

Language that keeps the feature honest

Good product copy for NIP-40: Expiration Timestamp does not say "the protocol handles it" and move on. It explains the visible consequence: what was sent, what was accepted, what was rejected, what is still loading and what another relay or client may show differently.

What this page does not promise

NIP-40: Expiration Timestamp does not promise a finished social product. It gives software a shared grammar. Feed design, moderation, ranking, notifications, storage duration and recovery remain separate product decisions. That distinction matters because a client can be technically compatible and still give you a weak experience if it hides relay errors, drops context or treats optional fields as if every app understood them.

Read it as a field test

Start NIP-40: Expiration Timestamp with the visible product symptom, then trace it back to draft, relay, expiration. That order keeps the article grounded: you see why the field exists, which relay or client behavior depends on it, and where adjacent standards change the story. A core NIP is strong only when it explains both the normal path and the awkward edge case.

Where the standard earns trust

The source links give you places to test the interpretation in public: NIP-11 Relay Information, NIP-37 Draft Wraps, NIP-38 User Statuses, nips.nostr.com NIP-40. Use those links to move from the spec to live libraries, mirrors, pull requests, guides or products.

Official NIP-40 source is the anchor for exact wording, and NIP-40 commit history shows how that wording moved over time. The strongest secondary clues here are NIP-11 Relay Information, NIP-37 Draft Wraps, NIP-38 User Statuses. Treat this evidence chain as part of the article, not as footnotes. A NIP page becomes useful when you can move from claim to source to working behavior without guessing.

Keep the chain visible for NIP-40: Expiration Timestamp: first the human promise, then draft, relay, expiration, then the implementation record, then the real-world failure case. That order keeps NIP-40 useful without turning it into marketing copy or protocol trivia.

Three questions to carry forward

  • Can two independent clients read the same draft, relay, expiration without a hidden compatibility rule?
  • Does the UI explain relay rejection, missing context or state replacement without blaming the whole network?
  • Which adjacent standard, especially NIP-01 and the adjacent source links, changes the behavior once the base event leaves the happy path?

What to verify before you rely on it

  • Find draft, relay, expiration in the official file and check where the UI exposes the same concept.
  • Read NIP-01 and the adjacent source links as context before treating NIP-40 as a complete product story.
  • Open at least one implementation, mirror, pull request or library source from the source links before trusting that the idea is mature.
  • Test the unhappy path: missing relays, stale metadata, invalid signatures, blocked events, expired state, revoked permissions or unavailable media.
  • Write the user-facing copy in plain language. If a standard changes authority, privacy, money, moderation or recovery, say that before the click.

Direct sources

Use these sources for NIP-40: Expiration Timestamp in that order: Official NIP-40 source for the current wording; NIP-40 commit history for the change record; NIP-11 Relay Information, NIP-37 Draft Wraps, NIP-38 User Statuses for public context. The article gives you the consequence in plain language, but the source trail is where exact fields, status notes, unresolved debates and implementation proof stay checkable.

Back to the NIP hub
NIPs route visual cue 1
NIPs route visual cue 2
NIPs route visual cue 3
NIPs route visual cue 4
NIPs route visual cue 5