draft
optional
This specification defines calendar events representing an occurrence at a specific moment or between moments. These calendar events are addressable and deletable per NIP-09.
Unlike the term calendar event
specific to this NIP, the term event
is used broadly in all the NIPs to describe any Nostr event. The distinction is being made here to discern between the two terms.
There are two types of calendar events represented by different kinds: date-based and time-based calendar events. Calendar events are not required to be part of a calendar.
This kind of calendar event starts on a date and ends before a different date in the future. Its use is appropriate for all-day or multi-day events where time and time zone hold no significance. e.g., anniversary, public holidays, vacation days.
The format uses an addressable event of kind:31922
.
The .content
of these events should be a detailed description of the calendar event. It is required but can be an empty string.
The list of tags are as follows:
d
(required) universally unique identifier (UUID). Generated by the client creating the calendar event.title
(required) title of the calendar eventstart
(required) inclusive start date in ISO 8601 format (YYYY-MM-DD). Must be less thanend
, if it exists.end
(optional) exclusive end date in ISO 8601 format (YYYY-MM-DD). If omitted, the calendar event ends on the same date asstart
.location
(optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video callg
(optional) geohash to associate calendar event with a searchable physical locationp
(optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meetingt
(optional, repeated) hashtag to categorize calendar eventr
(optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
The following tags are deprecated:
name
name of the calendar event. Use only iftitle
is not available.
{
"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at": <Unix timestamp in seconds>,
"kind": 31922,
"content": "<description of calendar event>",
"tags": [
["d", "<UUID>"],
["title", "<title of calendar event>"],
// Dates
["start", "<YYYY-MM-DD>"],
["end", "<YYYY-MM-DD>"],
// Location
["location", "<location>"],
["g", "<geohash>"],
// Participants
["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
// Hashtags
["t", "<tag>"],
["t", "<tag>"],
// Reference links
["r", "<url>"],
["r", "<url>"]
]
}
This kind of calendar event spans between a start time and end time.
The format uses an addressable event kind 31923
.
The .content
of these events should be a detailed description of the calendar event. It is required but can be an empty string.
The list of tags are as follows:
d
(required) universally unique identifier (UUID). Generated by the client creating the calendar event.title
(required) title of the calendar eventstart
(required) inclusive start Unix timestamp in seconds. Must be less thanend
, if it exists.end
(optional) exclusive end Unix timestamp in seconds. If omitted, the calendar event ends instantaneously.start_tzid
(optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g.,America/Costa_Rica
end_tzid
(optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g.,America/Costa_Rica
. If omitted andstart_tzid
is provided, the time zone of the end timestamp is the same as the start timestamp.summary
(optional) brief description of the calendar eventimage
(optional) url of an image to use for the eventlocation
(optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video callg
(optional) geohash to associate calendar event with a searchable physical locationp
(optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meetingl
(optional, repeated) label to categorize calendar event. e.g.audiospace
to denote a scheduled event from a live audio space implementation such as cornychat.comt
(optional, repeated) hashtag to categorize calendar eventr
(optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
The following tags are deprecated:
name
name of the calendar event. Use only iftitle
is not available.
{
"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at": <Unix timestamp in seconds>,
"kind": 31923,
"content": "<description of calendar event>",
"tags": [
["d", "<UUID>"],
["title", "<title of calendar event>"],
["summary", "<brief description of the calendar event>"],
["image", "<string with image URI>"],
// Timestamps
["start", "<Unix timestamp in seconds>"],
["end", "<Unix timestamp in seconds>"],
["start_tzid", "<IANA Time Zone Database identifier>"],
["end_tzid", "<IANA Time Zone Database identifier>"],
// Location
["location", "<location>"],
["g", "<geohash>"],
// Participants
["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
// Labels (example using com.cornychat namespace denoting the event as an audiospace)
["L", "com.cornychat"],
["l", "audiospace", "com.cornychat"],
// Hashtags
["t", "<tag>"],
["t", "<tag>"],
// Reference links
["r", "<url>"],
["r", "<url>"]
]
}
A calendar is a collection of calendar events, represented as a custom replaceable list event using kind 31924
. A user can have multiple calendars. One may create a calendar to segment calendar events for specific purposes. e.g., personal, work, travel, meetups, and conferences.
The .content
of these events should be a detailed description of the calendar. It is required but can be an empty string.
The format uses a custom replaceable list of kind 31924
with a list of tags as described below:
d
(required) universally unique identifier. Generated by the client creating the calendar.title
(required) calendar titlea
(repeated) reference tag to kind31922
or31923
calendar event being responded to
{
"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at": <Unix timestamp in seconds>,
"kind": 31924,
"content": "<description of calendar>",
"tags": [
["d", "<UUID>"],
["title", "<calendar title>"],
["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"],
["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"]
]
}
A calendar event RSVP is a response to a calendar event to indicate a user's attendance intention.
If a calendar event tags a pubkey, that can be interpreted as the calendar event creator inviting that user to attend. Clients MAY choose to prompt the user to RSVP for the calendar event.
Any user may RSVP, even if they were not tagged on the calendar event. Clients MAY choose to prompt the calendar event creator to invite the user who RSVP'd. Clients also MAY choose to ignore these RSVPs.
This NIP is intentionally not defining who is authorized to attend a calendar event if the user who RSVP'd has not been tagged. It is up to the calendar event creator to determine the semantics.
This NIP is also intentionally not defining what happens if a calendar event changes after an RSVP is submitted.
The RSVP MUST have an a
tag of the event coordinates to the calendar event, and optionally an e
tag of the id of the specific calendar event revision. If an e
tag is present, clients SHOULD interpret it as an indication that the RSVP is a response to that revision of the calendar event, and MAY interpret it to not necessarily apply to other revisions of the calendar event.
The RSVP MAY tag the author of the calendar event it is in response to using a p
tag so that clients can easily query all RSVPs that pertain to the author.
The format uses an addressable event kind 31925
.
The .content
of these events is optional and should be a free-form note that adds more context to this calendar event response.
The list of tags are as follows:
a
(required) coordinates to a kind31922
or31923
calendar event being responded to.e
(optional) event id of a kind31922
or31923
calendar event being responded to.d
(required) universally unique identifier. Generated by the client creating the calendar event RSVP.status
(required)accepted
,declined
, ortentative
. Determines attendance status to the referenced calendar event.fb
(optional)free
orbusy
. Determines if the user would be free or busy for the duration of the calendar event. This tag must be omitted or ignored if thestatus
label is set todeclined
.p
(optional) pubkey of the author of the calendar event being responded to.
{
"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at": <Unix timestamp in seconds>,
"kind": 31925,
"content": "<note>",
"tags": [
["e", "<kind 31922 or 31923 event id", "<optional recommended relay URL>"]
["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional recommended relay URL>"],
["d", "<UUID>"],
["status", "<accepted/declined/tentative>"],
["fb", "<free/busy>"],
["p", "<hex pubkey of kind 31922 or 31923 event>", "<optional recommended relay URL>"]
]
}
- No private events
Recurring calendar events come with a lot of complexity, making it difficult for software and humans to deal with. This complexity includes time zone differences between invitees, daylight savings, leap years, multiple calendar systems, one-off changes in schedule or other metadata, etc.
This NIP intentionally omits support for recurring calendar events and pushes that complexity up to clients to manually implement if they desire. i.e., individual calendar events with duplicated metadata represent recurring calendar events.