RFC 5546

iCalendar Transport-Independent Interoperability Protocol (iTIP)

๐Ÿ“… published December 2009, from ietf

RFC 5546: iCalendar Transport-Independent Interoperability Protocol (iTIP) ๐ŸŽ€

Okay bestie, let's do the paperwork first ๐Ÿ’… This is RFC 5546, the iCalendar Transport-Independent Interoperability Protocol (iTIP), from the Network Working Group. It's a Standards Track doc dated December 2009, written by C. Daboo, Ed. at Apple Inc. It obsoletes RFC 2446 and updates RFC 5545 ๐Ÿฆ‹

Abstract โœจ

Okay so this doc is a protocol that uses the iCalendar object spec to get scheduling to work between different calendar systems ๐Ÿ“… The best part is that it doesn't name one specific transport, so systems can talk to each other in lots of different ways ๐ŸŒˆ Future docs will create profiles that pick specific, interoperable ways to communicate, so this one is kind of the foundation ๐Ÿงฑ

iTIP basically adds the group scheduling stuff that calendar apps already do, like publishing, scheduling, rescheduling, replying to scheduling requests, negotiating changes, and canceling ๐Ÿ’– It's giving "everyone's calendar, in sync, no drama" ๐Ÿ’…

Status of This Memo ๐ŸŒธ

This doc is an Internet standards track protocol for the Internet community, and it's asking people to discuss it and suggest improvements ๐Ÿซถ For the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ“š Distribution of this memo is unlimited, so share it with everyone ๐Ÿงš


Copyright (c) 2009 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ’œ

Ngl, this part is a little legal-y, but it's important ๐Ÿ˜ญ This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they were in effect on the date this document was published. Please read these documents carefully, because they explain your rights and restrictions for this document ๐Ÿ‘‘ Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, just like the BSD License says โš ๏ธ

Heads up: some of this document may include material from IETF Documents or IETF Contributions that were published or made publicly available before November 10, 2008. The people who control the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. Unless you get an adequate license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. The exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐Ÿ™ˆ

Table of Contents ๐Ÿ’–

   1. Introduction and Overview .......................................5
      1.1. Formatting Conventions .....................................5
      1.2. Related Documents ..........................................6
      1.3. Roles ......................................................6
      1.4. Methods ....................................................7
   2. Interoperability Models .........................................9
      2.1. Application Protocol ......................................10
           2.1.1. Scheduling State ...................................10
           2.1.2. Delegation .........................................10
           2.1.3. Acting on Behalf of Other Calendar Users ...........11
           2.1.4. Component Revisions ................................11
           2.1.5. Message Sequencing .................................12
   3. Application Protocol Elements ..................................13
      3.1. Common Component Restriction Tables .......................15
           3.1.1. VCALENDAR ..........................................15
           3.1.2. VTIMEZONE ..........................................15
           3.1.3. VALARM .............................................17
      3.2. Methods for VEVENT Calendar Components ....................17
           3.2.1. PUBLISH ............................................18
           3.2.2. REQUEST ............................................20
           3.2.3. REPLY ..............................................25
           3.2.4. ADD ................................................27
           3.2.5. CANCEL .............................................29
           3.2.6. REFRESH ............................................31
           3.2.7. COUNTER ............................................33
           3.2.8. DECLINECOUNTER .....................................35
      3.3. Methods for VFREEBUSY Components ..........................37
           3.3.1. PUBLISH ............................................37
           3.3.2. REQUEST ............................................40
           3.3.3. REPLY ..............................................42

      3.4. Methods for VTODO Components ..............................44
           3.4.1. PUBLISH ............................................44
           3.4.2. REQUEST ............................................46
           3.4.3. REPLY ..............................................51
           3.4.4. ADD ................................................53
           3.4.5. CANCEL .............................................55
           3.4.6. REFRESH ............................................57
           3.4.7. COUNTER ............................................59
           3.4.8. DECLINECOUNTER .....................................61
      3.5. Methods for VJOURNAL Components ...........................62
           3.5.1. PUBLISH ............................................63
           3.5.2. ADD ................................................64
           3.5.3. CANCEL .............................................66
      3.6. Status Replies ............................................68
      3.7. Implementation Considerations .............................77
           3.7.1. Working With Recurrence Instances ..................77
           3.7.2. Attendee Property Considerations ...................78
           3.7.3. Extension Tokens ...................................79
   4. Examples .......................................................79
      4.1. Published Event Examples ..................................79
           4.1.1. A Minimal Published Event ..........................80
           4.1.2. Changing a Published Event .........................80
           4.1.3. Canceling a Published Event ........................81
           4.1.4. A Rich Published Event .............................81
           4.1.5. Anniversaries or Events Attached to Entire Days ....83
      4.2. Group Event Examples ......................................83
           4.2.1. A Group Event Request ..............................84
           4.2.2. Reply to a Group Event Request .....................85
           4.2.3. Update an Event ....................................85
           4.2.4. Countering an Event Proposal .......................86
           4.2.5. Delegating an Event ................................88
           4.2.6. Delegate Accepts the Meeting .......................90
           4.2.7. Delegate Declines the Meeting ......................91
           4.2.8. Forwarding an Event Request ........................92
           4.2.9. Cancel a Group Event ...............................92
           4.2.10. Removing Attendees ................................93
           4.2.11. Replacing the Organizer ...........................95
      4.3. Busy Time Examples ........................................96
           4.3.1. Publish Busy Time ..................................96
           4.3.2. Request Busy Time ..................................96
           4.3.3. Reply to a Busy Time Request .......................97
      4.4. Recurring Event and Time Zone Examples ....................98
           4.4.1. A Recurring Event Spanning Time Zones ..............98
           4.4.2. Modify a Recurring Instance ........................99
           4.4.3. Cancel an Instance ................................101
           4.4.4. Cancel a Recurring Event ..........................101
           4.4.5. Change All Future Instances .......................102
           4.4.6. Add a New Instance to a Recurring Event ...........102
           4.4.7. Add a New Series of Instances to a
                  Recurring Event ...................................103
           4.4.8. Refreshing a Recurring Event ......................104
           4.4.9. Counter an Instance of a Recurring Event ..........106
           4.4.10. Error Reply to a Request .........................107
      4.5. Group To-Do Examples .....................................108
           4.5.1. A VTODO Request ...................................109
           4.5.2. A VTODO Reply .....................................110
           4.5.3. A VTODO Request for Updated Status ................110
           4.5.4. A Reply: Percent-Complete .........................111
           4.5.5. A Reply: Completed ................................111
           4.5.6. An Updated VTODO Request ..........................112
           4.5.7. Recurring VTODOs ..................................112
      4.6. Journal Examples .........................................113
      4.7. Other Examples ...........................................114
           4.7.1. Event Refresh .....................................114
           4.7.2. Bad RECURRENCE-ID .................................114
   5. Application Protocol Fallbacks ................................116
      5.1. Partial Implementation ...................................116
           5.1.1. Event-Related Fallbacks ...........................117
           5.1.2. Free/Busy-Related Fallbacks .......................119
           5.1.3. To-Do-Related Fallbacks ...........................120
           5.1.4. Journal-Related Fallbacks .........................122
      5.2. Latency Issues ...........................................123
           5.2.1. Cancellation of an Unknown Calendar Component .....123
           5.2.2. Unexpected Reply from an Unknown Delegate .........124
      5.3. Sequence Number ..........................................124
   6. Security Considerations .......................................124
      6.1. Security Threats .........................................124
           6.1.1. Spoofing the Organizer ............................124
           6.1.2. Spoofing the Attendee .............................124
           6.1.3. Unauthorized Replacement of the Organizer .........125
           6.1.4. Eavesdropping and Data Integrity ..................125
           6.1.5. Flooding a Calendar ...............................125
           6.1.6. Unauthorized REFRESH Requests .....................125
      6.2. Recommendations ..........................................125
           6.2.1. Securing iTIP transactions ........................125
           6.2.2. Implementation Controls ...........................126
           6.2.3. Access Controls and Filtering .....................126
      6.3. Privacy Issues ...........................................126
   7. IANA Considerations ...........................................127
      7.1. Registration Template for REQUEST-STATUS Values ..........127
      7.2. Additions to iCalendar METHOD Registry ...................127
      7.3. REQUEST-STATUS Value Registry ............................129
   8. Acknowledgments ...............................................130
   9. References ....................................................131
      9.1. Normative References .....................................131
      9.2. Informative References ...................................131

   Appendix A.  Differences from RFC 2446 ...........................132
     A.1.  Changed Restrictions .....................................132
     A.2.  Deprecated Features ......................................133

1. Introduction and Overview โœจ

okay so this doc is all about how calendaring systems use iCalendar [RFC5545] objects to talk to each other ๐Ÿ“… like, scheduling events, to-dos, or daily journal entries, and also searching for when people are actually free (aka busy time info) ๐Ÿ’… It does all this in a super general way, so it never says how the messages actually get sent between systems. Future docs will handle the transport bindings, bestie ๐Ÿš€

basically it's all message-based: an originator sends stuff to one or more recipients ๐Ÿ’Œ For some message types, a recipient can reply to update their status, and can also send back transaction/request status info โœจ The originator can modify or cancel the original message (main character energy ๐Ÿ‘‘), and recipients can suggest changes to the originator too ๐Ÿซถ The protocol also defines the user roles for its transactions ๐ŸŽ€

and yes, this one obsoletes RFC 2446 ๐Ÿฆ‹ so there's a whole list of big changes in Appendix A. go check it, it's giving receipts ๐Ÿ’€

1.1. Formatting Conventions

Okay bestie, let's talk about the vocabulary first ๐Ÿ“ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. Totally essential, no cap ๐Ÿ’…

Roles get quoted strings with a capital first letter on each word. So "Organizer" is a role of a "Calendar User" (CU) inside the scheduling protocol. Iconic โœจ

Calendar components from [RFC5545] also live in capitalized quoted strings, and they all start with the letter "V" ๐Ÿฆ‹ So VEVENT is the event component, VTODO is the to-do component, and VJOURNAL is the daily journal component. Very organized, very cute.

Scheduling methods get the same treatment. REQUEST is the method for asking that a scheduling calendar component get created or modified ๐Ÿ“ฉ And REPLY is the method a recipient uses to update their status with the "Organizer" of that component. Literally the group chat of calendars ๐Ÿซถ

Properties from [RFC5545] are capitalized quoted strings followed by the word "property". So the ATTENDEE property is the iCalendar property used to convey the calendar address of a "Calendar User" ๐ŸŽ€

Property parameters defined by this spec follow the same pattern, but with the word "parameter" at the end. The VALUE parameter is the iCalendar property parameter that overrides the default data type for a property value ๐Ÿงš

Enumerated values defined here are capitalized text, either on their own or followed by the word "value" ๐ŸŒธ

And in tables, the quoted-string text drops its quotes so the table doesn't get huge ๐Ÿ’–

Implementers need to be familiar with a few other specifications too. Together with this one, they describe the Internet calendaring and scheduling standards ๐ŸŒˆ The related documents are:

  • [RFC5545] specifies the objects, data types, properties, and property parameters used in the protocols, along with the methods for representing and encoding them.
  • [iMIP] specifies an Internet email binding for iTIP.

This specification doesn't try to repeat the concepts or definitions from those other specs. Where possible, it just points straight at them with explicit references ๐Ÿ”—

1.3. Roles

Exchanges of iCalendar objects for group calendaring and scheduling happen between "Calendar Users" (CUs). CUs can take on several roles in iTIP, and here's the breakdown ๐Ÿ‘‘

+-----------+-------------------------------------------------------+
| Role      | Description                                           |
+-----------+-------------------------------------------------------+
| Organizer | The CU who initiates an exchange takes on the role of |
|           | Organizer.  For example, the CU who proposes a group  |
|           | meeting is the Organizer.                             |
|           |                                                       |
| Attendee  | CUs who are included in the scheduling message as     |
|           | possible recipients of that scheduling message.  For  |
|           | example, the CUs asked to participate in a group      |
|           | meeting by the Organizer take on the role of          |
|           | Attendee.                                             |
|           |                                                       |
| Other CU  | A CU that is not explicitly included in a scheduling  |
|           | message, i.e., not the Organizer or an Attendee.      |
+-----------+-------------------------------------------------------+

Now, a tiny plot twist ๐Ÿ™ˆ ROLE is also a descriptive parameter on the iCalendar ATTENDEE property. It's used to describe an "Attendee" with things like "chair", "required participant", or "non-required participant". It has absolutely nothing to do with the calendaring workflow, so don't mix them up, bestie ๐Ÿ’…

1.4. Methods

Here are the iTIP methods. Their usage and semantics are defined in Section 3 of this document ๐Ÿ“š

+----------------+--------------------------------------------------+
| Method         | Description                                      |
+----------------+--------------------------------------------------+
| PUBLISH        | Used to publish an iCalendar object to one or    |
|                | more "Calendar Users".  There is no              |
|                | interactivity between the publisher and any      |
|                | other "Calendar User".  An example might include |
|                | a baseball team publishing its schedule to the   |
|                | public.                                          |
|                |                                                  |
| REQUEST        | Used to schedule an iCalendar object with other  |
|                | "Calendar Users".  Requests are interactive in   |
|                | that they require the receiver to respond using  |
|                | the reply methods.  Meeting requests, busy-time  |
|                | requests, and the assignment of tasks to other   |
|                | "Calendar Users" are all examples.  Requests are |
|                | also used by the Organizer to update the status  |
|                | of an iCalendar object.                          |
|                |                                                  |
| REPLY          | A reply is used in response to a request to      |
|                | convey Attendee status to the Organizer.         |
|                | Replies are commonly used to respond to meeting  |
|                | and task requests.                               |
|                |                                                  |
| ADD            | Add one or more new instances to an existing     |
|                | recurring iCalendar object.                      |
|                |                                                  |
| CANCEL         | Cancel one or more instances of an existing      |
|                | iCalendar object.                                |
|                |                                                  |
| REFRESH        | Used by an Attendee to request the latest        |
|                | version of an iCalendar object.                  |
|                |                                                  |
| COUNTER        | Used by an Attendee to negotiate a change in an  |
|                | iCalendar object.  Examples include the request  |
|                | to change a proposed event time or change the    |
|                | due date for a task.                             |
|                |                                                  |
| DECLINECOUNTER | Used by the Organizer to decline the proposed    |
|                | counter proposal.                                |
+----------------+--------------------------------------------------+

Group scheduling in iTIP happens through the "request" and "response" methods above. This next table shows which methods each originator can send ๐ŸŽ€

+------------+------------------------------------------------------+
| Originator | Methods                                              |
+------------+------------------------------------------------------+
| Organizer  | PUBLISH, REQUEST, ADD, CANCEL, DECLINECOUNTER        |
|            |                                                      |
| Attendee   | REPLY, REFRESH, COUNTER, REQUEST (only when          |
|            | delegating)                                          |
+------------+------------------------------------------------------+

One more thing. For some calendar component types, the allowed methods are a subset of the set above ๐Ÿฆ‹ Also, apart from "VTIMEZONE" iCalendar components, only one component type is allowed in a single iTIP message. Keep it to one component type, bestie ๐Ÿ’œ

2. Interoperability Models

There are two distinct protocols that matter for interoperability: an "application protocol" and a "transport protocol" ๐ŸŒธ The application protocol defines the content of the iCalendar objects sent between sender and receiver to carry out the scheduling transactions listed above. The transport protocol defines how those iCalendar objects actually get sent between the two. This document focuses on the application protocol, and binding documents such as [iMIP] focus on the transport protocol.

The connection between sender and receiver in the diagram below refers to the application protocol. The iCalendar objects passed from sender to receiver are covered in Section 3, "Application Protocol Elements" โœจ

        +----------+                +----------+
        |          |      iTIP      |          |
        |  Sender  |<-------------->| Receiver |
        |          |                |          |
        +----------+                +----------+

Sender and receiver can take on various roles of a "Calendar User Agent" (CUA) or a "Calendar Service" (CS) in several variations of this diagram ๐Ÿงš

Here's the iTIP architecture. An application written to this specification may work with bindings for the store-and-forward transport, the real-time transport, or both. iTIP could also be bound to other transports too ๐ŸŒˆ

   +--------------------------------------------------------+
   |                     iTIP Protocol                      |
   +--------------------------------------------------------+
   |                       Transport                        |
   +  -  -  -  -  -  +  -  -  -  -  -  -  +  -  -  -  -  -  +
   | Real-Time       | Store-and-Forward  | Others          |
   +-----------------+--------------------+-----------------+

2.1. Application Protocol

In the iTIP model, an "Organizer" creates and manages an iCalendar object ๐Ÿ‘‘ The "Organizer" talks to other CUs by sending one or more of the iTIP messages listed above. "Attendees" use the "REPLY" method to share their status.

Here's the spicy bit: "Attendees" never make direct changes to the master iCalendar object ๐Ÿ™…โ€โ™€๏ธ They can use the "COUNTER" method to suggest changes to the "Organizer," but in every case, the "Organizer" has complete control over the master iCalendar object. Main character energy, but make it organizer ๐Ÿ’…

2.1.1. Scheduling State

There are two separate states that matter for iCalendar objects used in scheduling. One is the overall state of the iCalendar object, and the other is the state of each "Attendee" in that object ๐Ÿฆ‹

The state of an iCalendar object is defined by the STATUS property, and the "Organizer" controls it. There's no default value for STATUS, so the "Organizer" sets it to the right value for each iCalendar object ๐ŸŽ€

The state of a particular "Attendee" for an iCalendar object used in scheduling is defined by the PARTSTAT parameter on that "Attendee's" ATTENDEE property. When an "Organizer" issues the first iCalendar object, the "Attendee's" status is usually unknown ๐Ÿซถ So the "Organizer" marks it by setting PARTSTAT to NEEDS-ACTION. Then each "Attendee" updates their ATTENDEE property's PARTSTAT parameter to an appropriate value as part of a REPLY message sent back to the "Organizer" ๐Ÿ’–

2.1.2. Delegation ๐ŸŽ€

Okay so delegation is when an "Attendee" hands the right to attend over to another CU (or a few of them!) so they can show up on the Attendee's behalf ๐Ÿฆ‹ The "Organizer" finds out because the delegating "Attendee" tells them directly. The step-by-step details live in the REQUEST method sections for each component, so go check those if you want the full tea ๐Ÿ’…

2.1.3. Acting on Behalf of Other Calendar Users ๐ŸŒธ

In a lot of orgs, one person acts for someone else to organize and/or respond to meeting requests, and iTIP gives us two mechanisms to make that work ๐Ÿซถ

First, the "Organizer" is treated as its own special entity, separate from the "Attendees". All responses from "Attendees" flow back to the "Organizer", so it's super easy to tell apart the "Calendar User" who's organizing a meeting from the "Calendar Users" who are actually attending ๐Ÿ“ iCalendar also gives each "Attendee" a descriptive role. For example, a role of chair can be given to one or more "Attendees". The "chair" and the "Organizer" may or may not be the same "Calendar User", and this lines up perfectly with the assistant situation, where someone manages the logistics for a person who chairs the meeting. Iconic ๐Ÿ‘‘

Second, a SENT-BY parameter can be set on either the "Organizer" or "Attendee" properties. When it's there, it tells you the responding CU acted on behalf of the specified "Attendee" or "Organizer". Main character energy ๐Ÿ’–

2.1.4. Component Revisions โœจ

The SEQUENCE property is how the "Organizer" says "hey, this changed" ๐Ÿ”ฅ When the "Organizer" changes any of these properties, the sequence number MUST be incremented:

  • DTSTART
  • DTEND
  • DURATION
  • DUE
  • RRULE
  • RDATE
  • EXDATE
  • STATUS

Okay, but changes to other properties MAY also require a bump in the sequence number ๐ŸŒˆ The "Organizer" CUA MUST increment the sequence number whenever it changes properties in the calendar component that the "Organizer" thinks could jeopardize the participation status of the "Attendees". Like, if you move a meeting from one room to a totally different city, that could seriously mess with who's actually able to participate ๐Ÿ™ˆ

Depending on the METHOD, the SEQUENCE property MUST follow these rules in the context of iTIP:

  • For the PUBLISH and REQUEST methods, the SEQUENCE property value is incremented according to the rules stated above.
  • The SEQUENCE property value MUST be incremented each time the "Organizer" uses the ADD or CANCEL methods.
  • The SEQUENCE property value MUST NOT be incremented when using REPLY, REFRESH, COUNTER, DECLINECOUNTER, or when sending a delegation REQUEST.

Sometimes the "Organizer" never hears back about the final revision they sent out ๐Ÿ˜ญ In that case, they can send an update REQUEST with RSVP=TRUE set for all "Attendees" so they can collect the current responses ๐Ÿงš

Heads up: the SEQUENCE value in an "Attendee's" response might not always match the "Organizer's" revision. Implementations can choose to have the CUA tell the CU that the response is for an iCalendar object that's been revised, and then let the CU decide whether to accept it or not ๐Ÿ’…

A change in sequence number does signal a big change to something already scheduled, but "Attendee" CUAs SHOULD NOT rely solely on it to spot a significant change ๐Ÿ™…โ€โ™€๏ธ Instead, CUAs SHOULD compare the old and new versions of the calendar components, figure out exactly what changed, and then decide (maybe based on "Calendar User" preferences) whether the user actually needs a heads-up about it ๐Ÿซถ

2.1.5. Message Sequencing ๐Ÿฆ‹

CUAs that handle the iTIP application protocol must often match up a component in their calendar store with a component that shows up in an iTIP message. For example, an event might get updated with a later revision of itself. So a CUA has to correlate the version of the event already in its store with the version sent in the iTIP message ๐Ÿง  On top of that, a bunch of things can make iTIP messages arrive out of order. An "Organizer" could get a reply to an earlier revision after already getting a reply to a later one. Chaos, honestly ๐Ÿ’€

To keep interop smooth and handle messages that show up out of order, follow these rules:

  1. The primary key for referencing a particular iCalendar component is the UID property value. To reference an instance of a recurring component, the primary key is made up of the UID and the RECURRENCE-ID properties.
  2. The secondary key for referencing a component is the SEQUENCE property value. For components where the UID and RECURRENCE-ID property values are the same, the component with the highest numeric value for the SEQUENCE property obsoletes all other revisions of the component with lower values.
  3. "Attendees" send REPLY messages to the "Organizer". For replies where the UID and RECURRENCE-ID property values are the same, the value of the SEQUENCE property tells you which revision of the component the "Attendee" is replying to. The reply with the highest numeric value for the SEQUENCE property obsoletes all other replies with lower values.
  4. In situations where the UID, RECURRENCE-ID, and SEQUENCE property values all match, the DTSTAMP property is the tie-breaker. The component with the latest DTSTAMP overrides all others. Similarly, for "Attendee" responses where the UID, RECURRENCE-ID, and SEQUENCE property values match, the response with the latest DTSTAMP overrides all others ๐Ÿ†

So CUAs need to persist these component properties to process iTIP messages correctly: UID, RECURRENCE-ID, SEQUENCE, and DTSTAMP. Also, for each ATTENDEE property of a component, "Organizer" CUAs need to persist the SEQUENCE and DTSTAMP values from the "Attendee's" last response. That way, if an earlier response from an "Attendee" shows up late (say, because of a transport delay), it can be discarded properly ๐Ÿ—‘๏ธโœจ

3. Application Protocol Elements ๐Ÿ’œ

iTIP messages are text/calendar MIME entities that carry calendaring and scheduling information ๐Ÿ“… The particular type of iCalendar message is called the "method type". Each method type is identified by a METHOD property that's specified as part of the text/calendar content type. The table below shows the combinations of calendar components and method types that this specification supports ๐ŸŒธ

        +----------------+--------+-------+----------+-----------+
        |                | VEVENT | VTODO | VJOURNAL | VFREEBUSY |
        +----------------+--------+-------+----------+-----------+
        | PUBLISH        | Yes    | Yes   | Yes      | Yes       |
        | REQUEST        | Yes    | Yes   | No       | Yes       |
        | REFRESH        | Yes    | Yes   | No       | No        |
        | CANCEL         | Yes    | Yes   | Yes      | No        |
        | ADD            | Yes    | Yes   | Yes      | No        |
        | REPLY          | Yes    | Yes   | No       | Yes       |
        | COUNTER        | Yes    | Yes   | No       | No        |
        | DECLINECOUNTER | Yes    | Yes   | No       | No        |
        +----------------+--------+-------+----------+-----------+

Each method type is defined in terms of its associated components and properties. Some are required, some are optional, and some are excluded entirely. This document describes those restrictions with a simple "restriction table". The first column has the name of a component or property. Properties of the iCalendar object aren't indented, but properties of a component are ๐Ÿซง The second column (the "Presence" column) says whether a component or property should be there and, if so, how many times it can show up. The third column has extra comments to help clarify things ๐Ÿ’…

The presence column uses these values to say whether a property is required or optional, and how many times it can appear in the iCalendar object:

   +----------------+--------------------------------------------------+
   | Presence Value | Description                                      |
   +----------------+--------------------------------------------------+
   | 1              | One instance MUST be present.                    |
   | 1+             | At least one instance MUST be present.           |
   | 0              | Instances of this property MUST NOT be present.  |
   | 0+             | Multiple instances MAY be present.               |
   | 0 or 1         | Up to 1 instance of this property MAY be         |
   |                | present.                                         |
   +----------------+--------------------------------------------------+

The tables also call out IANA-PROPERTY, X-PROPERTY, IANA-COMPONENT, and X-COMPONENT to show where registered and experimental property and component extensions can show up ๐ŸŒˆ The tables don't lay out restrictions on property parameters, though. Those are defined in [RFC5545] ๐ŸŽ€

3.1. Common Component Restriction Tables ๐Ÿฆ‹

3.1.1. VCALENDAR ๐Ÿ’–

This restriction table applies to properties of the iCalendar object, meaning the properties at the outermost scope ๐Ÿ‘‘

          +-----------------------------------------------------+
          | Constraints for Properties in a VCALENDAR Component |
          +-----------------------------------------------------+

          +--------------------+----------+--------------------+
          | Component/Property | Presence | Comment            |
          +--------------------+----------+--------------------+
          | CALSCALE           | 0 or 1   |                    |
          | PRODID             | 1        |                    |
          | VERSION            | 1        | Value MUST be 2.0. |
          | IANA-PROPERTY      | 0+       |                    |
          | X-PROPERTY         | 0+       |                    |
          +--------------------+----------+--------------------+

3.1.2. VTIMEZONE ๐ŸŒ

okay so a VTIMEZONE component can be pointed at by other components through a TZID parameter on a DATETIME value type, which is giving organized ๐Ÿ’…. The table below sets the property restrictions for any VTIMEZONE component that shows up in an iTIP message. Read the Comment column closely, because it's where all the drama is ๐Ÿ‘€.

                 +--------------------------------------+
                 | Constraints for VTIMEZONE Components |
                 +--------------------------------------+

   +--------------------+----------+-----------------------------------+
   | Component/Property | Presence | Comment                           |
   +--------------------+----------+-----------------------------------+
   | VTIMEZONE          | 0+       | MUST be present if any date/time  |
   |                    |          | refers to timezone.               |
   |   DAYLIGHT         | 0+       | MUST be one or more of either     |
   |                    |          | STANDARD or DAYLIGHT.             |
   |     COMMENT        | 0+       |                                   |
   |     DTSTART        | 1        | MUST be local time format.        |
   |     RDATE          | 0+       |                                   |
   |     RRULE          | 0 or 1   |                                   |
   |     TZNAME         | 0+       |                                   |
   |     TZOFFSETFROM   | 1        |                                   |
   |     TZOFFSETTO     | 1        |                                   |
   |     IANA-PROPERTY  | 0+       |                                   |
   |     X-PROPERTY     | 0+       |                                   |
   |   LAST-MODIFIED    | 0 or 1   |                                   |
   |   STANDARD         | 0+       | MUST be one or more of either     |
   |                    |          | STANDARD or DAYLIGHT.             |
   |     COMMENT        | 0+       |                                   |
   |     DTSTART        | 1        | MUST be local time format.        |
   |     RDATE          | 0+       | If present, RRULE MUST NOT be     |
   |                    |          | present.                          |
   |     RRULE          | 0 or 1   | If present, RDATE MUST NOT be     |
   |                    |          | present.                          |
   |     TZNAME         | 0+       |                                   |
   |     TZOFFSETFROM   | 1        |                                   |
   |     TZOFFSETTO     | 1        |                                   |
   |     IANA-PROPERTY  | 0+       |                                   |
   |     X-PROPERTY     | 0+       |                                   |
   |   TZID             | 1        |                                   |
   |   TZURL            | 0 or 1   |                                   |
   |   IANA-PROPERTY    | 0+       |                                   |
   |   X-PROPERTY       | 0+       |                                   |
   +--------------------+----------+-----------------------------------+

3.1.3. VALARM โฐ

the VALARM rules are next, and they apply to any VALARM component in an iTIP message ๐Ÿ””. The table below is the vibe check for alarms, so bookmark it ๐Ÿ”–.

                   +-----------------------------------+
                   | Constraints for VALARM Components |
                   +-----------------------------------+

   +--------------------+----------+-----------------------------------+
   | Component/Property | Presence | Comment                           |
   +--------------------+----------+-----------------------------------+
   | VALARM             | 0+       |                                   |
   |   ACTION           | 1        |                                   |
   |   ATTACH           | 0+       |                                   |
   |   ATTENDEE         | 0+       |                                   |
   |   DESCRIPTION      | 0 or 1   |                                   |
   |   DURATION         | 0 or 1   | If present, REPEAT MUST be        |
   |                    |          | present.                          |
   |   REPEAT           | 0 or 1   | If present, DURATION MUST be      |
   |                    |          | present.                          |
   |   SUMMARY          | 0 or 1   |                                   |
   |   TRIGGER          | 1        |                                   |
   |   IANA-PROPERTY    | 0+       |                                   |
   |   X-PROPERTY       | 0+       |                                   |
   +--------------------+----------+-----------------------------------+

3.2. Methods for VEVENT Calendar Components ๐Ÿ“…

this section is where we get into the method types that work with the VEVENT calendar component ๐Ÿ’–. Every method has its own table that spells out the property constraints that make it that method, so you always know what you're getting into ๐Ÿงš.

here's the full lineup of methods for VEVENT. Some are the main-character requests, some are the supporting cast, and each one has its own energy โœจ.

   +----------------+--------------------------------------------------+
   | Method         | Description                                      |
   +----------------+--------------------------------------------------+
   | PUBLISH        | Post notification of an event.  Used primarily   |
   |                | as a method of advertising the existence of an   |
   |                | event.                                           |
   |                |                                                  |
   | REQUEST        | Make a request for an event.  This is an         |
   |                | explicit invitation to one or more Attendees.    |
   |                | Event requests are also used to update or change |
   |                | an existing event.  Clients that cannot handle   |
   |                | REQUEST MAY degrade the event to view it as a    |
   |                | PUBLISH.                                         |
   |                |                                                  |
   | REPLY          | Reply to an event request.  Clients may set      |
   |                | their status (PARTSTAT) to ACCEPTED, DECLINED,   |
   |                | TENTATIVE, or DELEGATED.                         |
   |                |                                                  |
   | ADD            | Add one or more instances to an existing event.  |
   |                |                                                  |
   | CANCEL         | Cancel one or more instances of an existing      |
   |                | event.                                           |
   |                |                                                  |
   | REFRESH        | A request is sent to an Organizer by an Attendee |
   |                | asking for the latest version of an event to be  |
   |                | resent to the requester.                         |
   |                |                                                  |
   | COUNTER        | Counter a REQUEST with an alternative proposal.  |
   |                | Sent by an Attendee to the Organizer.            |
   |                |                                                  |
   | DECLINECOUNTER | Decline a counter proposal.  Sent to an Attendee |
   |                | by the Organizer.                                |
   +----------------+--------------------------------------------------+

3.2.1. PUBLISH ๐Ÿ’–

okay so the "PUBLISH" method in a "VEVENT" calendar component is basically an unsolicited posting of an iCalendar object ๐Ÿ“ฎโœจ any CU is allowed to add published components to their calendar ๐ŸŽ€ the "Organizer" MUST be present in a published iCalendar component, and "Attendees" MUST NOT be present ๐Ÿ™ˆ its expected usage is encapsulating an arbitrary event as an iCalendar object ๐Ÿฆ‹ the "Organizer" may later update it (with another "PUBLISH" method), add instances to it (with an "ADD" method), or cancel it (with a "CANCEL" method) ๐Ÿ’… a previously published "VEVENT" calendar component is giving main character energy, no cap ๐Ÿ‘‘

this method type is an iCalendar object that conforms to the following property constraints ๐ŸŒธ

          +----------------------------------------------+
          | Constraints for a METHOD:PUBLISH of a VEVENT |
          +----------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST equal PUBLISH.               |
|                    |          |                                   |
| VEVENT             | 1+       |                                   |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   SEQUENCE         | 0 or 1   | MUST be present if value is       |
|                    |          | greater than 0; MAY be present if |
|                    |          | 0.                                |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0 or 1   |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | TENTATIVE/CONFIRMED/CANCELLED.    |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   ATTENDEE         | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
+--------------------+----------+-----------------------------------+

3.2.2. REQUEST ๐ŸŽ€

the "REQUEST" method in a "VEVENT" component is the multitasker of the group chat ๐Ÿงš it provides these scheduling functions:

  • Invite "Attendees" to an event. ๐Ÿ’Œ
  • Reschedule an existing event. ๐Ÿ“…
  • Response to a "REFRESH" request. ๐Ÿ”„
  • Update the details of an existing event, without rescheduling it. โœ๏ธ
  • Update the status of "Attendees" of an existing event, without rescheduling it. ๐Ÿ™‹
  • Reconfirm an existing event, without rescheduling it. ๐Ÿซถ
  • Forward a "VEVENT" to another uninvited CU. ๐Ÿ’œ
  • For an existing "VEVENT" calendar component, delegate the role of "Attendee" to another CU. ๐Ÿฆ‹
  • For an existing "VEVENT" calendar component, change the role of "Organizer" to another CU. ๐Ÿ‘‘

the "Organizer" originates the "REQUEST" ๐ŸŒˆ and the recipients are the CUs invited to the event, the "Attendees" ๐Ÿ’– "Attendees" use the "REPLY" method to convey attendance status to the "Organizer" ๐Ÿ“

the "UID" and "SEQUENCE" properties are how we tell the various uses of the "REQUEST" method apart ๐Ÿ”ฅ if the "UID" property value in the "REQUEST" is not found on the recipient's calendar, then the "REQUEST" is for a new "VEVENT" calendar component โœจ if the "UID" property value is found on the recipient's calendar, then the "REQUEST" is for a rescheduling, an update, or a reconfirmation of the "VEVENT" calendar component ๐Ÿ’…

for the "REQUEST" method, multiple "VEVENT" components in a single iCalendar object are only permitted for components with the same "UID" property ๐Ÿซถ that's giving series energy: a series of recurring events may have instance-specific information, and in this case multiple "VEVENT" components are needed to express the entire series ๐ŸŒธ

this method type is an iCalendar object that conforms to the following property constraints ๐Ÿงš

          +----------------------------------------------+
          | Constraints for a METHOD:REQUEST of a VEVENT |
          +----------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REQUEST.                  |
|                    |          |                                   |
| VEVENT             | 1+       | All components MUST have the same |
|                    |          | UID.                              |
|   ATTENDEE         | 1+       |                                   |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 0 or 1   | MUST be present if value is       |
|                    |          | greater than 0; MAY be present if |
|                    |          | 0.                                |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | TENTATIVE/CONFIRMED.              |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.2.1. Rescheduling an Event โœจ

okay so REQUEST is the method you use when you wanna reschedule an event ๐Ÿ—“๏ธ ๐Ÿ’… That means the time or recurrence intervals are changing, and maybe the location or description too. If the recipient CUA gets a REQUEST and the UID value already exists on their calendar, but the SEQUENCE (or DTSTAMP) property value in that REQUEST is greater than the value for the existing event, then the REQUEST is describing a reschedule. periodt ๐Ÿ˜ญ

3.2.2.2. Updating or Reconfirmation of an Event ๐ŸŽ€

REQUEST can also be used to update or reconfirm an event ๐Ÿซถ An update is NOT a time or recurrence change. it might not even touch the location or description. If the recipient CUA finds the UID already on the calendar and the SEQUENCE in the REQUEST matches the existing event's value, then the REQUEST is updating the event details but not rescheduling it. lowkey my favourite small detail ๐Ÿฆ‹

The update REQUEST is the right reply to a REFRESH method that an "Attendee" sends to the "Organizer" ๐ŸŒธ

The "Organizer" can also send unsolicited REQUEST methods whenever they want ๐Ÿ’– These can update the event details without rescheduling, update the PARTSTAT parameter of "Attendees", or reconfirm the event โœจ

3.2.2.3. Delegating an Event to Another CU ๐Ÿงš

okay this one is so iconic ๐Ÿ˜ญ some calendar systems let "Attendees" delegate their presence at an event to another "Calendar User", and iTIP supports that with the workflow below ๐Ÿ’… Any "Attendee" can delegate their right to take part in a calendar VEVENT to another CU. The delegate takes part in lieu of the original "Attendee", not in addition to them. The delegator MUST notify the "Organizer" of this action using the steps below ๐Ÿซถ Implementations may support or restrict delegation as they see fit. For example, some implementations may stop a delegate from delegating a REQUEST to another CU ๐Ÿ™ˆ

The "Delegator" forwards the existing REQUEST to the "Delegate" ๐Ÿฆ‹ The REQUEST MUST include an ATTENDEE property with the calendar address of the "Delegate" โœจ The "Delegator" MUST also send a REPLY method to the "Organizer" with the "Delegator's" ATTENDEE property PARTSTAT parameter value set to DELEGATED ๐Ÿ’œ On top of that, the DELEGATED-TO parameter MUST be included with the calendar address of the "Delegate". And a new ATTENDEE property for the "Delegate" MUST be included too, and it must specify the calendar user address that's set in the DELEGATED-TO parameter, same as above ๐Ÿ‘‘

In response to the request, the "Delegate" MUST send a REPLY method to the "Organizer", and optionally to the "Delegator" ๐ŸŒˆ The REPLY SHOULD include the ATTENDEE property with the DELEGATED-FROM parameter value set to the "Delegator's" calendar address ๐Ÿ“

The "Delegator" may keep getting updates to the event even though they won't be attending ๐Ÿ‘€ They do this by setting their role attribute to NON-PARTICIPANT in the REPLY to the "Organizer" ๐Ÿซถ

3.2.2.4. Changing the Organizer ๐ŸŒธ

sometimes the "Organizer" of a VEVENT can't do the job anymore and just bounces without handing the role to anyone else ๐Ÿ˜ญ When that happens, the "Attendees" of the VEVENT may use out-of-band mechanisms to talk it through and agree on a new "Organizer" ๐Ÿ’ฌ The new "Organizer" should then send out a new REQUEST with a modified version of the VEVENT, where the SEQUENCE number has been incremented and the ORGANIZER property has been changed to the new "Organizer" โœจ

3.2.2.5. Sending on Behalf of the Organizer ๐Ÿ’…

there are a bunch of situations where a "Calendar User" needs to act for the "Organizer" without actually switching roles ๐Ÿงš Like, the CU who's the "Organizer" might be sick or just unable to do the organizer stuff ๐Ÿค’ iTIP supports one CU acting on behalf of another, so using the SENT-BY parameter, a "Calendar User" could send an updated VEVENT REQUEST ๐Ÿ’œ When one CU sends on behalf of another, the "Attendee" responses still go back to the CU that's designated as "Organizer" ๐Ÿฆ‹

3.2.2.6. Forwarding to an Uninvited CU ๐ŸŽ€

an "Attendee" who was invited to a VEVENT calendar component can forward it to a new CU that wasn't previously connected to it ๐Ÿ‘€ The current "Attendee" does this by forwarding the original REQUEST method to the new CU ๐Ÿซถ The new CU can then send a REPLY to the "Organizer" of the VEVENT calendar component, and that reply includes an ATTENDEE property for the new CU ๐ŸŒˆ

The "Organizer" is the one who decides whether the new CU joins the event, and they're not obligated to do anything with a REPLY from a new (uninvited) CU ๐Ÿ‘‘ If the "Organizer" doesn't want the new CU in the event, the new ATTENDEE property doesn't get added to the VEVENT calendar component ๐Ÿ™… The "Organizer" MAY send the CU a CANCEL message to say they won't be added to the event ๐Ÿ’€ If the "Organizer" does decide to add the new CU, the new ATTENDEE property gets added to the VEVENT calendar component. The "Organizer" is also free to change any ATTENDEE property parameter from the values the new CU supplied to whatever the "Organizer" thinks is appropriate ๐Ÿ’… The "Organizer" SHOULD send the new CU a REQUEST message to let them know they've been added ๐Ÿงš

When an "Attendee" forwards a REQUEST to another CU, the forwarding "Attendee" MUST NOT make changes to the original message ๐Ÿ”’

3.2.2.7. Updating Attendee Status ๐Ÿ“

the "Organizer" of an event can also ask one or more "Attendees" for an updated status ๐Ÿ™‹โ€โ™€๏ธ The "Organizer" sends a REQUEST method to the "Attendee" and sets the ATTENDEE;RSVP=TRUE property parameter. The SEQUENCE property for the event stays at its previous value. A recipient can tell that the only change in the REQUEST is their RSVP property parameter asking for an updated status ๐Ÿฆ‹ The recipient SHOULD respond with a REPLY method that shows their current status for the REQUEST โœจ๐Ÿ’–

3.2.3. REPLY โœจ

okay so the "REPLY" method in a "VEVENT" calendar component is how you answer a "REQUEST" ๐Ÿ’… (like accepting or declining), and it's also how you reply to a delegation "REQUEST" ๐Ÿฆ‹. when it's a delegation response, the "Delegator" SHOULD put the calendar address of the "Delegate" on the "DELEGATED-TO" property parameter of the "Delegator's" "ATTENDEE" property ๐ŸŽ€. and the "Delegate" SHOULD put the calendar address of the "Delegator" on the "DELEGATED-FROM" property parameter of the "Delegate's" "ATTENDEE" property ๐Ÿซถ

"REPLY" is also used when processing a "REQUEST" fails ๐Ÿ’€. depending on what the "REQUEST-STATUS" property says, no scheduling action may have been performed, so check that first ๐Ÿ”ฅ

the "Organizer" can get a "REPLY" from a CU that wasn't in the original "REQUEST" ๐Ÿ‘€. for example, a "Delegate" might reply to an event. and sometimes a "REPLY" comes from a total stranger, aka a "Party Crasher" ๐Ÿ™ˆ. that uninvited "Attendee" can be accepted, or the "Organizer" can cancel the event for them by sending a "CANCEL" method to them. no drama, just vibes ๐Ÿ’…

an "Attendee" MAY include a message to the "Organizer" using the "COMMENT" property ๐ŸŒธ. like, if someone is tentatively accepting and wants the "Organizer" to know why, that reason can go right in the "COMMENT" property value ๐Ÿ’œ

the "Organizer" may also get a "REPLY" from one CU on behalf of another ๐Ÿงš. just like the situation above, "Attendees" can have another CU respond for them. that's what the "SENT-BY" parameter is for โœจ

the optional properties in the table below (the ones marked "0+" or "0 or 1") MUST NOT be changed from the original request ๐Ÿšซ if someone wants to change properties, the "COUNTER" message must be used ๐Ÿฆ‹

this method type is an iCalendar object that follows these property constraints, so here's the full checklist ๐Ÿ“‹

+--------------------------------------------+
| Constraints for a METHOD:REPLY of a VEVENT |
+--------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REPLY.                    |
|                    |          |                                   |
| VEVENT             | 1+       | All components MUST have the same |
|                    |          | UID.                              |
|   ATTENDEE         | 1        | MUST be the address of the        |
|                    |          | Attendee replying.                |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   UID              | 1        | MUST be the UID of the original   |
|                    |          | REQUEST.                          |
|   SEQUENCE         | 0 or 1   | If non-zero, MUST be the sequence |
|                    |          | number of the original REQUEST.   |
|                    |          | MAY be present if 0.              |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DTSTART          | 0 or 1   |                                   |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   |                                   |
|   SUMMARY          | 0 or 1   |                                   |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0 or 1   | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.4. ADD โœจ

okay so the ADD method is lowkey the cutest little shortcut ๐Ÿฆ‹ It lets the Organizer tack one or more brand new instances onto an existing VEVENT in a single iTIP message. No need to resend the whole event with every single existing instance inside it, which is what you'd have to do with REQUEST. Way less extra baggage, bestie ๐Ÿงณ๐Ÿ’–

The UID has to be the one from the event that already exists ๐Ÿ”‘ If the UID in an ADD isn't on the recipient's calendar, the recipient SHOULD send a REFRESH to the Organizer so they can grab the newest version of the VEVENT ๐Ÿ”„ And if an Attendee's implementation doesn't support ADD, it should reply with a REQUEST-STATUS value of 3.14 and ask for a REFRESH ๐Ÿ™ˆ (not me being dramatic about it, that's just the vibe ๐Ÿ’€)

When an Attendee handles an ADD message, they treat each component in it as if it were pointed to by an RDATE in the main component โœจ So the new instances get slotted right in, no drama ๐Ÿ’…

This method type is an iCalendar object that follows these property constraints ๐Ÿ‘‘

            +------------------------------------------+
            | Constraints for a METHOD:ADD of a VEVENT |
            +------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be ADD.                      |
|                    |          |                                   |
| VEVENT             | 1        |                                   |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        | MUST be greater than 0.           |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        | MUST match that of the original   |
|                    |          | event.                            |
|   ATTACH           | 0+       |                                   |
|   ATTENDEE         | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | TENTATIVE/CONFIRMED.              |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   EXDATE           | 0        |                                   |
|   RECURRENCE-ID    | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RDATE            | 0        |                                   |
|   RRULE            | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.5. CANCEL ๐Ÿšซ๐Ÿ’…

okay bestie, so the CANCEL method in a VEVENT calendar component is how the Organizer sends a cancellation notice for an event request that already exists, and it goes out to the Attendees who are affected ๐Ÿซถ. The Organizer is the one who sends it, always. โœจ

For a recurring event, you can cancel the whole thing or just some of the instances. ๐Ÿ” To cancel the complete range, the UID property value for the event MUST be specified, and a RECURRENCE-ID MUST NOT be specified in the CANCEL method. ๐Ÿ’€ If you want to cancel one single instance instead, the RECURRENCE-ID property value for the event MUST be specified in the CANCEL method. ๐Ÿฆ‹

There are two ways to cancel a run of instances of a recurring VEVENT calendar component:

a. The RECURRENCE-ID property for an instance in the run MUST be specified with the RANGE property parameter value of THISANDFUTURE, which means cancelling the specified VEVENT calendar component and every instance after it. ๐ŸŒŠ

b. Individual recurrence instances can be cancelled by specifying multiple VEVENT components, each with a RECURRENCE-ID property matching one of the instances being cancelled. ๐Ÿงฉ

The Organizer MUST send a CANCEL message to each Attendee affected by the cancellation. ๐Ÿ“ฌ You can do this with one CANCEL message for everybody, or with several messages that each cover a different subset of the affected Attendees. ๐ŸŒˆ

When a VEVENT is cancelled, the SEQUENCE property value MUST be incremented as described in Section 2.1.4. ๐Ÿ”ขโœจ

This method type is an iCalendar object that follows these property constraints:

+---------------------------------------------+
| Constraints for a METHOD:CANCEL of a VEVENT |
+---------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be CANCEL.                   |
|                    |          |                                   |
| VEVENT             | 1+       | All must have the same UID.       |
|   ATTENDEE         | 0+       | MUST include some or all          |
|                    |          | Attendees being removed from the  |
|                    |          | event.  MUST include some or all  |
|                    |          | Attendees if the entire event is  |
|                    |          | cancelled.                        |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        |                                   |
|   UID              | 1        | MUST be the UID of the original   |
|                    |          | REQUEST.                          |
|   COMMENT          | 0+       |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DTSTART          | 0 or 1   |                                   |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MUST be set to CANCELLED to       |
|                    |          | cancel the entire event.  If      |
|                    |          | uninviting specific Attendees,    |
|                    |          | then MUST NOT be included.        |
|   SUMMARY          | 0 or 1   |                                   |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.6. REFRESH ๐Ÿ”„๐ŸŽ€

so the REFRESH method in a VEVENT calendar component is how Attendees of an existing event ask the event Organizer for an updated description ๐Ÿ’–. The REFRESH method must specify the UID property of the event being updated. ๐Ÿ†” If you want one recurrence instance, you can specify the RECURRENCE-ID property matching the associated event. ๐Ÿฆ‹ The Organizer replies with the latest description and version of the event. ๐Ÿ“จโœจ

This method type is an iCalendar object that follows these property constraints:

+----------------------------------------------+
| Constraints for a METHOD:REFRESH of a VEVENT |
+----------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REFRESH.                  |
|                    |          |                                   |
| VEVENT             | 1        |                                   |
|   ATTENDEE         | 1        | MUST be the address of requester. |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   UID              | 1        | MUST be the UID associated with   |
|                    |          | original REQUEST.                 |
|   COMMENT          | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   ATTACH           | 0        |                                   |
|   CATEGORIES       | 0        |                                   |
|   CLASS            | 0        |                                   |
|   CONTACT          | 0        |                                   |
|   CREATED          | 0        |                                   |
|   DESCRIPTION      | 0        |                                   |
|   DTEND            | 0        |                                   |
|   DTSTART          | 0        |                                   |
|   DURATION         | 0        |                                   |
|   EXDATE           | 0        |                                   |
|   GEO              | 0        |                                   |
|   LAST-MODIFIED    | 0        |                                   |
|   LOCATION         | 0        |                                   |
|   PRIORITY         | 0        |                                   |
|   RDATE            | 0        |                                   |
|   RELATED-TO       | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RESOURCES        | 0        |                                   |
|   RRULE            | 0        |                                   |
|   SEQUENCE         | 0        |                                   |
|   STATUS           | 0        |                                   |
|   SUMMARY          | 0        |                                   |
|   TRANSP           | 0        |                                   |
|   URL              | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       |                                   |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.7. COUNTER โœจ

okay so the "COUNTER" method for a "VEVENT" is how an "Attendee" of an existing event says "hmm, what if we did it this other way instead? ๐Ÿซถ" They send it to the "Organizer" of that event. The counter proposal is its own iCalendar object, and its "VEVENT" has the complete description of the alternate event, not just the changes. ๐Ÿ’…

The "Organizer" can say no by sending a "DECLINECOUNTER" method back to the "Attendee". Or they can say yes by rescheduling the event as described in Section 3.2.2.1, "Rescheduling an Event" ๐Ÿ“… The "Organizer's" CUA SHOULD send a "REQUEST" message to all "Attendees" affected by any change triggered by an accepted "COUNTER". It's giving "everyone stays in the loop" energy ๐Ÿฆ‹

This method type is an iCalendar object that conforms to the following property constraints:

          +----------------------------------------------+
          | Constraints for a METHOD:COUNTER of a VEVENT |
          +----------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be COUNTER.                  |
|                    |          |                                   |
| VEVENT             | 1        |                                   |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        | MUST be the Organizer of the      |
|                    |          | original event.                   |
|   SEQUENCE         | 1        | MUST echo the original SEQUENCE   |
|                    |          | number.  MUST be present if       |
|                    |          | non-zero.  MAY be present if      |
|                    |          | zero.                             |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        | MUST be the UID associated with   |
|                    |          | the REQUEST being countered.      |
|   ATTACH           | 0+       |                                   |
|   ATTENDEE         | 0+       | Can also be used to propose other |
|                    |          | Attendees.                        |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | Value must be one of              |
|                    |          | CONFIRMED/TENATIVE/CANCELLED.     |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.2.8. DECLINECOUNTER ๐Ÿ™…โ€โ™€๏ธ

the "DECLINECOUNTER" method in a "VEVENT" is the "Organizer" politely saying "nope, not that one" ๐Ÿ’€ It's how they reject a counter proposal some "Attendee" sent in. The "Organizer" must send the "DECLINECOUNTER" message to the "Attendee" that sent the "COUNTER" method to the "Organizer". Make sure it goes back to the right person, bestie ๐ŸŽ€

This method type is an iCalendar object that conforms to the following property constraints:

         +-----------------------------------------------------+
         | Constraints for a METHOD:DECLINECOUNTER of a VEVENT |
         +-----------------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be DECLINECOUNTER.           |
|                    |          |                                   |
| VEVENT             | 1+       | All components MUST have the same |
|                    |          | UID.                              |
|   ATTENDEE         | 1+       | MUST for all Attendees.           |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        | MUST echo the original SEQUENCE   |
|                    |          | number.                           |
|   UID              | 1        | MUST echo original UID.           |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTSTART          | 0 or 1   |                                   |
|   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | TENTATIVE/CONFIRMED.              |
|   SUMMARY          | 0 or 1   | Can be null.                      |
|   TRANSP           | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.3. Methods for VFREEBUSY Components โœจ

okay so this section is where we get into the methods for the VFREEBUSY calendar component ๐Ÿ“… every method gets its own restriction table, which is basically a checklist of what's required, what's optional, and what's a total no-go ๐Ÿ’…

first things first, this doc ONLY covers sharing busy time info ๐Ÿฆ‹ if an app wants free time info, it MUST infer that from the busy time it has. no shortcuts, bestie ๐Ÿซถ

The FREEBUSY property value MAY include a list of values, separated by the COMMA character (US-ASCII decimal 44). Or, multiple busy time periods MAY be specified with multiple instances of the FREEBUSY property. Both forms MUST be supported by implementations conforming to this document. Duplicate busy time periods SHOULD NOT be specified in an iCalendar object ๐Ÿ™ˆ however, two different busy time periods MAY overlap, so that's giving flexibility ๐ŸŒˆ

FREEBUSY properties SHOULD be sorted so their values are in ascending order, based on the start time and then the end time, with the earliest periods first ๐Ÿ“ for example, today's busy time should show up after yesterday's, and the busy time for this half-hour should come after the busy time for earlier today. busy time periods can also span a day boundary, which is so iconic โœจ

here's the summary of the methods defined for the VFREEBUSY component ๐Ÿ’œ

          +---------+-------------------------------------+
          | Method  | Description                         |
          +---------+-------------------------------------+
          | PUBLISH | Publish unsolicited busy time data. |
          |         |                                     |
          | REQUEST | Request busy time data.             |
          |         |                                     |
          | REPLY   | Reply to a busy time request.       |
          +---------+-------------------------------------+

3.3.1. PUBLISH

okay the PUBLISH method in a VFREEBUSY component is used to publish busy time data ๐ŸŽ€ it can be sent from one CU to any other CU. the whole point is to send unsolicited busy time data, meaning it's NOT being sent as a reply to a REQUEST ๐Ÿ’Œ

The ORGANIZER property MUST be specified in the busy time information. Its value is the CU address of the originator of the busy time information ๐Ÿ‘‘

The busy time information inside the iCalendar object MAY be grouped into more than one VFREEBUSY component. this lets you group busy time periods by a common periodicity, like a calendar week, month, or year ๐Ÿ“† when you do that, each VFREEBUSY component MUST include the ORGANIZER, DTSTART, and DTEND properties, so it's clear where the busy time came from and what date and time interval it covers ๐Ÿ”ฅ

this method type is an iCalendar object that follows these property constraints ๐ŸŒธ

          +-------------------------------------------------+
          | Constraints for a METHOD:PUBLISH of a VFREEBUSY |
          +-------------------------------------------------+

  +--------------------+----------+-----------------------------------+
  | Component/Property | Presence | Comment                           |
  +--------------------+----------+-----------------------------------+
  | METHOD             | 1        | MUST be PUBLISH.                  |
  |                    |          |                                   |
  | VFREEBUSY          | 1+       |                                   |
  |   DTSTAMP          | 1        |                                   |
  |   DTSTART          | 1        | DateTime values must be in UTC.   |
  |   DTEND            | 1        | DateTime values must be in UTC.   |
  |   FREEBUSY         | 0+       | MUST be BUSYTIME.  Multiple       |
  |                    |          | instances are allowed.  Multiple  |
  |                    |          | instances SHOULD be sorted in     |
  |                    |          | ascending order.                  |
  |   ORGANIZER        | 1        | MUST contain the address of       |
  |                    |          | originator of busy time data.     |
  |   UID              | 1        |                                   |
  |   COMMENT          | 0+       |                                   |
  |   CONTACT          | 0 or 1   |                                   |
  |   IANA-PROPERTY    | 0+       |                                   |
  |   X-PROPERTY       | 0+       |                                   |
  |   URL              | 0 or 1   | Specifies busy time URL.          |
  |   ATTENDEE         | 0        |                                   |
  |   DURATION         | 0        |                                   |
  |   REQUEST-STATUS   | 0        |                                   |
  |                    |          |                                   |
  |   VALARM           | 0        |                                   |
  |                    |          |                                   |
  | IANA-COMPONENT     | 0+       |                                   |
  | X-COMPONENT        | 0+       |                                   |
  |                    |          |                                   |
  | VEVENT             | 0        |                                   |
  |                    |          |                                   |
  | VTODO              | 0        |                                   |
  |                    |          |                                   |
  | VJOURNAL           | 0        |                                   |
  |                    |          |                                   |
  | VTIMEZONE          | 0        |                                   |
  +--------------------+----------+-----------------------------------+

3.3.2. REQUEST

okay the REQUEST method in a VFREEBUSY component is used to ask a "Calendar User" for their busy time info ๐Ÿ™‹โ€โ™€๏ธ the request can be for busy time bounded by a specific date and time interval โญ

this message ONLY allows requests for busy time info ๐Ÿ’… it's sent from a "Calendar User" asking for the busy time of one or more intended recipients ๐Ÿงš

if the originator of the REQUEST method is NOT authorized to make a busy time request on the recipient's calendar system, then an exception message SHOULD be returned in a REPLY method. no busy time data needs to come back though ๐Ÿ’€

ngl this is the part where the vibes get a little strict: no auth, no busy time, just an exception message ๐Ÿ”ฅ

this method type is an iCalendar object that follows these property constraints ๐ŸŒˆ

          +-------------------------------------------------+
          | Constraints for a METHOD:REQUEST of a VFREEBUSY |
          +-------------------------------------------------+

  +--------------------+----------+-----------------------------------+
  | Component/Property | Presence | Comment                           |
  +--------------------+----------+-----------------------------------+
  | METHOD             | 1        | MUST be REQUEST.                  |
  |                    |          |                                   |
  | VFREEBUSY          | 1        |                                   |
  |   ATTENDEE         | 1+       | Contains the calendar user        |
  |                    |          | addresses of the "Calendar Users" |
  |                    |          | whose freebusy is being           |
  |                    |          | requested.                        |
  |   DTEND            | 1        | DateTime values must be in UTC.   |
  |   DTSTAMP          | 1        |                                   |
  |   DTSTART          | 1        | DateTime values must be in UTC.   |
  |   ORGANIZER        | 1        | MUST be the request originator's  |
  |                    |          | address.                          |
  |   UID              | 1        |                                   |
  |   COMMENT          | 0+       |                                   |
  |   CONTACT          | 0 or 1   |                                   |
  |   IANA-PROPERTY    | 0+       |                                   |
  |   X-PROPERTY       | 0+       |                                   |
  |   FREEBUSY         | 0        |                                   |
  |   DURATION         | 0        |                                   |
  |   REQUEST-STATUS   | 0        |                                   |
  |   URL              | 0        |                                   |
  |                    |          |                                   |
  |   VALARM           | 0        |                                   |
  |                    |          |                                   |
  | IANA-COMPONENT     | 0+       |                                   |
  | X-COMPONENT        | 0+       |                                   |
  |                    |          |                                   |
  | VEVENT             | 0        |                                   |
  |                    |          |                                   |
  | VTODO              | 0        |                                   |
  |                    |          |                                   |
  | VJOURNAL           | 0        |                                   |
  |                    |          |                                   |
  | VTIMEZONE          | 0        |                                   |
  +--------------------+----------+-----------------------------------+

3.3.3. REPLY ๐Ÿ’Œ

okay bestie, so the REPLY method in a VFREEBUSY calendar component is how you answer a busy time request ๐Ÿซถ It goes from the person who got the request back to whoever sent it. โœจ

REPLY can also be used to answer a REQUEST that didn't work out ๐Ÿ™ˆ Depending on the REQUEST-STATUS value, there might not be any busy time info in there at all, so don't be shocked if it's empty ๐Ÿ’€

This method type is an iCalendar object, and it follows these property constraints ๐ŸŽ€

             +-----------------------------------------------+
             | Constraints for a METHOD:REPLY of a VFREEBUSY |
             +-----------------------------------------------+

   +--------------------+----------+-----------------------------------+
   | Component/Property | Presence | Comment                           |
   +--------------------+----------+-----------------------------------+
   | METHOD             | 1        | MUST be REPLY.                    |
   |                    |          |                                   |
   | VFREEBUSY          | 1        |                                   |
   |   ATTENDEE         | 1        | MUST be the address of the        |
   |                    |          | Attendee replying.                |
   |   DTSTAMP          | 1        |                                   |
   |   DTEND            | 1        | DateTime values must be in UTC.   |
   |   DTSTART          | 1        | DateTime values must be in UTC.   |
   |   FREEBUSY         | 0+       | MUST be BUSYTIME.  Multiple       |
   |                    |          | instances are allowed.  Multiple  |
   |                    |          | instances SHOULD be sorted in     |
   |                    |          | ascending order.                  |
   |   ORGANIZER        | 1        | MUST be the request originator's  |
   |                    |          | address.                          |
   |   UID              | 1        | MUST be the UID of the original   |
   |                    |          | REQUEST.                          |
   |   COMMENT          | 0+       |                                   |
   |   CONTACT          | 0 or 1   |                                   |
   |   REQUEST-STATUS   | 0+       |                                   |
   |   URL              | 0 or 1   | Specifies busy time URL.          |
   |   IANA-PROPERTY    | 0+       |                                   |
   |   X-PROPERTY       | 0+       |                                   |
   |   DURATION         | 0        |                                   |
   |   SEQUENCE         | 0        |                                   |
   |                    |          |                                   |
   |   VALARM           | 0        |                                   |
   |                    |          |                                   |
   | IANA-COMPONENT     | 0+       |                                   |
   | X-COMPONENT        | 0+       |                                   |
   |                    |          |                                   |
   | VEVENT             | 0        |                                   |
   |                    |          |                                   |
   | VTODO              | 0        |                                   |
   |                    |          |                                   |
   | VJOURNAL           | 0        |                                   |
   |                    |          |                                   |
   | VTIMEZONE          | 0        |                                   |
   +--------------------+----------+-----------------------------------+

3.4. Methods for VTODO Components ๐ŸŒธ

this section is all about the methods that work with the VTODO calendar component ๐Ÿ“‹ Each method gets its own restriction table that spells out the property constraints that define it, so you always know exactly what's expected โœจ

Here's the quick summary of every method defined for VTODO ๐Ÿ‘€

   +----------------+--------------------------------------------------+
   | Method         | Description                                      |
   +----------------+--------------------------------------------------+
   | PUBLISH        | Post notification of a VTODO.  Used primarily as |
   |                | a method of advertising the existence of a       |
   |                | VTODO.                                           |
   |                |                                                  |
   | REQUEST        | Assign a VTODO.  This is an explicit assignment  |
   |                | to one or more Calendar Users.  The REQUEST      |
   |                | method is also used to update or change an       |
   |                | existing VTODO.  Clients that cannot handle      |
   |                | REQUEST MAY degrade the method to treat it as a  |
   |                | PUBLISH.                                         |
   |                |                                                  |
   | REPLY          | Reply to a VTODO request.  Attendees MAY set     |
   |                | PARTSTAT to ACCEPTED, DECLINED, TENTATIVE,       |
   |                | DELEGATED, PARTIAL, and COMPLETED.               |
   |                |                                                  |
   | ADD            | Add one or more instances to an existing to-do.  |
   |                |                                                  |
   | CANCEL         | Cancel one or more instances of an existing      |
   |                | to-do.                                           |
   |                |                                                  |
   | REFRESH        | A request sent to a VTODO Organizer asking for   |
   |                | the latest version of a VTODO.                   |
   |                |                                                  |
   | COUNTER        | Counter a REQUEST with an alternative proposal.  |
   |                |                                                  |
   | DECLINECOUNTER | Decline a counter proposal by an Attendee.       |
   +----------------+--------------------------------------------------+

3.4.1. PUBLISH ๐Ÿ“ฃ

the PUBLISH method in a VTODO calendar component doesn't have any response attached ๐Ÿ™…โ€โ™€๏ธ It's basically just posting an iCalendar object that people can add to their calendar ๐Ÿ’– It MUST have an "Organizer". It MUST NOT have "Attendees" ๐Ÿšซ The main idea is to wrap up an arbitrary VTODO calendar component as an iCalendar object ๐ŸŽ After that, the Organizer MAY update the published VTODO with another PUBLISH method, add instances with an ADD method, or cancel it with a CANCEL method ๐Ÿฆ‹

This method type is an iCalendar object, and it follows these property constraints ๐Ÿ’…

              +---------------------------------------------+
              | Constraints for a METHOD:PUBLISH of a VTODO |
              +---------------------------------------------+

   +--------------------+----------+-----------------------------------+
   | Component/Property | Presence | Comment                           |
   +--------------------+----------+-----------------------------------+
   | METHOD             | 1        | MUST be PUBLISH.                  |
   |                    |          |                                   |
   | VTODO              | 1+       |                                   |
   |   DTSTAMP          | 1        |                                   |
   |   DTSTART          | 1        |                                   |
   |   ORGANIZER        | 1        |                                   |
   |   PRIORITY         | 1        |                                   |
   |   SEQUENCE         | 0 or 1   | MUST be present if value is       |
   |                    |          | greater than 0; MAY be present if |
   |                    |          | 0.                                |
   |   SUMMARY          | 1        | Can be null.                      |
   |   UID              | 1        |                                   |
   |   ATTACH           | 0+       |                                   |
   |   CATEGORIES       | 0+       |                                   |
   |   CLASS            | 0 or 1   |                                   |
   |   COMMENT          | 0+       |                                   |
   |   COMPLETED        | 0 or 1   |                                   |
   |   CONTACT          | 0+       |                                   |
   |   CREATED          | 0 or 1   |                                   |
   |   DESCRIPTION      | 0 or 1   | Can be null.                      |
   |   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
   |                    |          | present.                          |
   |   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
   |                    |          | present.                          |
   |   EXDATE           | 0+       |                                   |
   |   GEO              | 0 or 1   |                                   |
   |   LAST-MODIFIED    | 0 or 1   |                                   |
   |   LOCATION         | 0 or 1   |                                   |
   |   PERCENT-COMPLETE | 0 or 1   |                                   |
   |   RDATE            | 0+       |                                   |
   |   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
   |                    |          | of a recurring calendar           |
   |                    |          | component.  Otherwise, it MUST    |
   |                    |          | NOT be present.                   |
   |   RELATED-TO       | 0+       |                                   |
   |   RESOURCES        | 0+       |                                   |
   |   RRULE            | 0 or 1   |                                   |
   |   STATUS           | 0 or 1   | MAY be one of                     |
   |                    |          | COMPLETED/NEEDS-ACTION/           |
   |                    |          | IN-PROCESS/CANCELLED.             |
   |   URL              | 0 or 1   |                                   |
   |   IANA-PROPERTY    | 0+       |                                   |
   |   X-PROPERTY       | 0+       |                                   |
   |   ATTENDEE         | 0        |                                   |
   |   REQUEST-STATUS   | 0        |                                   |
   |                    |          |                                   |
   |   VALARM           | 0+       |                                   |
   |                    |          |                                   |
   | VTIMEZONE          | 0+       | MUST be present if any date/time  |
   |                    |          | refers to a timezone.             |
   |                    |          |                                   |
   | IANA-COMPONENT     | 0+       |                                   |
   | X-COMPONENT        | 0+       |                                   |
   |                    |          |                                   |
   | VFREEBUSY          | 0        |                                   |
   |                    |          |                                   |
   | VEVENT             | 0        |                                   |
   |                    |          |                                   |
   | VJOURNAL           | 0        |                                   |
   +--------------------+----------+-----------------------------------+

3.4.2. REQUEST ๐Ÿ’–

okay so the "REQUEST" method in a "VTODO" calendar component is basically the queen of to-do scheduling ๐Ÿ‘‘ it does a bunch of stuff:

  • Assign a to-do to one or more "Calendar Users" ๐ŸŽ€
  • Reschedule an existing to-do ๐Ÿ—“๏ธ
  • Update the details of an existing to-do, without rescheduling it โœ๏ธ
  • Update the completion status of "Attendees" of an existing to-do, without rescheduling it โœ…
  • Reconfirm an existing to-do, without rescheduling it ๐Ÿซถ
  • Delegate/reassign an existing to-do to another "Calendar User" ๐Ÿฆ‹

the assigned "Calendar Users" get identified in the "VTODO" calendar component by individual ATTENDEE;ROLE=REQ-PARTICIPANT property value sequences. so cute, right? ๐Ÿฅน

typically the one sending a "REQUEST" is the "Organizer" of the to-do, and the one receiving it is the "Calendar User" who got assigned the to-do. then the "Attendee" uses the "REPLY" method to tell the "Organizer" of the "REQUEST" whether they're in and where they're at with completion status ๐Ÿ’…

the UID, SEQUENCE, and DTSTAMP properties are the dream team that tells all the different "REQUEST" uses apart ๐Ÿงš if the UID value in the "REQUEST" isn't on the recipient's calendar, then it's a brand new to-do โœจ if the UID value is already on their calendar, then the "REQUEST" is a rescheduling, an update, or a reconfirmation of that "VTODO" calendar object. iconic sorting energy ๐Ÿ™ˆ

โš ๏ธ bestie, if the "Organizer" of the "REQUEST" method isn't authorized to make a to-do request on the "Attendee's" calendar system, then an exception gets returned in the REQUEST-STATUS property of a later "REPLY" method. but no scheduling action happens. no drama, just a polite no ๐Ÿ™…โ€โ™€๏ธ

for the "REQUEST" method, you can have multiple "VTODO" components in one iCalendar object, but only if they all have the same UID property. so a series of recurring events can carry instance-specific info, and you need multiple "VTODO" components to express the whole series. it's giving organized ๐Ÿ“š๐ŸŒธ

this method type is an iCalendar object that follows these property constraints ๐Ÿ‘‡

+---------------------------------------------+
| Constraints for a METHOD:REQUEST of a VTODO |
+---------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REQUEST.                  |
|                    |          |                                   |
| VTODO              | 1+       | All components must have the same |
|                    |          | UID.                              |
|   ATTENDEE         | 1+       |                                   |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   PRIORITY         | 1        |                                   |
|   SEQUENCE         | 0 or 1   | MUST be present if value is       |
|                    |          | greater than 0; MAY be present if |
|                    |          | 0.                                |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null                       |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | COMPLETED/NEEDS-ACTION/           |
|                    |          | IN-PROCESS.                       |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.2.1. REQUEST for Rescheduling a VTODO ๐Ÿ—“๏ธ

the "REQUEST" method can be used to reschedule a "VTODO" calendar component ๐Ÿฅฐ

rescheduling a "VTODO" calendar component means changing the existing one in terms of its start or due time, its recurrence intervals, and maybe its description too. so if the recipient CUA of a "REQUEST" method finds that the UID value is already on the calendar, but the SEQUENCE value in the "REQUEST" is higher than the one for the existing "VTODO", then the "REQUEST" is describing a rescheduling of that "VTODO" calendar component. main character glow-up moment โœจ

3.4.2.2. REQUEST for Update or Reconfirmation of a VTODO โœ๏ธ

the "REQUEST" method can also update or reconfirm a "VTODO" calendar component ๐Ÿซถ reconfirmation is basically just an update to the "Attendee" completion status or the overall "VTODO" calendar component status.

an update to an existing "VTODO" calendar component doesn't touch the start or due time, the recurrence intervals, or (generally) the description. so if the recipient CUA of a "REQUEST" method finds that the UID value is already on the calendar, and the SEQUENCE value in the "REQUEST" is the same as the value for the existing event, then the "REQUEST" is describing an update of the "VTODO" calendar component details, but not a rescheduling ๐Ÿ’…

the update "REQUEST" is the right answer to a "REFRESH" method sent from an "Attendee" to the "Organizer" of a "VTODO" calendar component ๐Ÿ”

unsolicited "REQUEST" methods MAY be sent by the "Organizer" of a "VTODO" calendar component ๐ŸŽ they're used to update the details of the "VTODO" (without rescheduling it or updating the completion status of "Attendees"), or to reconfirm the "VTODO" calendar component itself. no surprises, just vibes ๐ŸŒˆ

3.4.2.3. REQUEST for Delegating a VTODO ๐Ÿฆ‹

the "REQUEST" method is also how you delegate or reassign ownership of a "VTODO" calendar component to another "Calendar User" ๐Ÿงšโ€โ™€๏ธ for example, it can delegate an "Attendee's" role (like "chair" or "participant") for a "VTODO" calendar component. the "REQUEST" is sent by one of the "Attendees" of an existing "VTODO" calendar component to some other person.

for this part, the "Attendee" doing the delegating is called the "Delegator" ๐Ÿซก and the "Attendee" getting the delegation request is called the "Delegate" ๐Ÿ’œ

okay, the rules for delegation are a whole thing, so read carefully bestie ๐Ÿ‘€

  • The "Delegator" of a "VTODO" calendar component MUST forward the existing "REQUEST" method for that "VTODO" calendar component to the "Delegate". ๐Ÿ“จ
  • The "VTODO" calendar component description MUST include the "Delegator's" up-to-date "VTODO" calendar component definition. ๐Ÿ—’๏ธ
  • The "REQUEST" method MUST also include an ATTENDEE property with the calendar address of the "Delegate". ๐Ÿ“ฌ
  • The "Delegator" MUST also send a "REPLY" method back to the "Organizer", with the "Delegator's" Attendee property PARTSTAT parameter value set to DELEGATED. ๐Ÿ’Œ
  • On top of that, the DELEGATED-TO parameter MUST be included, with the calendar address of the "Delegate". ๐Ÿ“

the response to the delegation "REQUEST" gets sent from the "Delegate" to the "Organizer", and optionally to the "Delegator" ๐ŸŒธ the "REPLY" from the "Delegate" SHOULD include the ATTENDEE property with their own calendar address, and the DELEGATED-FROM parameter with the "Delegator's" calendar address. so many little addresses, so much love ๐Ÿ’–

one more: the delegation "REQUEST" MUST assign a value for the RSVP property parameter that's associated with the "Delegator's" Attendee property, matching the "Delegate's" ATTENDEE property. for example, if the "Delegator's" ATTENDEE property says RSVP=TRUE, then the "Delegate's" ATTENDEE property MUST specify RSVP=TRUE too ๐Ÿ“ no switching it up mid-delegation, periodt ๐Ÿ™…โ€โ™€๏ธโœจ

3.4.2.4. REQUEST Forwarded to an Uninvited Calendar User โœจ

okay so an "Attendee" who's been assigned a "VTODO" can pass that "VTODO" along to a brand new CU who was never part of it ๐Ÿ’Œ the current "Attendee" does this by forwarding the original "REQUEST" method to the new CU. then the new CU can send a "REPLY" back to the "Organizer" of the "VTODO", and that reply includes an ATTENDEE property for them ๐Ÿฆ‹

but here's the tea: the "Organizer" is the one who gets the final say on whether the new CU actually joins the to-do ๐Ÿ‘‘ they don't have to do anything with a "REPLY" from someone uninvited. if they don't want the new CU in, the new ATTENDEE property just doesn't get added to the "VTODO" calendar component. the "Organizer" MAY send that CU a "CANCEL" message to say "nope, you're not in this one" ๐Ÿ™ˆ

if the "Organizer" does say yes, the new ATTENDEE property gets added to the "VTODO" calendar component. and the "Organizer" is totally free to tweak any ATTENDEE property parameter from what the new CU sent, switching it to whatever the "Organizer" thinks fits best ๐Ÿ’… once they're in, the "Organizer" SHOULD send the new "Attendee" a "REQUEST" message so they know they've been added ๐ŸŽ€

and the forwarding "Attendee" MUST NOT make any changes to the original message while passing it along. no edits, no glitter, nothing! ๐Ÿซถ

3.4.2.5. REQUEST Updated Attendee Status ๐ŸŒธ

an "Organizer" of a "VTODO" can ask one or more "Attendees" for an updated status โœจ they send a "REQUEST" method with the ATTENDEE;RSVP=TRUE property sequence. the SEQUENCE property for the "VTODO" stays exactly the same as before ๐Ÿงš

so how does the recipient know what's going on? they look at the "REQUEST" and see that the only thing that changed is their RSVP property parameter asking for an updated status. that's the whole signal ๐Ÿ’œ the recipient SHOULD then answer with a "REPLY" method that shows their current status for that "REQUEST" ๐Ÿ“

3.4.3. REPLY ๐Ÿ’–

the "REPLY" method in a "VTODO" calendar component is how you answer a request (like accepting or declining it) or reply to a delegation request ๐ŸŒˆ it's also how an "Attendee" updates their completion status, which is lowkey so useful ๐ŸŽ€

when a "REPLY" is a delegation response, the "Delegator" MUST put the calendar address of the "Delegate" in the "DELEGATED-TO" parameter of the "Delegator's" ATTENDEE property ๐Ÿซถ and the "Delegate" MUST put the calendar address of the "Delegator" in the "DELEGATED-FROM" parameter of the "Delegate's" ATTENDEE property. it's a whole chain of receipts, bestie ๐Ÿงพ

the "REPLY" method MAY also be used to respond to a "VTODO" calendar component "REQUEST" that didn't go through ๐Ÿ’… depending on the REQUEST-STATUS value, it's possible that no scheduling action got performed at all ๐Ÿ™ˆ

the "Organizer" of a "VTODO" calendar component MAY get a "REPLY" from a "Calendar User" who wasn't in the original "REQUEST" ๐Ÿฆ‹ for example, a "REPLY" MAY come from a "Delegate" of the "VTODO" calendar component. and a "REPLY" MAY also come from an unknown "Calendar User" who got forwarded the "REQUEST" by an original "Attendee" of the "VTODO" calendar component ๐Ÿ‘€ that uninvited "Attendee" MAY be accepted, or the "Organizer" MAY cancel the "VTODO" calendar component for them by sending a "CANCEL" method. main character energy from the organizer, honestly ๐Ÿ‘‘

this method type is an iCalendar object that follows these property constraints. here's the whole checklist, no cap ๐Ÿ’•

            +-------------------------------------------+
            | Constraints for a METHOD:REPLY of a VTODO |
            +-------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REPLY.                    |
|                    |          |                                   |
| VTODO              | 1+       | All components MUST have the same |
|                    |          | UID.                              |
|   ATTENDEE         | 1        | MUST be the address of the        |
|                    |          | Attendee replying.                |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   UID              | 1        | MUST be the UID of the original   |
|                    |          | REQUEST.                          |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTSTART          | 0 or 1   |                                   |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   SEQUENCE         | 0 or 1   | MUST be the sequence number of    |
|                    |          | the original REQUEST if greater   |
|                    |          | than 0.  MAY be present if 0.     |
|   STATUS           | 0 or 1   |                                   |
|   SUMMARY          | 0 or 1   | Can be null.                      |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0 or 1   | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.4. ADD ๐Ÿฆ‹

okay so the "ADD" method is giving efficiency ๐Ÿ’… It lets the Organizer tack one or more brand-new instances onto an existing VTODO with a single iTIP message, so they don't have to resend the whole VTODO with all the existing instance data like they would with REQUEST ๐Ÿ™ˆ

The UID has to be the one belonging to the existing to-do. ngl, if the UID in an ADD isn't on the recipient's calendar, the recipient SHOULD send a REFRESH to the Organizer so they can get the latest version of the VTODO ๐Ÿ”ฅ And if an Attendee's implementation doesn't support ADD, it should respond with a REQUEST-STATUS value of 3.14 and ask for a REFRESH ๐Ÿ’€

When an Attendee handles an ADD, they treat each component in the message as if it were referenced via an RDATE in the main component ๐Ÿงš

The SEQUENCE property value gets incremented since the sequence of to-dos has changed ๐ŸŒธ

This method type is an iCalendar object that conforms to the following property constraints:

            +-----------------------------------------+
            | Constraints for a METHOD:ADD of a VTODO |
            +-----------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be ADD.                      |
|                    |          |                                   |
| VTODO              | 1        |                                   |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   PRIORITY         | 1        |                                   |
|   SEQUENCE         | 1        | MUST be greater than 0.           |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        | MUST match that of the original   |
|                    |          | to-do.                            |
|   ATTACH           | 0+       |                                   |
|   ATTENDEE         | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTSTART          | 0 or 1   |                                   |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | COMPLETED/NEEDS-ACTION/           |
|                    |          | IN-PROCESS.                       |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   EXDATE           | 0        |                                   |
|   RECURRENCE-ID    | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RDATE            | 0        |                                   |
|   RRULE            | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VJOURNAL           | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.5. CANCEL ๐Ÿ’…

okay bestie, the CANCEL method in a VTODO calendar component is how the Organizer tells the affected Attendees that an existing to-do request is cancelled ๐Ÿ’€ it's sent by the Organizer of the VTODO to its Attendees, and it's giving very clear "we're not doing this anymore" energy ๐Ÿ™…โ€โ™€๏ธ

for a recurring VTODO, you can cancel the whole thing or just some of the instances ๐Ÿ” to cancel the complete range, the UID value for the VTODO MUST be specified, and a RECURRENCE-ID MUST NOT be specified in the CANCEL method. to cancel one specific instance, the RECURRENCE-ID value for the VTODO MUST be specified in the CANCEL method. so the rule is basically: no RECURRENCE-ID means the whole series, RECURRENCE-ID means one instance ๐ŸŽ€

there are two ways to cancel a sequence of instances ๐ŸŒธ

  1. the RECURRENCE-ID for an instance in the sequence MUST be specified with the RANGE property parameter value of THISANDFUTURE, which cancels the specified VTODO and all instances after it โœจ
  2. individual recurrence instances may be cancelled by specifying multiple VTODO components, each with a RECURRENCE-ID property that matches one of the instances to be cancelled ๐Ÿงš
the Organizer MUST send a CANCEL message to each Attendee affected by the cancellation ๐Ÿšจ it can be one CANCEL message for everyone, or several messages each covering a different subset of the affected Attendees. either way, nobody gets left out!!

when a VTODO is cancelled, the SEQUENCE value MUST be incremented as described in Section 2.1.4 ๐Ÿ“ˆ that's how everyone knows this is the newest version of the story ๐Ÿ‘‘

this method type is an iCalendar object that has to follow these property constraints (no skipping, it's the rules, babe):

           +--------------------------------------------+
           | Constraints for a METHOD:CANCEL of a VTODO |
           +--------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be CANCEL.                   |
|                    |          |                                   |
| VTODO              | 1+       |                                   |
|   ATTENDEE         | 0+       | MUST include some or all          |
|                    |          | Attendees being removed from the  |
|                    |          | to-do.  MUST include some or all  |
|                    |          | Attendees if the entire to-do is  |
|                    |          | cancelled.                        |
|   UID              | 1        | MUST echo original UID.           |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTSTART          | 0 or 1   |                                   |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MUST be set to CANCELLED to       |
|                    |          | cancel the entire VTODO.  If      |
|                    |          | removing specific Attendees, then |
|                    |          | MUST NOT be included.             |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0 or 1   | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.6. REFRESH ๐Ÿฆ‹

the REFRESH method in a VTODO calendar component is how Attendees of an existing VTODO ask the Organizer for an updated description ๐Ÿ™‹โ€โ™€๏ธ it's basically the "hey, what's the latest tea on this?" message ๐Ÿต the Organizer MAY use this method to ask the Attendees for an updated status too, so it goes both ways ๐Ÿซถ and the REFRESH method MUST specify the UID property that matches the VTODO needing the update.

if you want a refresh for one instance of a recurring VTODO, specify the RECURRENCE-ID property that matches the associated VTODO ๐Ÿ” the Organizer then responds with the latest description and rendition of the VTODO. most of the time that response is a REQUEST, but if the VTODO has been cancelled, the Organizer MUST send a CANCEL instead ๐Ÿ’€ this method is meant to make machine processing of update requests for a VTODO easier to handle ๐Ÿค–โœจ

this method type is an iCalendar object that has to follow these property constraints (again, rules are rules, no cap):

          +---------------------------------------------+
          | Constraints for a METHOD:REFRESH of a VTODO |
          +---------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be REFRESH.                  |
|                    |          |                                   |
| VTODO              | 1        |                                   |
|   ATTENDEE         | 1        |                                   |
|   DTSTAMP          | 1        |                                   |
|   UID              | 1        | MUST echo original UID.           |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   ATTACH           | 0        |                                   |
|   CATEGORIES       | 0        |                                   |
|   CLASS            | 0        |                                   |
|   COMMENT          | 0        |                                   |
|   COMPLETED        | 0        |                                   |
|   CONTACT          | 0        |                                   |
|   CREATED          | 0        |                                   |
|   DESCRIPTION      | 0        |                                   |
|   DTSTART          | 0        |                                   |
|   DUE              | 0        |                                   |
|   DURATION         | 0        |                                   |
|   EXDATE           | 0        |                                   |
|   GEO              | 0        |                                   |
|   LAST-MODIFIED    | 0        |                                   |
|   LOCATION         | 0        |                                   |
|   ORGANIZER        | 0        |                                   |
|   PERCENT-COMPLETE | 0        |                                   |
|   PRIORITY         | 0        |                                   |
|   RDATE            | 0        |                                   |
|   RELATED-TO       | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RESOURCES        | 0        |                                   |
|   RRULE            | 0        |                                   |
|   SEQUENCE         | 0        |                                   |
|   STATUS           | 0        |                                   |
|   URL              | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       |                                   |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.7. COUNTER ๐Ÿ”„

okay so the "COUNTER" method in a "VTODO" calendar component is how an "Attendee" of an existing "VTODO" slides into the "Organizer's" DMs with a counter proposal for that to-do ๐Ÿ’…

the counter proposal is an iCalendar object made of a "VTODO" calendar component that fully describes the alternate "VTODO". it's giving complete package ๐ŸŽ€

the "Organizer" can say no by sending the "Attendee" a "DECLINECOUNTER" method ๐Ÿ’€. or they can say yes by rescheduling the to-do, as described in Section 3.4.2.1, "REQUEST for Rescheduling a To-Do" ๐Ÿฆ‹. and if they say yes, the "Organizer's" CUA SHOULD send a "REQUEST" message to all "Attendees" affected by any change triggered by an accepted "COUNTER" โœจ. that's the glow-up everyone needs to see ๐Ÿ’–

this method type is an iCalendar object that follows these property constraints:

           +---------------------------------------------+
           | Constraints for a METHOD:COUNTER of a VTODO |
           +---------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be COUNTER.                  |
|                    |          |                                   |
| VTODO              | 1        |                                   |
|   ATTENDEE         | 1+       |                                   |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   PRIORITY         | 1        |                                   |
|   SUMMARY          | 1        | Can be null.                      |
|   UID              | 1        |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   | Can be null.                      |
|   DTSTART          | 0 or 1   |                                   |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   SEQUENCE         | 0 or 1   | MUST echo the original SEQUENCE   |
|                    |          | number.  MUST be present if       |
|                    |          | non-zero.  MAY be present if      |
|                    |          | zero.                             |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | COMPLETED/NEEDS-ACTION/           |
|                    |          | IN-PROCESS/CANCELLED.             |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0 or 1   | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.4.8. DECLINECOUNTER ๐Ÿ™…โ€โ™€๏ธ

the "DECLINECOUNTER" method in a "VTODO" calendar component is used by an "Organizer" of the "VTODO" calendar component to turn down a counter proposal from one of the "Attendees" ๐Ÿ’…. the "Organizer" sends the message to the "Attendee" who sent the "COUNTER" method to the "Organizer" ๐Ÿ’Œ. bye bye, counter ๐Ÿ‘‹

this method type is an iCalendar object that follows these property constraints:

      +----------------------------------------------------+
      | Constraints for a METHOD:DECLINECOUNTER of a VTODO |
      +----------------------------------------------------+
+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be DECLINECOUNTER.           |
|                    |          |                                   |
| VTODO              | 1        |                                   |
|   ATTENDEE         | 1+       | MUST for all ATTENDEEs.           |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        | MUST echo the original SEQUENCE   |
|                    |          | number.                           |
|   UID              | 1        | MUST echo original UID.           |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   COMPLETED        | 0 or 1   |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTSTART          | 0 or 1   |                                   |
|   DUE              | 0 or 1   | If present, DURATION MUST NOT be  |
|                    |          | present.                          |
|   DURATION         | 0 or 1   | If present, DUE MUST NOT be       |
|                    |          | present.                          |
|   EXDATE           | 0+       |                                   |
|   GEO              | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   LOCATION         | 0 or 1   |                                   |
|   PERCENT-COMPLETE | 0 or 1   |                                   |
|   PRIORITY         | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   REQUEST-STATUS   | 0+       |                                   |
|   RESOURCES        | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | COMPLETED/NEEDS-ACTION/           |
|                    |          | IN-PROCESS.                       |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.5. Methods for VJOURNAL Components ๐Ÿ““

this section defines the property set for the methods that apply to the "VJOURNAL" calendar component ๐ŸŒธ

here's the quick summary of the methods defined for the "VJOURNAL" calendar component. it's the little cheat sheet we all need ๐Ÿงš

+---------+---------------------------------------------------------+
| Method  | Description                                             |
+---------+---------------------------------------------------------+
| PUBLISH | Post a journal entry.  Used primarily as a method of    |
|         | advertising the existence of a journal entry.           |
|         |                                                         |
| ADD     | Add one or more instances to an existing journal entry. |
|         |                                                         |
| CANCEL  | Cancel one or more instances of an existing journal     |
|         | entry.                                                  |
+---------+---------------------------------------------------------+

3.5.1. PUBLISH โœจ

okay so PUBLISH for a VJOURNAL is giving "here's a post, no reply needed" ๐Ÿ’… there's no associated response, it's just a posting of an iCalendar object that can get added to someone's calendar ๐Ÿ““ it MUST have an "Organizer" ๐Ÿซถ and it MUST NOT have "Attendees" because it's a solo journal moment ๐Ÿ™ˆ the expected vibe is wrapping up any random journal entry as an iCalendar object ๐Ÿฆ‹ and the "Organizer" MAY later update it with another PUBLISH, or cancel it with a CANCEL method ๐ŸŒธ

here's the property checklist for a METHOD:PUBLISH of a VJOURNAL ๐Ÿ‘‘

+------------------------------------------------+
| Constraints for a METHOD:PUBLISH of a VJOURNAL |
+------------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be PUBLISH.                  |
|                    |          |                                   |
| VJOURNAL           | 1+       |                                   |
|   DESCRIPTION      | 1        | Can be null.                      |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   UID              | 1        |                                   |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   EXDATE           | 0+       |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   SEQUENCE         | 0 or 1   | MUST be present if non-zero.  MAY |
|                    |          | be present if zero.               |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | DRAFT/FINAL/CANCELLED.            |
|   SUMMARY          | 0 or 1   | Can be null.                      |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   ATTENDEE         | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.5.2. ADD ๐ŸŽ€

the "ADD" method is the Organizer's way of tossing one or more brand-new instances into an existing "VJOURNAL" with a single iTIP message ๐Ÿ’– no need to resend the whole "VJOURNAL" with all the old instance data, which is what you'd have to do with "REQUEST" ๐Ÿซ  so much more efficient bestie ๐Ÿงš

the "UID" has to be the one from the existing journal entry ๐Ÿ”‘ and if the "UID" in the "ADD" isn't on the recipient's calendar, the recipient MAY treat the "ADD" as a "PUBLISH" ๐ŸŒˆ

when an "Attendee" handles an "ADD" message, they treat each component in it as if it were referenced by an "RDATE" in the main component โœจ and there's no response going back to the "Organizer", so it's a quiet little drop ๐Ÿคซ๐Ÿฆ‹

here's the property checklist for a METHOD:ADD of a VJOURNAL ๐Ÿ’…

+--------------------------------------------+
| Constraints for a METHOD:ADD of a VJOURNAL |
+--------------------------------------------+

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be ADD.                      |
|                    |          |                                   |
| VJOURNAL           | 1        |                                   |
|   DESCRIPTION      | 1        | Can be null.                      |
|   DTSTAMP          | 1        |                                   |
|   DTSTART          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        | MUST be greater than 0.           |
|   UID              | 1        | MUST match that of the original   |
|                    |          | journal.                          |
|   ATTACH           | 0+       |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   RELATED-TO       | 0+       |                                   |
|   STATUS           | 0 or 1   | MAY be one of                     |
|                    |          | DRAFT/FINAL/CANCELLED.            |
|   SUMMARY          | 0 or 1   | Can be null.                      |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   ATTENDEE         | 0        |                                   |
|   EXDATE           | 0        |                                   |
|   RECURRENCE-ID    | 0        |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|   RDATE            | 0        |                                   |
|   RRULE            | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0+       |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0 or 1   | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.5.3. CANCEL โœจ

Okay so the "CANCEL" method in a "VJOURNAL" calendar component is how you send a cancellation notice for a journal entry that already exists ๐Ÿซถ The "Organizer" of that journal entry is the one who sends it. If the entry is recurring, you can cancel the whole thing or just some of its instances, so let's break it down ๐Ÿ’…

To cancel the complete range of a recurring journal entry, the "UID" property value for the journal entry MUST be specified and a "RECURRENCE-ID" property MUST NOT be specified in the "CANCEL" method. But if you only want to cancel one individual instance, the "RECURRENCE-ID" property value for the journal entry MUST be specified in the "CANCEL" method ๐ŸŽ€

There are two ways to cancel a whole sequence of instances of a recurring "VJOURNAL" calendar component:

  • a. The "RECURRENCE-ID" property for an instance in the sequence MUST be specified with the "RANGE" property parameter value of "THISANDFUTURE", which means cancelling the specified "VJOURNAL" calendar component and all the instances after it ๐Ÿฆ‹
  • b. Individual recurrence instances may be cancelled by specifying multiple "VJOURNAL" components, each with a "RECURRENCE-ID" property matching one of the instances you want gone ๐ŸŒธ

When a "VJOURNAL" is cancelled, the "SEQUENCE" property value MUST be incremented as described in Section 2.1.4. Don't skip this one, it's a big deal ๐Ÿ˜ญ

This method type is an iCalendar object that follows the property constraints below. Here's the little box for it ๐Ÿ“ฆ

+-----------------------------------------------+
| Constraints for a METHOD:CANCEL of a VJOURNAL |
+-----------------------------------------------+

And here's the full table, so you know exactly what's allowed and what's not ๐Ÿ‘‘

+--------------------+----------+-----------------------------------+
| Component/Property | Presence | Comment                           |
+--------------------+----------+-----------------------------------+
| METHOD             | 1        | MUST be CANCEL.                   |
|                    |          |                                   |
| VJOURNAL           | 1+       | All MUST have the same UID.       |
|   DTSTAMP          | 1        |                                   |
|   ORGANIZER        | 1        |                                   |
|   SEQUENCE         | 1        |                                   |
|   UID              | 1        | MUST be the UID of the original   |
|                    |          | REQUEST.                          |
|   ATTACH           | 0+       |                                   |
|   ATTENDEE         | 0        |                                   |
|   CATEGORIES       | 0+       |                                   |
|   CLASS            | 0 or 1   |                                   |
|   COMMENT          | 0+       |                                   |
|   CONTACT          | 0+       |                                   |
|   CREATED          | 0 or 1   |                                   |
|   DESCRIPTION      | 0 or 1   |                                   |
|   DTSTART          | 0 or 1   |                                   |
|   EXDATE           | 0+       |                                   |
|   LAST-MODIFIED    | 0 or 1   |                                   |
|   RDATE            | 0+       |                                   |
|   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
|                    |          | of a recurring calendar           |
|                    |          | component.  Otherwise, it MUST    |
|                    |          | NOT be present.                   |
|   RELATED-TO       | 0+       |                                   |
|   RRULE            | 0 or 1   |                                   |
|   STATUS           | 0 or 1   | MAY be present; MUST be CANCELLED |
|                    |          | if present.                       |
|   SUMMARY          | 0 or 1   |                                   |
|   URL              | 0 or 1   |                                   |
|   IANA-PROPERTY    | 0+       |                                   |
|   X-PROPERTY       | 0+       |                                   |
|   REQUEST-STATUS   | 0        |                                   |
|                    |          |                                   |
|   VALARM           | 0        |                                   |
|                    |          |                                   |
| VTIMEZONE          | 0+       | MUST be present if any date/time  |
|                    |          | refers to a timezone.             |
|                    |          |                                   |
| IANA-COMPONENT     | 0+       |                                   |
| X-COMPONENT        | 0+       |                                   |
|                    |          |                                   |
| VEVENT             | 0        |                                   |
|                    |          |                                   |
| VFREEBUSY          | 0        |                                   |
|                    |          |                                   |
| VTODO              | 0        |                                   |
+--------------------+----------+-----------------------------------+

3.6. Status Replies ๐ŸŒˆ

Okay, this part is all about the "REQUEST-STATUS" property, which is how you tell people what happened to a "REPLY", "COUNTER", or "DECLINECOUNTER" iTIP message โœจ The codes in the table below SHOULD be used. And if the "REQUEST-STATUS" property isn't there at all, a status code of "2.0" (success) MUST be assumed. So no property, no drama ๐Ÿ’–

This spec adds a brand new IANA registry for "REQUEST-STATUS" property values, which is defined in Section 7. It also includes a new registration template for spelling out the specific parts of a "REQUEST-STATUS" property value ๐Ÿงš Extra codes MAY be used too, as long as they get registered through the process in Section 8.2.1 of [RFC5545].

Multiple "REQUEST-STATUS" properties are allowed in the iCalendar components of the right iTIP messages ๐Ÿ“ But when there are several, these rules apply:

  1. Within any one component, the "top-level" numeric value of the "short return status code" MUST be the same for all "REQUEST-STATUS" properties. Basically, no mixing a 2.xx and a 5.xx in the same component, bestie ๐Ÿ™ˆ
  2. Across all components in the iTIP message, the following applies:
    • A. If any one component would have a 5.xx code, then either all components MUST have a code in that range, or "REQUEST-STATUS" MUST NOT be present in the other components if a 5.xx code is not appropriate for those components.
    • B. Otherwise, if any one component would have a 3.xx code, then either all components MUST have a code in that range, or "REQUEST-STATUS" MUST NOT be present in the other components if a 3.xx code is not appropriate for those components.
    • C. 2.xx and 4.xx codes can be used in different components, provided that each component follows the restriction in (1) above.

Here are the "REQUEST-STATUS" codes that are defined. Any "Offending Data" MAY be specified in the "REQUEST-STATUS" value as the extdata field ๐Ÿ’…

3.6.1. Status Code 2.0 ๐Ÿ’–

  • Status Code: 2.0
  • Status Description: Success.
  • Status Exception Data: None.
  • Description: iTIP operation succeeded.

Just the classic "everything went perfectly" code ๐ŸŒŸ

3.6.2. Status Code 2.1 ๐Ÿฆ‹

  • Status Code: 2.1
  • Status Description: Success, but fallback taken on one or more property values.
  • Status Exception Data: Property name and value MAY be specified.
  • Description: iTIP operation succeeded with fallback on one or more property values.

It worked, but something had to fall back, so the property name and value can be named ๐Ÿซถ

3.6.3. Status Code 2.2 ๐ŸŒธ

  • Status Code: 2.2
  • Status Description: Success; invalid property ignored.
  • Status Exception Data: Property name MAY be specified.
  • Description: iTIP operation succeeded but a property was ignored.

Succeeded, but one property got ghosted because it was invalid ๐Ÿ‘ป

3.6.4. Status Code 2.3 ๐ŸŽ€

  • Status Code: 2.3
  • Status Description: Success; invalid property parameter ignored.
  • Status Exception Data: Property parameter name and value MAY be specified.
  • Description: iTIP operation succeeded but a property parameter was ignored because it was invalid.

Same vibe, except this time it's the parameter that got left on read ๐Ÿ™ƒ

3.6.5. Status Code 2.4 ๐Ÿงš

  • Status Code: 2.4
  • Status Description: Success; unknown, non-standard property ignored.
  • Status Exception Data: Non-standard property name MAY be specified.
  • Description: iTIP operation succeeded but a property parameter was ignored because it was unknown.

When something unknown and non-standard shows up, it gets ignored, but the operation still counts as a win ๐ŸŒˆ

3.6.6. Status Code 2.5 ๐Ÿ“

  • Status Code: 2.5
  • Status Description: Success; unknown, non-standard property value ignored.
  • Status Exception Data: Property and non-standard value MAY be specified.
  • Description: iTIP operation succeeded but a property was ignored because its value was unknown.

Same energy, but this time the value is the mystery ๐Ÿ”ฎ

3.6.7. Status Code 2.6 ๐ŸŒ™

  • Status Code: 2.6
  • Status Description: Success; invalid calendar component ignored.
  • Status Exception Data: Calendar component sentinel (e.g., BEGIN:ALARM) MAY be specified.
  • Description: iTIP operation succeeded but a component was ignored because it was invalid.

Okay so a whole component got benched because it was invalid, but the rest went through ๐Ÿฅฒ

3.6.8. Status Code 2.7 ๐Ÿฆข

  • Status Code: 2.7
  • Status Description: Success; request forwarded to Calendar User.
  • Status Exception Data: Original and forwarded calendar user addresses MAY be specified.
  • Description: iTIP operation succeeded, and the request was forwarded to another Calendar User.

The request got passed along to someone else, and yes, you can name both addresses ๐Ÿ’Œ

3.6.9. Status Code 2.8 ๐ŸŒท

  • Status Code: 2.8
  • Status Description: Success; repeating event ignored. Scheduled as a single component.
  • Status Exception Data: RRULE or RDATE property name and value MAY be specified.
  • Description: iTIP operation succeeded but a repeating event was truncated to a single instance.

The repeating event got cut down to one instance. Still a success, just a little shorter ๐Ÿซง

3.6.10. Status Code 2.9 ๐ŸŽˆ

  • Status Code: 2.9
  • Status Description: Success; truncated end date time to date boundary.
  • Status Exception Data: DTEND property value MAY be specified.
  • Description: iTIP operation succeeded but the end time was truncated to a date boundary.

The end time got rounded down to the date boundary. Succeeded, just a bit neater โœ‚๏ธ

3.6.11. Status Code 2.10 ๐Ÿชฉ

  • Status Code: 2.10
  • Status Description: Success; repeating VTODO ignored. Scheduled as a single VTODO.
  • Status Exception Data: RRULE or RDATE property name and value MAY be specified.
  • Description: iTIP operation succeeded but a repeating to-do was truncated to a single instance.

Same story as 2.8, but for a to-do instead of an event โœ…

3.6.12. Status Code 2.11 โญ

  • Status Code: 2.11
  • Status Description: Success; unbounded RRULE clipped at some finite number of instances.
  • Status Exception Data: RRULE property name and value MAY be specified. Number of instances MAY also be specified.
  • Description: iTIP operation succeeded but an unbounded repeating object was clipped to a finite number of instances.

An endless repeat got clipped to a set number of instances. Still a success, just with a finish line now ๐Ÿ

3.6.13. Status Code 3.0 ๐Ÿฅ€

  • Status Code: 3.0
  • Status Description: Invalid property name.
  • Status Exception Data: Property name MAY be specified.
  • Description: iTIP operation failed because of an invalid property name.

Okay this one is a 3-series code, so it's a failure ๐Ÿ’€ The property name was invalid, so the operation didn't go through.

3.6.14. Status Code 3.1 ๐Ÿ–ค

  • Status Code: 3.1
  • Status Description: Invalid property value.
  • Status Exception Data: Property name and value MAY be specified.
  • Description: iTIP operation failed because of an invalid property value.

Same failure energy as 3.0, but this time the value is what's wrong ๐Ÿ˜ญ The property name and value can be named so the sender knows exactly what went sideways.

3.6.15. Status Code 3.2 โœจ

  • Status Code: 3.2
  • Status Description: Invalid property parameter.
  • Status Exception Data: Property parameter name and value MAY be specified.

Description: okay so the iTIP operation flopped bc one of the property parameters was invalid ๐Ÿ’€ not the vibe.

3.6.16. Status Code 3.3 ๐Ÿ’…

  • Status Code: 3.3
  • Status Description: Invalid property parameter value.
  • Status Exception Data: Property parameter name and value MAY be specified.

Description: the iTIP operation failed bc a property parameter had an invalid value (the name was fine, the value was giving chaos) ๐Ÿ™ˆ

3.6.17. Status Code 3.4 ๐Ÿฆ‹

  • Status Code: 3.4
  • Status Description: Invalid calendar component sequence.
  • Status Exception Data: Calendar component sentinel MAY be specified (e.g., BEGIN:VTIMEZONE).

Description: iTIP operation failed bc a component was invalid. The sentinel, like BEGIN:VTIMEZONE, is allowed to be included if you want to flag it ๐ŸŒธ

3.6.18. Status Code 3.5 ๐ŸŽ€

  • Status Code: 3.5
  • Status Description: Invalid date or time.
  • Status Exception Data: Date/time value(s) MAY be specified.

Description: the iTIP operation failed bc a date or time property was not it. Main character energy, but make it valid ๐Ÿ•ฐ๏ธ

3.6.19. Status Code 3.6 ๐ŸŒˆ

  • Status Code: 3.6
  • Status Description: Invalid rule.
  • Status Exception Data: RRULE property value MAY be specified.

Description: the iTIP operation failed bc a rule property was invalid. The RRULE value is allowed to be included in the error, so the sender can see what went wrong ๐Ÿ”

3.6.20. Status Code 3.7 ๐Ÿงš

  • Status Code: 3.7
  • Status Description: Invalid Calendar User.
  • Status Exception Data: ATTENDEE property value MAY be specified.

Description: the iTIP operation failed bc the ATTENDEE property was invalid. The ATTENDEE value is allowed to be included so everyone knows who got flagged ๐Ÿ‘€

3.6.21. Status Code 3.8 ๐Ÿ‘‘

  • Status Code: 3.8
  • Status Description: No authority.
  • Status Exception Data: METHOD and ATTENDEE property values MAY be specified.

Description: the iTIP operation failed bc an Attendee doesn't have the right privileges for it. Not their lane, bestie ๐Ÿšซ The METHOD and ATTENDEE values are allowed to be included in the error.

3.6.22. Status Code 3.9 ๐Ÿ“

  • Status Code: 3.9
  • Status Description: Unsupported version.
  • Status Exception Data: VERSION property name and value MAY be specified.

Description: the iTIP operation failed bc the calendar data's version isn't supported. Old version, new vibes, no match โœจ

3.6.23. Status Code 3.10 ๐Ÿ’œ

  • Status Code: 3.10
  • Status Description: Request entity too large.
  • Status Exception Data: None.

Description: the iTIP operation failed bc the calendar data was too big. Girl, that's a lot of data ๐Ÿ˜ญ

3.6.24. Status Code 3.11 ๐ŸŒธ

  • Status Code: 3.11
  • Status Description: Required component or property missing.
  • Status Exception Data: Component or property name MAY be specified.

Description: the iTIP operation failed bc the calendar data didn't have a required property or component. Something important was left out, periodt ๐Ÿ“ฆ

3.6.25. Status Code 3.12 ๐Ÿ”ฎ

  • Status Code: 3.12
  • Status Description: Unknown component or property found.
  • Status Exception Data: Component or property name MAY be specified.

Description: the iTIP operation failed bc the calendar data had an unknown property or component in it. Who invited that? ๐Ÿคจ

3.6.26. Status Code 3.13 ๐Ÿฆ„

  • Status Code: 3.13
  • Status Description: Unsupported component or property found.
  • Status Exception Data: Component or property name MAY be specified.

Description: the iTIP operation failed bc the calendar data had an unsupported property or component. Known, but not supported here, so no ๐Ÿ™…โ€โ™€๏ธ

3.6.27. Status Code 3.14 ๐ŸŽˆ

  • Status Code: 3.14
  • Status Description: Unsupported capability.
  • Status Exception Data: METHOD or action MAY be specified.

Description: the iTIP operation failed bc the operation just isn't supported. The METHOD or action is allowed to be included in the error ๐Ÿ› ๏ธ

3.6.28. Status Code 4.0 ๐Ÿ”ฅ

  • Status Code: 4.0
  • Status Description: Event conflict. Date/time is busy.
  • Status Exception Data: DTSTART and DTEND property names and values MAY be specified.

Description: the iTIP operation failed bc the event overlapped the date and time of another event. Double-booked, no cap ๐Ÿ“… The DTSTART and DTEND names and values are allowed to be included.

3.6.29. Status Code 5.0 ๐ŸŒท

  • Status Code: 5.0
  • Status Description: Request not supported.
  • Status Exception Data: METHOD property value MAY be specified.

Description: the iTIP operation failed bc the operation isn't supported. Same energy as 3.14, but this one is about the request itself. The METHOD value is allowed to be included ๐Ÿซถ

3.6.30. Status Code 5.1 ๐ŸŒ™

  • Status Code: 5.1
  • Status Description: Service unavailable.
  • Status Exception Data: ATTENDEE property value MAY be specified.

Description: the iTIP operation failed bc scheduling isn't active right now. The service is just offline rn ๐Ÿ˜ด The ATTENDEE value is allowed to be included.

3.6.31. Status Code 5.2 ๐Ÿช„

  • Status Code: 5.2
  • Status Description: Invalid calendar service.
  • Status Exception Data: ATTENDEE property value MAY be specified.

Description: the iTIP operation failed bc there's no scheduling capability there at all. Wrong service, bestie ๐Ÿšช The ATTENDEE value is allowed to be included.

3.6.32. Status Code 5.3 ๐Ÿ’–

  • Status Code: 5.3
  • Status Description: No scheduling support for user.
  • Status Exception Data: ATTENDEE property value MAY be specified.

Description: the iTIP operation failed bc scheduling isn't turned on for an Attendee. They're just not enabled yet ๐Ÿ”’ The ATTENDEE value is allowed to be included.

3.7. Implementation Considerations ๐Ÿง 

3.7.1. Working With Recurrence Instances

okay so iCalendar has a recurrence grammar for repeating events, and it's honestly so smart bc you can represent a whole bunch of events in just one object. But the catch is that individual meeting instances still need to be referenced. Like, an Attendee might decline just the third instance of a recurring Friday event. Or the Organizer might change the time or location for only one instance of that recurring event ๐Ÿ“†

Since implementations can choose to store recurring events either as one single event object or as a collection of separate, related event objects, the protocol is designed so that each recurring instance can be both referenced and versioned ๐Ÿฆ‹ So implementations that want to keep per-instance properties (like the PARTSTAT parameter on the ATTENDEE property) can totally do that. But the protocol doesn't require per-instance recognition unless that instance itself has to be renegotiated.

Here are the scenarios for recurrence instance referencing. To keep things simple, a change to an event counts as a "trigger property." That means a property with a real effect on the meeting itself, like start time, location, due date (for VTODO calendar components), and possibly description โœจ

"Organizer"-initiated actions:

  • deletes or changes a single instance of a recurring event
  • makes changes that affect all future instances
  • makes changes that affect all previous instances
  • deletes or modifies a previously changed instance

"Attendee"-initiated actions:

  • changes status for a particular recurrence instance
  • sends a COUNTER for a particular recurrence instance

An instance of a recurring event gets a unique identifier, the RECURRENCE-ID property, when that instance is renegotiated. Renegotiation might be needed when a big change happens to the event or to-do, like changing the start time, end time, due date, or location ๐Ÿ”„ The "Organizer" can point to a specific recurrence instance using RECURRENCE-ID, and its value is the date/time of that instance. If the "Organizer" wants to change the DTSTART, then the original, unmodified DTSTART value of the instance gets used as the RECURRENCE-ID value, and the new DTSTART and DTEND values show the change ๐Ÿ’…

3.7.2. Attendee Property Considerations

The ORGANIZER property is required on published events, to-dos, and journal entries, and there are two big reasons. First, only the Organizer is allowed to update and redistribute an event or to-do component. So the ORGANIZER property MUST be present in the event, to-do, or journal entry component so the CUA has a basis for authorizing an update ๐Ÿ” Second, it's smart to give anyone who gets a published component a point of contact, just in case something goes wrong ๐Ÿซถ

Email addresses that stand for groups of "Calendar Users" could be specified as a mailto: URI [RFC2368] calendar user address. Sending email to one of those addresses means the email goes out to multiple recipients. Such an address can be used as the value of an ATTENDEE property. So it's possible that the recipient of a REQUEST doesn't show up explicitly in the list ๐Ÿ‘ฏ

It's recommended that the general approach to finding a "Calendar User" in an Attendee list goes like this:

  1. Search for the "Calendar User" in the Attendee list where CUTYPE=INDIVIDUAL
  2. If (1) fails, look for Attendees where CUTYPE=GROUP or CUTYPE=UNKNOWN. The CUA then figures out whether the "Calendar User" is a member of one of those groups. If so, the REPLY method sent to the Organizer MUST contain a new ATTENDEE property in which:
    • the TYPE property parameter is set to INDIVIDUAL
    • the MEMBER property parameter is set to the name of the group
  3. If (2) fails, the CUA MAY ignore or accept the request, whatever the "Calendar User" wants ๐Ÿคทโ€โ™€๏ธ

3.7.3. Extension Tokens

To make iCalendar objects extensible, you can use new components, properties, or property parameters. There are two types of extensions defined by [RFC5545]: IANA-registered tokens (iana-token) and experimental use tokens (x-name) ๐Ÿงฉ A client SHOULD save "iana-token's" and MAY use them in replies. A client MAY save "x-name's" and MAY use them in replies. When delegating or forwarding messages to other CUs, a client SHOULD include "iana-token's" and "x-names's" ๐Ÿ’œ

4. Examples ๐ŸŽ€

4.1. Published Event Examples

Okay, so publishing is basically a one-way transfer of event info. The people getting published events just add the event to their calendar, and no reply is expected ๐Ÿ“ฎ Individual A publishes an event, and Individual B reads it and adds it to their calendar. Events get published in a bunch of ways, like embedding the event as an object in a web page, emailing it to a distribution list, or posting it to a newsgroup ๐ŸŒ

The table below shows the sequence of events between the publisher and the people consuming the published event:

+----------------+-----------------------+--------------------------+
| Action         | Organizer             | Receiver                 |
+----------------+-----------------------+--------------------------+
| Publish an     | "A" sends or posts a  | "B" reads a published    |
| event          | PUBLISH message.      | event.                   |
|                |                       |                          |
| Publish an     | "A" sends or posts a  | "B" reads the updated    |
| updated event  | PUBLISH message.      | event.                   |
|                |                       |                          |
| Cancel a       | "A" sends or posts a  | "B" reads the canceled   |
| published      | CANCEL message.       | event publication.       |
| event          |                       |                          |
+----------------+-----------------------+--------------------------+

4.1.1. A Minimal Published Event ๐ŸŒŸ

The iCalendar object below describes a single event that begins on July 1, 1997 at 20:00 UTC. This event has the minimum set of properties for a PUBLISH of a VEVENT calendar component. It's giving clean and simple ๐Ÿฅฐ

BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
DTSTART:19970701T200000Z
DTSTAMP:19970611T190000Z
SUMMARY:ST. PAUL SAINTS -VS- DULUTH-SUPERIOR DUKES
UID:0981234-1234234-23@example.com
END:VEVENT
END:VCALENDAR

4.1.2. Changing a Published Event ๐Ÿฆ‹

okay so this one is an update to the event from Section 4.1.1, bestie ๐ŸŽ€ the time got moved, an end time got added, and the sequence number got bumped. no cap, it's giving "new version, who dis" ๐Ÿ’…

BEGIN:VCALENDAR
METHOD:PUBLISH
VERSION:2.0
PRODID:-//Example/ExampleCalendarClient//EN
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
DTSTAMP:19970612T190000Z
DTSTART:19970701T210000Z
DTEND:19970701T230000Z
SEQUENCE:1
UID:0981234-1234234-23@example.com
SUMMARY:ST. PAUL SAINTS -VS- DULUTH-SUPERIOR DUKES
END:VEVENT
END:VCALENDAR

The UID property is how the client knows which event is which ๐Ÿ” and the SEQUENCE property tells everyone this is a change to that event โœจ The event with a matching UID and sequence number 0 is superseded by this one, so it's a total glow-up ๐Ÿ‘‘

The SEQUENCE property is the reliable way to tell different versions of the same event apart ๐Ÿงš Every time an event gets published, its sequence number goes up. If a client gets an event with sequence number 5 and it already has sequence number 2 of that same event, the event SHOULD be updated ๐Ÿ’– but if the client gets sequence number 2 and already has sequence number 5 of the same event, the event MUST NOT be updated ๐Ÿ™…โ€โ™€๏ธ the older version does not get to win, periodt ๐Ÿ’…

4.1.3. Canceling a Published Event ๐Ÿฅ€

this one cancels the event from Section 4.1.1 ๐Ÿ˜ญ it cancels the event with SEQUENCE values of 0, 1, and 2, so the whole run is over ๐Ÿ’€

BEGIN:VCALENDAR
METHOD:CANCEL
VERSION:2.0
PRODID:-//Example/ExampleCalendarClient//EN
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
COMMENT:DUKES forfeit the game
SEQUENCE:2
UID:0981234-1234234-23@example.com
DTSTAMP:19970613T190000Z
END:VEVENT
END:VCALENDAR

4.1.4. A Rich Published Event ๐Ÿ’Ž

this is the same event as Section 4.1.1, but with the full glam treatment ๐Ÿ‘‘ way more detail, and it's honestly so iconic ๐ŸŒˆ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:PUBLISH
SCALE:GREGORIAN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America-Chicago
TZURL:http://example.com/tz/America-Chicago
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0500
TZOFFSETTO:-0600
TZNAME:CST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0600
TZOFFSETTO:-0500
TZNAME:CDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTACH:http://www.example.com/
CATEGORIES:SPORTS EVENT,ENTERTAINMENT
CLASS:PRIVATE
DESCRIPTION:MIDWAY STADIUM\n
 Big time game.  MUST see.\n
 Expected duration:2 hours\n
DTEND;TZID=America-Chicago:19970701T180000
DTSTART;TZID=America-Chicago:19970702T160000
DTSTAMP:19970614T190000Z
STATUS:CONFIRMED
LOCATION;VALUE=URI:http://stadium.example.com/
PRIORITY:2
RESOURCES:SCOREBOARD
SEQUENCE:3
SUMMARY:ST. PAUL SAINTS -VS- DULUTH-SUPERIOR DUKES
UID:0981234-1234234-23@example.com
RELATED-TO:0981234-1234234-14@example.com
BEGIN:VALARM
TRIGGER:-PT2H
ACTION:DISPLAY
DESCRIPTION:You should be leaving for the game now.
END:VALARM
BEGIN:VALARM
TRIGGER:-PT30M
ACTION:AUDIO
END:VALARM
END:VEVENT
END:VCALENDAR

The RELATED-TO field holds the UID of a related calendar event ๐Ÿ”— and the SEQUENCE value of 3 means this event supersedes versions 0, 1, and 2 โœจ main character energy, literally ๐ŸŽ€

4.1.5. Anniversaries or Events Attached to Entire Days ๐ŸŽ‰

this example shows how the VALUE parameter ties a VEVENT to a whole day instead of a specific time ๐Ÿ“… perfect for birthdays and holidays ๐Ÿ‡ซ๐Ÿ‡ท

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:PUBLISH
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
DTSTAMP:19970614T190000Z
UID:0981234-1234234-23@example.com
DTSTART;VALUE=DATE:19970714
RRULE:FREQ=YEARLY;INTERVAL=1
SUMMARY: Bastille Day
END:VEVENT
END:VCALENDAR

4.2. Group Event Examples ๐Ÿซถ

okay bestie, group events are different from published events because they have "Attendees," and there's actual back-and-forth between the "Attendees" and the "Organizer" ๐Ÿ—ฃ๏ธ here, individual "A" requests a meeting with "A", "B", "C", and "D" ๐Ÿ“จ "B" confirms, "C" declines, and "D" tentatively confirms ๐Ÿ™ˆ the table below shows the message flow, and "A", the CU scheduling the meeting, is the "Organizer" ๐Ÿ“‹

+--------------+-----------------------+----------------------------+
| Action       | "Organizer"           | Attendee                   |
+--------------+-----------------------+----------------------------+
| Initiate a   | "A" sends a REQUEST   |                            |
| meeting      | message to "B", "C",  |                            |
| request      | and "D".              |                            |
|              |                       |                            |
| Accept the   |                       | "B" sends a REPLY message  |
| meeting      |                       | to "A" with its ATTENDEE   |
| request      |                       | PARTSTAT parameter set to  |
|              |                       | ACCEPTED.                  |
|              |                       |                            |
| Decline the  |                       | "C" sends a REPLY message  |
| meeting      |                       | to "A" with its ATTENDEE   |
| request      |                       | PARTSTAT parameter set to  |
|              |                       | DECLINED.                  |
|              |                       |                            |
| Tentatively  |                       | "D" sends a REPLY message  |
| accept the   |                       | to "A" with its ATTENDEE   |
| meeting      |                       | PARTSTAT parameter set to  |
| request      |                       | TENTATIVE.                 |
|              |                       |                            |
| Confirm      | "A" sends a REQUEST   |                            |
| meeting      | message to "B" and    |                            |
| status with  | "D" with updated      |                            |
| Attendees    | information.          |                            |
+--------------+-----------------------+----------------------------+

4.2.1. A Group Event Request ๐Ÿ“ฌ

here "A" sends a meeting request to "B", "C", and "D" โœจ "E" gets a copy too, but "E" isn't expected to attend and doesn't need to reply ๐Ÿ‘€ this shows how CUAs might do an "FYI"-type feature, which is lowkey genius ๐Ÿง  check out the ROLE parameter: its default is "REQ-PARTICIPANT" and it doesn't need to be written out ๐Ÿ’… here we use "NON-PARTICIPANT" to say "E" is a non-attending CU ๐Ÿ™ˆ the parameter isn't needed on the other "Attendees" since "PARTICIPANT" is already the default ๐Ÿ’–

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=A:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;CN=B:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;CN=C:mailto:c@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;CN=Hal:mailto:d@example.com
ATTENDEE;RSVP=FALSE;CUTYPE=ROOM:conf_big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:mailto:e@example.com
DTSTAMP:19970611T190000Z
DTSTART:19970701T200000Z
DTEND:19970701T2100000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.2.2. Reply to a Group Event Request ๐Ÿ’Œ

"Attendee" "B" says yes to the meeting ๐Ÿฅณ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VEVENT
ATTENDEE;PARTSTAT=ACCEPTED:mailto:b@example.com
ORGANIZER:mailto:a@example.com
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
REQUEST-STATUS:2.0;Success
DTSTAMP:19970612T190000Z
END:VEVENT
END:VCALENDAR

"B" could have declined or said tentative by setting the "ATTENDEE" "PARTSTAT" parameter to "DECLINED" or "TENTATIVE", respectively ๐Ÿ™ƒ also, REQUEST-STATUS is not required in successful transactions, so you can chill on that one โœจ

4.2.3. Update an Event ๐Ÿ”„

the event got moved to a different time โฐ the UID property stays the same and the SEQUENCE gets bumped to 1, and together those two signal the update ๐Ÿฆ‹

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:c@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;CN=Hal:mailto:d@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE;
 CUTYPE=ROOM:mailto:conf@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:mailto:e@example.com
DTSTART:19970701T180000Z
DTEND:19970701T190000Z
SUMMARY:Phone Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
DTSTAMP:19970613T190000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.2.4. Countering an Event Proposal ๐ŸŽ€

okay so "A" sends a REQUEST to "B" and "C" ๐Ÿ’Œ. then "B" is like "ummm can we do a different time and place??" and makes a counter proposal to "A" to change the time and location ๐Ÿ™ˆ

"A" sends the following REQUEST ๐Ÿ“จ:

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:c@example.com
DTSTART:19970701T190000Z
DTEND:19970701T200000Z
SUMMARY:Discuss the Merits of the election results
LOCATION:Green Conference Room
UID:calsrv.example.com-873970198738777a@example.com
SEQUENCE:0
DTSTAMP:19970611T190000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

"B" sends COUNTER to "A" ๐Ÿฆ‹, asking for changes to the time and place. "B" uses the COMMENT property to explain the reasoning behind the change ๐Ÿซถ. Note that the SEQUENCE property is not incremented on a COUNTER ๐Ÿค“

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:COUNTER
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:c@example.com
DTSTART:19970701T160000Z
DTEND:19970701T170000Z
DTSTAMP:19970612T190000Z
SUMMARY:Discuss the Merits of the election results
LOCATION:Blue Conference Room
COMMENT:This time works much better and I think the big conference
 room is too big
UID:calsrv.example.com-873970198738777a@example.com
SEQUENCE:0
END:VEVENT
END:VCALENDAR

"A" accepts the changes from "B" ๐Ÿฅฐ. To accept a counter proposal, the "Organizer" sends a new event REQUEST with an incremented sequence number โœ…

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:c@example.com
DTSTAMP:19970613T190000Z
DTSTART:19970701T160000Z
DTEND:19970701T170000Z
SUMMARY:Discuss the Merits of the election results - changed to
 meet B's schedule
LOCATION:Blue Conference Room
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Or, plot twist: "A" rejects "B's" counter proposal ๐Ÿ™…โ€โ™€๏ธ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:DECLINECOUNTER
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
COMMENT:Sorry, I cannot change this meeting time
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
DTSTAMP:19970614T190000Z
END:VEVENT
END:VCALENDAR

4.2.5. Delegating an Event ๐Ÿงš

okay this one is so fun ๐Ÿคญ when you delegate an event request to another "Calendar User", the "Delegator" must both update the "Organizer" with a REPLY and send a request to the "Delegate". there is currently no protocol limitation to delegation depth, so the original delegate can totally pass the meeting to someone else, and then that person can pass it on too, and so on ๐ŸŒ€ when a request gets delegated from one CUA to another, the "Delegator" has a few responsibilities that come with it. The "Delegator" MUST:

  • Send a REPLY to the "Organizer" with the following updates:
    • A. The "Delegator's" ATTENDEE property PARTSTAT parameter is set to DELEGATED, and the DELEGATED-TO parameter is set to the address of the "Delegate" ๐Ÿ’ซ
    • B. Add an additional ATTENDEE property for the "Delegate", with the DELEGATED-FROM property parameter set to the "Delegator" ๐Ÿซง
    • C. Indicate whether they want to keep getting updates when the "Organizer" sends out updated versions of the event ๐Ÿ”” Setting the RSVP property parameter to TRUE will cause the updates to be sent, and setting it to FALSE means no further updates get sent. Note that in either case, if the "Delegate" declines the invitation, the "Delegator" will be notified ๐Ÿ’Œ
  • The "Delegator" MUST also send a copy of the original REQUEST method to the "Delegate", with changes (A) and (B), as detailed above, applied โœจ

If the "Delegate" declines the meeting, the "Organizer" MUST send an update REQUEST to the "Delegator" so that the "Delegator" can choose to delegate the REQUEST to another CUA ๐Ÿ”

Here's the whole flow in one glance ๐Ÿ‘€

+----------------+-----------------+--------------------------------+
| Action         | "Organizer"     | Attendee                       |
+----------------+-----------------+--------------------------------+
| Initiate a     | "A" sends a     |                                |
| meeting        | REQUEST message |                                |
| request        | to "B" and "C". |                                |
|                |                 |                                |
| Delegate: "C"  |                 | "C" sends a REPLY to "A" with  |
| delegates to   |                 | the ATTENDEE PARTSTAT          |
| "E"            |                 | parameter set to DELEGATED and |
|                |                 | with a new ATTENDEE property   |
|                |                 | for "E".  "E's" ATTENDEE       |
|                |                 | DELEGATED-FROM parameter is    |
|                |                 | set to "C".  "C's" ATTENDEE    |
|                |                 | DELEGATED-TO parameter is set  |
|                |                 | to "E".  "C" sends REQUEST     |
|                |                 | message to "E" with the        |
|                |                 | original meeting request       |
|                |                 | information.  The PARTSTAT     |
|                |                 | property parameter for "C" is  |
|                |                 | set to DELEGATED and the       |
|                |                 | DELEGATED-TO parameter is set  |
|                |                 | to the address of "E".  An     |
|                |                 | ATTENDEE property is added for |
|                |                 | "E" and the DELEGATED-FROM     |
|                |                 | parameter is set to the        |
|                |                 | address of "C".                |
|                |                 |                                |
| Confirm        |                 | "E" sends REPLY message to     |
| meeting        |                 | "A", and optionally to "C",    |
| attendance     |                 | with its PARTSTAT property     |
|                |                 | parameter set to ACCEPTED.     |
|                |                 |                                |
| Optional:      | "A" sends       |                                |
| Redistribute   | REQUEST message |                                |
| meeting to     | to "B", "C",    |                                |
| Attendees      | and "E".        |                                |
+----------------+-----------------+--------------------------------+

"C" responds to the "Organizer" ๐Ÿ’โ€โ™€๏ธ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=DELEGATED;DELEGATED-
 TO="mailto:e@example.com":mailto:c@example.com
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
REQUEST-STATUS:2.0;Success
DTSTAMP:19970611T190000Z
END:VEVENT
END:VCALENDAR

"Attendee" "C" delegates presence at the meeting to "E" ๐Ÿซถ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=DELEGATED;DELEGATED-
 TO="mailto:e@example.com":mailto:c@example.com
ATTENDEE;RSVP=TRUE;
 DELEGATED-FROM="mailto:c@example.com":mailto:e@example.com
DTSTART:19970701T180000Z
DTEND:19970701T200000Z
SUMMARY:Phone Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
DTSTAMP:19970611T190000Z
END:VEVENT
END:VCALENDAR

4.2.6. Delegate Accepts the Meeting ๐Ÿฅณ

so when it's time to accept a delegated meeting, the delegate, "E", sends this message to "A" and "C" ๐Ÿ’–

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=ACCEPTED;DELEGATED-
 FROM="mailto:c@example.com":mailto:e@example.com
ATTENDEE;PARTSTAT=DELEGATED;
 DELEGATED-TO="mailto:e@example.com":mailto:c@example.com
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
REQUEST-STATUS:2.0;Success
DTSTAMP:19970614T190000Z
END:VEVENT
END:VCALENDAR

4.2.7. Delegate Declines the Meeting ๐Ÿ’€

okay plot twist ๐Ÿ˜ญ in this example, the "Delegate" declines the meeting request and sets the ATTENDEE property PARTSTAT parameter to DECLINED. The "Organizer" SHOULD resend the REQUEST to "C" with the PARTSTAT parameter of the "Delegate" set to DECLINED. this lets the "Delegator" know that the "Delegate" said no, and gives them a chance to either accept the request or pass it along to another CU ๐Ÿ”„

"E" responds to "A" and "C". Note the COMMENT property that "E" uses to say why the delegation was declined ๐Ÿ™ˆ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=DELEGATED;
 DELEGATED-TO="mailto:e@example.com":mailto:c@example.com
ATTENDEE;PARTSTAT=DECLINED;
 DELEGATED-FROM="mailto:c@example.com":mailto:e@example.com
COMMENT:Sorry, I will be out of town at that time.
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
REQUEST-STATUS:2.0;Success
DTSTAMP:19970614T190000Z
END:VEVENT
END:VCALENDAR

"A" resends the REQUEST method to "C". "A" may also want to show that the item was delegated, using the COMMENT property ๐Ÿ“

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=DECLINED;
 DELEGATED-FROM="mailto:c@example.com":mailto:e@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
SUMMARY:Phone Conference
DTSTART:19970701T180000Z
DTEND:19970701T200000Z
DTSTAMP:19970614T200000Z
COMMENT:DELEGATE (ATTENDEE mailto:e@example.com) DECLINED YOUR
 INVITATION
END:VEVENT
END:VCALENDAR

4.2.8. Forwarding an Event Request โœจ

Okay bestie, so the protocol doesn't stop an "Attendee" from "forwarding" a "VEVENT" calendar component to other "Calendar Users" ๐Ÿ’Œ. Forwarding is different from delegation because the forwarded "Calendar User" (iconic name: "Party Crasher" ๐ŸŽ‰) does not replace the person who forwarded it. Implementations are not required to add the "Party Crasher" to the "Attendee" list, so there's no guarantee the "Party Crasher" will get extra updates about the event ๐Ÿ™ˆ. The forwarding "Calendar User" SHOULD NOT add the "Party Crasher" to the "Attendee" list. The "Organizer" MAY add the forwarded "Calendar User" to the "Attendee" list ๐Ÿ’….

4.2.9. Cancel a Group Event ๐Ÿšซ

Main character moment: "A" sets up a meeting with "B", "C", and "D" ๐Ÿ“…. Then "B" declines to come ๐Ÿ˜ฌ, and "A" decides to cancel the whole thing ๐Ÿ’€. The table below shows the messages these four would swap.

Messages related to a previously canceled event ("SEQUENCE" property value is less than the "SEQUENCE" property value of the "CANCEL" message) MUST be ignored ๐Ÿ›‘. Don't be the one who replies to an old canceled event, periodt ๐Ÿ’….

+-------------+---------------------+-------------------------------+
| Action      | Organizer           | Attendee                      |
+-------------+---------------------+-------------------------------+
| Initiate a  | "A" sends a REQUEST |                               |
| meeting     | message to "B",     |                               |
| request     | "C", and "D".       |                               |
|             |                     |                               |
| Decline the |                     | "B" sends a REPLY message to  |
| meeting     |                     | "A" with its PARTSTAT         |
| request     |                     | parameter set to DECLINED.    |
|             |                     |                               |
| Cancel the  | "A" sends a CANCEL  |                               |
| meeting     | message to "B",     |                               |
|             | "C", and "D".       |                               |
+-------------+---------------------+-------------------------------+

Here's how "A" cancels the event ๐ŸŽ€:

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:CANCEL
   VERSION:2.0
   BEGIN:VEVENT
   ORGANIZER:mailto:a@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL;mailto:a@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:b@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:c@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:d@example.com
   COMMENT:Mr. B cannot attend.  It's raining.  Lets cancel.
   UID:calsrv.example.com-873970198738777@example.com
   SEQUENCE:1
   STATUS:CANCELLED
   DTSTAMP:19970613T190000Z
   END:VEVENT
   END:VCALENDAR

4.2.10. Removing Attendees ๐Ÿ‘‹

"A" wants to remove "B" from the meeting ๐Ÿ™…โ€โ™€๏ธ. To do that, "A" sends a "CANCEL" to "B" and takes "B" off the "Attendee" list in the master copy of the event, lowkey a clean exit ๐Ÿงš.

+--------------------+-----------------------------------+----------+
| Action             | Organizer                         | Attendee |
+--------------------+-----------------------------------+----------+
| Remove "B" as an   | "A" sends a CANCEL message to     |          |
| Attendee           | "B".                              |          |
|                    |                                   |          |
| Update the master  | "A" optionally sends the updated  |          |
| copy of the event  | event to the remaining Attendees. |          |
+--------------------+-----------------------------------+----------+

The original meeting had "A", "B", "C", and "D" ๐Ÿ‘ฏ. In the example below, "A" sends the "CANCEL" to "B". Heads up: the "STATUS" property is left out here ๐Ÿ™ˆ. That's used when the meeting itself is cancelled, not when someone is just being removed from the event.

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:CANCEL
   VERSION:2.0
   BEGIN:VEVENT
   ORGANIZER:mailto:a@example.com
   ATTENDEE:mailto:b@example.com
   COMMENT:You're off the hook for this meeting
   UID:calsrv.example.com-873970198738777@example.com
   DTSTAMP:19970613T193000Z
   SEQUENCE:1
   END:VEVENT
   END:VCALENDAR

Here's the updated master copy ๐Ÿ’–. The "Organizer" MAY resend the updated event to the remaining "Attendees" โœจ. Notice that "B" is gone ๐Ÿ’….

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:REQUEST
   VERSION:2.0
   BEGIN:VEVENT
   ORGANIZER:mailto:a@example.com
   ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:c@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:d@example.com
   ATTENDEE;CUTYPE=ROOM:mailto:cr_big@example.com
   ATTENDEE;ROLE=NON-PARTICIPANT;
    RSVP=FALSE:mailto:e@example.com
   DTSTAMP:19970611T190000Z
   DTSTART:19970701T200000Z
   DTEND:19970701T203000Z
   SUMMARY:Phone Conference
   UID:calsrv.example.com-873970198738777@example.com
   SEQUENCE:2
   STATUS:CONFIRMED
   END:VEVENT
   END:VCALENDAR

4.2.11. Replacing the Organizer ๐Ÿ‘‘

This one's a whole plot ๐Ÿ˜ญ. "A" is the "Organizer" for a recurring meeting with "B", "C", and "D". Then "A" gets a new job offer in another country and totally goes dark, leaving no forwarding address and no way to reach them ๐Ÿ’€. The other "Attendees" find out what happened through out-of-band communication, and they agree that "B" should take over as the new "Organizer". So "B" sends out a new version of the event and removes "A" from it ๐Ÿซถ.

When the "Organizer" is replaced, the "SEQUENCE" property value MUST be incremented ๐Ÿ”ฅ. No skipping!

Here's the message "B" sends to "C" and "D" ๐Ÿฆ‹:

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:REQUEST
   VERSION:2.0
   BEGIN:VEVENT
   ORGANIZER:mailto:b@example.com
   ATTENDEE;ROLE=CHAIR;STATUS=ACCEPTED:mailto:b@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:c@example.com
   ATTENDEE;CUTYPE=INDIVIDUAL:mailto:d@example.com
   DTSTAMP:19970611T190000Z
   DTSTART:19970701T200000Z
   DTEND:19970701T203000Z
   RRULE:FREQ=WEEKLY
   SUMMARY:Phone Conference
   UID:123456@example.com
   SEQUENCE:1
   STATUS:CONFIRMED
   END:VEVENT
   END:VCALENDAR

4.3. Busy Time Examples ๐ŸŒˆ

Busy time objects can be used in a few different ways ๐Ÿง . First, a CU can ask another CU for busy time over a specific range of time, and that request can be answered with a busy time "REPLY". Or, a CU can just publish their busy time for a given interval and point other CUs to where it lives ๐Ÿ“. The examples below show both scenarios.

4.3.1. Publish Busy Time ๐Ÿ“ข

Individual "A" publishes busy time for one week ๐Ÿ—“๏ธ.

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   VERSION:2.0
   METHOD:PUBLISH
   BEGIN:VFREEBUSY
   DTSTAMP:19980101T124100Z
   ORGANIZER:mailto:a@example.com
   DTSTART:19980101T124200Z
   DTEND:19980108T124200Z
   FREEBUSY:19980101T180000Z/19980101T190000Z
   FREEBUSY:19980103T020000Z/19980103T050000Z
   FREEBUSY:19980107T020000Z/19980107T050000Z
   FREEBUSY:19980113T000000Z/19980113T010000Z
   FREEBUSY:19980115T190000Z/19980115T200000Z
   FREEBUSY:19980115T220000Z/19980115T230000Z
   FREEBUSY:19980116T013000Z/19980116T043000Z
   END:VFREEBUSY
   END:VCALENDAR

4.3.2. Request Busy Time ๐Ÿ”

Individual "A" asks individuals "B" and "C" for their busy time, and both of them reply with busy time data for "A" ๐Ÿ’Œ. The table shows the messages that get swapped.

+---------------------+--------------------+------------------------+
| Action              | Organizer          | Attendee               |
+---------------------+--------------------+------------------------+
| Initiate a busy     | "A" sends REQUEST  |                        |
| time request        | message to "B" and |                        |
|                     | "C".               |                        |
|                     |                    |                        |
| Reply to the BUSY   |                    | "B" sends a REPLY      |
| request with BUSY   |                    | message to "A" with    |
| time data           |                    | busy time data.        |
+---------------------+--------------------+------------------------+

"A" sends a "REQUEST" to "B" and "C" for busy time ๐Ÿ™.

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:REQUEST
   VERSION:2.0
   BEGIN:VFREEBUSY
   ORGANIZER:mailto:a@example.com
   ATTENDEE;ROLE=CHAIR:mailto:a@example.com
   ATTENDEE:mailto:b@example.com
   ATTENDEE:mailto:c@example.com
   DTSTAMP:19970613T190000Z
   DTSTART:19970701T080000Z
   DTEND:19970701T200000
   UID:calsrv.example.com-873970198738777@example.com
   END:VFREEBUSY
   END:VCALENDAR

4.3.3. Reply to a Busy Time Request ๐Ÿ’œ

"B" sends a "REPLY" method type of a "VFREEBUSY" calendar component back to "A" ๐Ÿฆ‹.

   BEGIN:VCALENDAR
   PRODID:-//Example/ExampleCalendarClient//EN
   METHOD:REPLY
   VERSION:2.0
   BEGIN:VFREEBUSY
   ORGANIZER:mailto:a@example.com
   ATTENDEE:mailto:b@example.com
   DTSTART:19970701T080000Z
   DTEND:19970701T200000Z
   UID:calsrv.example.com-873970198738777@example.com
   FREEBUSY:19970701T090000Z/PT1H,19970701T140000Z/PT30M
   DTSTAMP:19970613T190030Z
   END:VFREEBUSY
   END:VCALENDAR

"B" is busy from 09:00 to 10:00 and from 14:00 to 14:30 ๐Ÿ™ˆ.

4.4. Recurring Event and Time Zone Examples ๐ŸŒธ

4.4.1. A Recurring Event Spanning Time Zones โœจ

okay so this one is a weekly phone conference ๐Ÿ“ž and the "Attendees" are each in a totally different time zone ๐ŸŒ bestie, it's giving global squad energy ๐Ÿซถ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America-SanJose
TZURL:http://example.com/tz/America-SanJose
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;
 CUTYPE=INDIVIDUAL:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:b@example.fr
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:c@example.jp
DTSTAMP:19970613T190030Z
DTSTART;TZID=America-SanJose:19970701T140000
DTEND;TZID=America-SanJose:19970701T150000
RRULE:FREQ=WEEKLY;COUNT=20;WKST=SU;BYDAY=TU
RDATE;TZID=America-SanJose:19970910T140000
EXDATE;TZID=America-SanJose:19970909T140000
EXDATE;TZID=America-SanJose:19971028T140000
SUMMARY:Weekly Phone Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

okay so the first component in this iCalendar object is the time zone component ๐Ÿ•ฐ๏ธ and the "DTSTART" date lines up with the first instance of the "RRULE" property ๐Ÿ’…

the recurring meeting is defined in one particular time zone, presumably the originator's ๐Ÿค” but each "Attendee"'s client is the one that has to work out the recurrence time in that "Attendee's" time zone. that's on them, not the organizer ๐Ÿซถ

the repeating event kicks off on Tuesday, July 1, 1997 at 2:00pm PDT (UTC-7) ๐ŸŒธ "Attendee" B@example.fr is in France, where the local time on this date is 9 hours ahead of PDT, or 23:00 CEST (UTC+2) ๐Ÿฅ and "Attendee" C@example.jp is in Japan, where local time is 16 hours ahead of PDT, or Wednesday, July 2 at 06:00 JST (UTC+9) ๐Ÿฃ the day flip is literally so real ๐Ÿ’€ the event repeats weekly on Tuesdays (in PST/PDT). the "RRULE" property results in 20 instances. the last instance falls on Tuesday, November 11, 1997 2:00pm PST. the "RDATE" property adds another instance: WED, 10-SEP-1997 2:00 PM PDT โœจ

there are also two exception dates to the recurrence rule ๐Ÿ™ˆ the first one is:

  • TUE, 09-SEP-1997 14:00 PDT (UTC-7)
  • TUE, 09-SEP-1997 23:00 CEST (UTC+2)
  • WED, 10-SEP-1997 06:00 JST (UTC+9)

and the second is:

  • TUE, 28-OCT-1997 14:00 PST (UTC-8)
  • TUE, 28-OCT-1997 23:00 CET (UTC+1)
  • WED, 29-OCT-1997 07:00 JST (UTC+9)

4.4.2. Modify a Recurring Instance ๐Ÿฆ‹

in this example, the "Organizer" sets up a recurring meeting ๐Ÿ“… later on, the "Organizer" changes one instance of the event by changing the "DTSTART" property. watch the "RECURRENCE-ID" property and the "SEQUENCE" property in the second request, they're the stars here ๐ŸŒŸ

Original Request:

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
SEQUENCE:0
RRULE:FREQ=MONTHLY;BYMONTHDAY=1;UNTIL=19980901T210000Z
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
ATTENDEE:mailto:c@example.com
ATTENDEE:mailto:d@example.com
DESCRIPTION:IETF-C&S Conference Call
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970601T210000Z
DTEND:19970601T220000Z
LOCATION:Conference Call
DTSTAMP:19970526T083000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

the event request below changes the time of one specific instance ๐Ÿ•’ it moves the July 1st instance to July 3rd ๐ŸŽ€

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
RECURRENCE-ID:19970701T210000Z
SEQUENCE:1
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
ATTENDEE:mailto:c@example.com
ATTENDEE:mailto:d@example.com
DESCRIPTION:IETF-C&S Conference Call
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970703T210000Z
DTEND:19970703T220000Z
LOCATION:Conference Call
DTSTAMP:19970626T093000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.4.3. Cancel an Instance ๐Ÿšซ

in this example, the "Organizer" of a recurring event deletes the August 1st instance ๐Ÿ—‘๏ธ just that one, the rest of the series stays put ๐Ÿ’œ

BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
ATTENDEE:mailto:c@example.com
ATTENDEE:mailto:d@example.com
RECURRENCE-ID:19970801T210000Z
SEQUENCE:2
STATUS:CANCELLED
DTSTAMP:19970721T093000Z
END:VEVENT
END:VCALENDAR

4.4.4. Cancel a Recurring Event ๐Ÿ’€

in this example, the "Organizer" wants to cancel the entire recurring event, exceptions and all ๐Ÿ˜ญ whole series, gone, no notes ๐Ÿซ 

BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
ATTENDEE:mailto:c@example.com
ATTENDEE:mailto:d@example.com
DTSTAMP:19970721T103000Z
STATUS:CANCELLED
SEQUENCE:3
END:VEVENT
END:VCALENDAR

4.4.5. Change All Future Instances ๐ŸŒˆ

this one is a glow-up for the meeting location ๐Ÿ™๏ธ it moves the meeting from a conference call to Seattle, starting September 1 and carrying on through every future instance ๐Ÿ’–

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
RECURRENCE-ID;THISANDFUTURE:19970901T210000Z
SEQUENCE:3
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
ATTENDEE;RSVP=TRUE:mailto:d@example.com
DESCRIPTION:IETF-C&S Discussion
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970901T210000Z
DTEND:19970901T220000Z
LOCATION:Building 32, Microsoft, Seattle, WA
DTSTAMP:19970526T083000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.4.6. Add a New Instance to a Recurring Event ๐Ÿงš

this example adds a one-time extra instance to the recurring event โœจ the "Organizer" adds a second July meeting on the 15th ๐ŸŒŸ

BEGIN:VCALENDAR
METHOD:ADD
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:4
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
ATTENDEE;RSVP=TRUE:mailto:d@example.com
DESCRIPTION:IETF-C&S Conference Call
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970715T210000Z
DTEND:19970715T220000Z
LOCATION:Conference Call
DTSTAMP:19970629T093000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.4.7. Add a New Series of Instances to a Recurring Event ๐Ÿ”ฅ

the setup here is an ongoing meeting that was originally set up to happen every Tuesday ๐Ÿ“š later, the "Organizer" decides the meetings need to be on Tuesdays and Thursdays. main character glow-up ๐Ÿ‘‘

The original event:

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:0
RRULE:WKST=SU;BYDAY=TU;FREQ=WEEKLY
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980303T210000Z
DTEND:19980303T220000Z
LOCATION:The White Room
DTSTAMP:19980301T093000Z
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

the whole event can be rescheduled with a "REQUEST" ๐Ÿ” you do this by using the "UID" of the event you're rescheduling and including the modified "RRULE". heads up though, since this reschedules the entire event, any instance-specific information gets lost ๐Ÿ˜ญ unless you explicitly include it with the update "REQUEST" ๐Ÿซถ

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:7
RRULE:WKST=SU;BYDAY=TU,TH;FREQ=WEEKLY
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980303T210000Z
DTEND:19980303T220000Z
DTSTAMP:19980303T193000Z
LOCATION:The White Room
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.4.8. Refreshing a Recurring Event โœจ

okay so this section is all about what an "Organizer" does when an "Attendee" sends a "REFRESH" after a bunch of instance-specific edits ๐Ÿ”„ to convey every single instance-specific change, the "Organizer" must provide the latest event description and the relevant instances, no skipping ๐Ÿ’… the first three examples show the whole history: the original "VEVENT" request, the instance changes, and then finally the "REFRESH" ๐ŸŽ€

Original Request:

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:0
RDATE:19980304T180000Z
RDATE:19980311T180000Z
RDATE:19980318T180000Z
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980304T180000Z
DTEND:19980304T200000Z
DTSTAMP:19980303T193000Z
LOCATION:Conference Room A
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Organizer changes 2nd instance location and time:

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:1
RECURRENCE-ID:19980311T180000Z
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980311T160000Z
DTEND:19980311T180000Z
DTSTAMP:19980306T193000Z
LOCATION:The Small conference room
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Organizer adds a 4th instance of the meeting using the ADD method. ๐Ÿงš

BEGIN:VCALENDAR
METHOD:ADD
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:2
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980315T180000Z
DTEND:19980315T200000Z
DTSTAMP:19980307T193000Z
LOCATION:Conference Room A
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

bestie, so when "B" asks for a "REFRESH", "A" replies with this ๐Ÿซถ it captures all the instance-specific data in one go. Both the initial request and an extra "VEVENT" holding the instance-specific data are included. And because they're both the same type (they're both "VEVENTS"), they can ride together in the same iCalendar object. iconic efficiency ๐Ÿ‘‘

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:123456789@example.com
SEQUENCE:2
RDATE:19980304T180000Z
RDATE:19980311T160000Z
RDATE:19980315T180000Z
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980304T180000Z
DTEND:19980304T200000Z
DTSTAMP:19980303T193000Z
LOCATION:Conference Room A
STATUS:CONFIRMED
END:VEVENT
BEGIN:VEVENT
SEQUENCE:2
UID:123456789@example.com
RECURRENCE-ID:19980311T160000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
SUMMARY:Review Accounts
DTSTART:19980311T160000Z
DTEND:19980304T180000Z
DTSTAMP:19980306T193000Z
LOCATION:The Small conference room
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

4.4.9. Counter an Instance of a Recurring Event ๐ŸŒธ

in this one, an "Attendee" counters the "DTSTART" property of the proposed second July meeting. it's giving "can we move it?" energy ๐Ÿ™ˆ

BEGIN:VCALENDAR
METHOD:COUNTER
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
RECURRENCE-ID:19970715T210000Z
SEQUENCE:4
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;RSVP=TRUE:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
ATTENDEE;RSVP=TRUE:mailto:d@example.com
DESCRIPTION:IETF-C&S Conference Call
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970715T220000Z
DTEND:19970715T230000Z
LOCATION:Conference Call
COMMENT:May we bump this by an hour? I have a conflict
DTSTAMP:19970629T094000Z
END:VEVENT
END:VCALENDAR

4.4.10. Error Reply to a Request ๐Ÿ’€

the following example is a meeting proposal with an unsupported property and a bad property in it. drama ๐ŸŽญ

Original Request:

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:guid-1@example.com
SEQUENCE:0
RRULE:FREQ=MONTHLY;BYMONTHDAY=1
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
ATTENDEE;RSVP=TRUE:mailto:d@example.com
DESCRIPTION:IETF-C&S Conference Call
CLASS:PUBLIC
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970601T210000Z
DTEND:19970601T220000Z
DTSTAMP:19970602T094000Z
LOCATION:Conference Call
STATUS:CONFIRMED
FOO:BAR
END:VEVENT
END:VCALENDAR

"B" replies to say that RRULE isn't supported and that an unrecognized property showed up. ๐Ÿ™…โ€โ™€๏ธ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE:mailto:b@example.com
REQUEST-STATUS:3.0;Invalid Property Name;FOO
UID:guid-1@example.com
SEQUENCE:0
DTSTAMP:19970603T094000Z
END:VEVENT
END:VCALENDAR

4.5. Group To-Do Examples ๐Ÿ“

okay so "A" makes a group task that "A", "B", "C", and "D" are all going to work on ๐Ÿงš "B" confirms they accepted, "C" declines, and "D" tentatively accepts. the table below shows the messages going back and forth. then "A" sends a "REQUEST" to get everyone's status, and the replies show each "Attendee's" completion status. main character energy ๐Ÿ‘‘

+--------------+------------------------+---------------------------+
| Action       | Organizer              | Attendee                  |
+--------------+------------------------+---------------------------+
| Initiate a   | "A" sends a REQUEST    |                           |
| to-do        | message to "B", "C",   |                           |
| request      | and "D".               |                           |
|              |                        |                           |
| Accept the   |                        | "B" sends a REPLY message |
| to-do        |                        | to "A" with its PARTSTAT  |
| request      |                        | parameter set to          |
|              |                        | ACCEPTED.                 |
|              |                        |                           |
| Decline the  |                        | "C" sends a REPLY message |
| to-do        |                        | to "A" with its PARTSTAT  |
| request      |                        | parameter set to          |
|              |                        | DECLINED.                 |
|              |                        |                           |
| Tentatively  |                        | "D" sends a REPLY message |
| accept the   |                        | to "A" with its PARTSTAT  |
| to-do        |                        | parameter set to          |
| request      |                        | TENTATIVE.                |
|              |                        |                           |
| Check        | "A" sends a REQUEST    |                           |
| Attendee     | message to "B" and "D" |                           |
| completion   | with current           |                           |
| status       | information.           |                           |
|              |                        |                           |
| Attendee     |                        | "B" sends a REPLY message |
| indicates    |                        | indicating percent        |
| percent      |                        | complete.                 |
| complete     |                        |                           |
|              |                        |                           |
| Attendee     |                        | "D" sends a REPLY message |
| indicates    |                        | indicating completion.    |
| completion   |                        |                           |
+--------------+------------------------+---------------------------+

4.5.1. A VTODO Request ๐Ÿ’…

this is a sample "REQUEST" for a "VTODO" calendar component that "A" sends to "B", "C", and "D". โœจ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR:mailto:a@example.com
ATTENDEE;RSVP=TRUE:mailto:b@example.com
ATTENDEE;RSVP=TRUE:mailto:c@example.com
ATTENDEE;RSVP=TRUE:mailto:d@example.com
DTSTART:19970701T170000Z
DUE:19970722T170000Z
PRIORITY:1
SUMMARY:Create the requirements document
UID:calsrv.example.com-873970198738777-00@example.com
SEQUENCE:0
DTSTAMP:19970717T200000Z
STATUS:NEEDS-ACTION
END:VTODO
END:VCALENDAR

4.5.2. A VTODO Reply ๐Ÿซถ

"B" accepts the to-do. yay ๐ŸŽ‰

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=ACCEPTED:mailto:b@example.com
UID:calsrv.example.com-873970198738777-00@example.com
COMMENT:I'll send you my input by email
SEQUENCE:0
DTSTAMP:19970717T203000Z
REQUEST-STATUS:2.0;Success
END:VTODO
END:VCALENDAR

"B" could have declined the "VTODO" or indicated tentative acceptance by setting the "PARTSTAT" property parameter sequence to "DECLINED" or "TENTATIVE", respectively. ๐Ÿฆ‹

4.5.3. A VTODO Request for Updated Status ๐Ÿ“

"A" requests status from all "Attendees". ๐Ÿ”ฅ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:d@example.com
UID:calsrv.example.com-873970198738777-00@example.com
SUMMARY:Create the requirements document
PRIORITY:1
SEQUENCE:0
STATUS:IN-PROCESS
DTSTART:19970701T170000Z
DTSTAMP:19970717T230000Z
END:VTODO
END:VCALENDAR

4.5.4. A Reply: Percent-Complete ๐Ÿ“Š

okay so this one is a reply where B tells A which task they're working on and that they're 75% done with their part ๐Ÿ”ฅ. the vibe is "almost there, bestie" โœจ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:b@example.com
PERCENT-COMPLETE:75
UID:calsrv.example.com-873970198738777-00@example.com
DTSTAMP:19970717T233000Z
SEQUENCE:0
END:VTODO
END:VCALENDAR

4.5.5. A Reply: Completed โœ…

this is giving "D is DONE" ๐Ÿ’… D replies to say their part of the assignment is completed. no notes, just slay.

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;PARTSTAT=COMPLETED:mailto:d@example.com
UID:calsrv.example.com-873970198738777-00@example.com
DTSTAMP:19970717T233000Z
SEQUENCE:0
END:VTODO
END:VCALENDAR

4.5.6. An Updated VTODO Request ๐Ÿ”„

so "Organizer" "A" resends the "VTODO" calendar component, and this time A sets the overall completion for the whole to-do at 40% ๐Ÿ“ˆ. the main character of this update is clearly the percentage.

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE;PARTSTAT=ACCEPTED;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;PARTSTAT=COMPLETED;CUTYPE=INDIVIDUAL:mailto:d@example.com
DTSTART:19970701T170000Z
DUE:19970722T170000Z
PRIORITY:1
SUMMARY:Create the requirements document
UID:calsrv.example.com-873970198738777-00@example.com
SEQUENCE:1
DTSTAMP:19970718T100000Z
STATUS:IN-PROCESS
PERCENT-COMPLETE:40
END:VTODO
END:VCALENDAR

4.5.7. Recurring VTODOs ๐Ÿ”

the next few examples are all about recurring "VTODO" calendar components, so get ready for repeat-mode energy ๐ŸŒ€

4.5.7.1. Request for a Recurring VTODO ๐ŸŽ€

in this one, "A" sends a recurring "VTODO" calendar component to "B" and "D" ๐Ÿ’Œ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR:mailto:a@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:b@example.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:d@example.com
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTART:19980101T100000Z
DUE:19980103T100000Z
SUMMARY:Send Status Reports to Area Managers
UID:calsrv.example.com-873970198738777-00@example.com
SEQUENCE:0
DTSTAMP:19970717T200000Z
STATUS:NEEDS-ACTION
PRIORITY:1
END:VTODO
END:VCALENDAR

4.5.7.2. Replying to an Instance of a Recurring VTODO ๐Ÿฆ‹

here "B" gives "A" an update on just one instance of the "VTODO" calendar component. one instance, one update, zero drama โœจ

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REPLY
VERSION:2.0
BEGIN:VTODO
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:b@example.com
PERCENT-COMPLETE:75
UID:calsrv.example.com-873970198738777-00@example.com
DTSTAMP:19970717T233000Z
RECURRENCE-ID:19980101T170000Z
SEQUENCE:1
END:VTODO
END:VCALENDAR

4.6. Journal Examples ๐Ÿ““

this iCalendar object describes one single journal entry for October 2, 1997 ๐Ÿ“. the "RELATED-TO" property points back at the phone conference event where the minutes were taken, so it's basically a little callback ๐Ÿ“ž

BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VJOURNAL
DTSTART:19971002T200000Z
DTSTAMP:19970717T233100Z
ORGANIZER:mailto:a@example.com
SUMMARY:Phone conference minutes
DESCRIPTION:The editors meeting was held on October 1, 1997.
 Details are in the attached document.
UID:0981234-1234234-2410@example.com
RELATED-TO:0981234-1234234-2402-35@example.com
ATTACH:ftp://ftp.example.com/pub/ed/minutes100197.txt
END:VJOURNAL
END:VCALENDAR

4.7. Other Examples ๐Ÿงš

4.7.1. Event Refresh ๐Ÿ’Œ

here we refresh the event whose "UID" property value is "guid-1-12345@example.com" ๐Ÿ”„

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REFRESH
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
ATTENDEE:mailto:c@example.com
ATTENDEE:mailto:d@example.com
UID:guid-1-12345@example.com
DTSTAMP:19970603T094000
END:VEVENT
END:VCALENDAR

4.7.2. Bad RECURRENCE-ID ๐Ÿ’€

okay this one is a little spicy, so pay attention ๐Ÿ‘€. component instances are identified by the combination of "UID", "RECURRENCE-ID", and "SEQUENCE" ๐Ÿ”‘. when an "Organizer" sends an iTIP message to an "Attendee", there are three cases where an instance can't be found:

  1. The component with the referenced "UID" and "RECURRENCE-ID" has been found, but the "SEQUENCE" number in the calendar store does not match the one in the iTIP message.
  2. The component with the referenced "UID" has been found and the "SEQUENCE" numbers match, but the "RECURRENCE-ID" can't be found.
  3. The "UID" and "SEQUENCE" numbers are found, but the CUA does not support recurrences.

in case (1), two things can happen ๐Ÿค”. if the "SEQUENCE" number of the "Attendee's" instance is larger than the one in the "Organizer's" message, then the "Attendee" is getting an out-of-sequence message and MUST ignore it ๐Ÿ™…โ€โ™€๏ธ. if the "SEQUENCE" number of the "Attendee's" instance is smaller, then the "Organizer" is sending a newer version of the component, and the "Attendee's" version needs updating. since one or more updates were missed, the "Attendee" SHOULD send a "REFRESH" message to the "Organizer" to get an updated version of the event ๐Ÿ™.

in case (2), something has gone wrong ๐Ÿ˜ญ. both the "Organizer" and the "Attendee" should have the same instances, but the "Attendee" doesn't have the referenced instance. in this situation, the "Attendee" SHOULD send a "REFRESH" to the "Organizer" to get an updated version of the event.

in case (3), the CUA's limitations make it impossible to match any instance other than the single instance scheduled ๐Ÿซ . so in this case the "Attendee" need not send a "REFRESH" to the "Organizer".

the example below shows a sequence where an "Attendee" sends a "REFRESH" to the "Organizer" ๐ŸŽฌ

+-------------------------+--------------------+--------------------+
| Action                  | Organizer          | Attendee           |
+-------------------------+--------------------+--------------------+
| Update an instance      | "A" sends REQUEST  |                    |
| request                 | message to "B".    |                    |
|                         |                    |                    |
| Attendee requests       |                    | "B" sends a        |
| refresh because         |                    | REFRESH message to |
| RECURRENCE-ID was not   |                    | "A".               |
| found                   |                    |                    |
|                         |                    |                    |
| Refresh the entire      | "A" sends the      |                    |
| event                   | latest copy of the |                    |
|                         | event to "B"       |                    |
|                         |                    |                    |
| Attendee handles the    |                    | "B" updates to the |
| request and updates the |                    | latest copy of the |
| instance                |                    | meeting.           |
+-------------------------+--------------------+--------------------+

Request from "A":

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VEVENT
UID:example-12345@example.com
SEQUENCE:3
RRULE:FREQ=WEEKLY
RDATE;VALUE=PERIOD:19970819T210000Z/199700819T220000Z
ORGANIZER:mailto:a@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:mailto:a@example.com
ATTENDEE:mailto:b@example.com
DESCRIPTION:IETF-C&S Conference Call
SUMMARY:IETF Calendaring Working Group Meeting
DTSTART:19970801T210000Z
DTEND:19970801T220000Z
RECURRENCE-ID:19970809T210000Z
DTSTAMP:19970726T083000
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

"B" has the event with "UID" property "example-12345@example.com", but "B's" "SEQUENCE" property value is "1" and the event doesn't have an instance at the specified recurrence time. so basically "B" has missed at least one update and needs a fresh copy of the event ๐Ÿ˜ฉ. "B" asks for the latest copy with this refresh message:

BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REFRESH
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:mailto:a@example.com
ATTENDEE:mailto:b@example.com
UID:example-12345@example.com
DTSTAMP:19970603T094000
END:VEVENT
END:VCALENDAR

5. Application Protocol Fallbacks โœจ

5.1. Partial Implementation ๐Ÿซถ

applications that support this specification aren't required to support the entire protocol, and that's totally valid ๐Ÿ’–. the following describes how methods and properties SHOULD "fallback" in applications that don't support the complete protocol. if a method or property isn't addressed in this section, it may be ignored ๐ŸŒธ.

more parts coming, so stay tuned bestie ๐Ÿฆ‹

okay bestie, let's start with the event fallbacks ๐Ÿ“… this first table is all about the methods and what to do when you're not fully on board with one ๐Ÿ’…

+----------------+--------------------------------------------------+
| Method         | Fallback                                         |
+----------------+--------------------------------------------------+
| PUBLISH        | Required                                         |
| REQUEST        | PUBLISH                                          |
| REPLY          | Required                                         |
| ADD            | Required if recurrences supported; otherwise,    |
|                | reply with a REQUEST-STATUS "2.8; Success,       |
|                | repeating event ignored.  Scheduled as a single  |
|                | component", and schedule as a single component.  |
| CANCEL         | Required                                         |
| REFRESH        | Required                                         |
| COUNTER        | Reply with "Not Supported".                      |
| DECLINECOUNTER | Required if COUNTER is implemented for VEVENTs;  |
|                | otherwise, reply with "Not Supported".           |
+----------------+--------------------------------------------------+

next up are the iCalendar properties ๐ŸŽ€ these ones are kinda the basics, so it's giving simple vibes

+-----------------+-------------------------------------------------+
| iCalendar       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| CALSCALE        | Ignore - assume GREGORIAN.                      |
| PRODID          | Ignore                                          |
| METHOD          | Required as described in the Method list above. |
| VERSION         | Ignore                                          |
+-----------------+-------------------------------------------------+

now the event-related components ๐Ÿงš VALARM and VTIMEZONE are the stars of this one, and VTIMEZONE has a little condition attached

+-----------------+-------------------------------------------------+
| Event-Related   | Fallback                                        |
| Components      |                                                 |
+-----------------+-------------------------------------------------+
| VALARM          | Reply with "Not Supported".                     |
| VTIMEZONE       | Required if any DateTime value refers to a time |
|                 | zone.                                           |
+-----------------+-------------------------------------------------+

and last but absolutely not least, the component properties ๐Ÿ’œ this is the biggest table and it's literally got everything, from ATTACH to X- properties ๐Ÿซถ the one to watch is RRULE, because the fallback has a MUST in it, so pay attention to that one ๐Ÿ‘‘

+-----------------+-------------------------------------------------+
| Component       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| ATTACH          | Ignore                                          |
| ATTENDEE        | Required if METHOD is REQUEST; otherwise,       |
|                 | ignore.                                         |
| CATEGORIES      | Ignore                                          |
| CLASS           | Ignore                                          |
| COMMENT         | Ignore                                          |
| COMPLETED       | Ignore                                          |
| CONTACT         | Ignore                                          |
| CREATED         | Ignore                                          |
| DESCRIPTION     | Ignore                                          |
| DURATION        | Required                                        |
| DTSTAMP         | Required                                        |
| DTSTART         | Required                                        |
| DTEND           | Required                                        |
| EXDATE          | Ignore                                          |
| GEO             | Ignore                                          |
| LAST-MODIFIED   | Ignore                                          |
| LOCATION        | Required                                        |
| ORGANIZER       | Required if METHOD is REQUEST; otherwise,       |
|                 | ignore.                                         |
| PRIORITY        | Ignore                                          |
| RELATED-TO      | Ignore                                          |
| RDATE           | Ignore                                          |
| RRULE           | Ignore - assume the first instance occurs on    |
|                 | the DTSTART property.  If implemented,          |
|                 | VTIMEZONE MUST also be implemented.             |
| RECURRENCE-ID   | Required if RRULE is implemented; otherwise,    |
|                 | ignore.                                         |
| REQUEST-STATUS  | Required                                        |
| RESOURCES       | Ignore                                          |
| SEQUENCE        | Required                                        |
| STATUS          | Ignore                                          |
| SUMMARY         | Ignore                                          |
| TRANSP          | Required if FREEBUSY is implemented; otherwise, |
|                 | ignore.                                         |
| URL             | Ignore                                          |
| UID             | Required                                        |
| X-              | Ignore                                          |
+-----------------+-------------------------------------------------+

ooh, now we're switching gears to free/busy ๐Ÿ•’ this first table covers the methods, and the fallback here is pretty consistent across all three of them

+---------+---------------------------------------------------------+
| Method  | Fallback                                                |
+---------+---------------------------------------------------------+
| PUBLISH | Required if freebusy lookups are supported; otherwise,  |
|         | reply with a REQUEST-STATUS "3.14; Unsupported          |
|         | capability".                                            |
| REQUEST | Required if freebusy lookups are supported; otherwise,  |
|         | reply with a REQUEST-STATUS "3.14; Unsupported          |
|         | capability".                                            |
| REPLY   | Required if freebusy lookups are supported; otherwise,  |
|         | reply with a REQUEST-STATUS "3.14; Unsupported          |
|         | capability".                                            |
+---------+---------------------------------------------------------+

the iCalendar properties table here is the same as the one we saw earlier, so no new surprises ๐ŸŒธ

+-----------------+-------------------------------------------------+
| iCalendar       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| CALSCALE        | Ignore - assume GREGORIAN.                      |
| PRODID          | Ignore                                          |
| METHOD          | Required as described in the Method list above. |
| VERSION         | Ignore                                          |
+-----------------+-------------------------------------------------+

and finally the component properties for free/busy ๐Ÿ“ notice that DURATION and REQUEST-STATUS are ignored in this one, but FREEBUSY is required, which is so iconic for it ๐Ÿ”ฅ

+-----------------+-------------------------------------------------+
| Component       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| ATTENDEE        | Required if METHOD is REQUEST; otherwise,       |
|                 | ignore.                                         |
| COMMENT         | Ignore                                          |
| CONTACT         | Ignore                                          |
| DTEND           | Required                                        |
| DTSTAMP         | Required                                        |
| DTSTART         | Required                                        |
| DURATION        | Ignore                                          |
| FREEBUSY        | Required                                        |
| ORGANIZER       | Required if METHOD is REQUEST; otherwise,       |
|                 | ignore.                                         |
| REQUEST-STATUS  | Ignore                                          |
| UID             | Required                                        |
| URL             | Ignore                                          |
| X-              | Ignore                                          |
+-----------------+-------------------------------------------------+

okay bestie, to-dos get their own fallback table ๐Ÿ“ here's how each METHOD falls back ๐Ÿ’–

+----------------+--------------------------------------------------+
| Method         | Fallback                                         |
+----------------+--------------------------------------------------+
| PUBLISH        | Required                                         |
| REQUEST        | PUBLISH                                          |
| REPLY          | Required                                         |
| ADD            | Required if recurrences supported; otherwise,    |
|                | reply with a REQUEST-STATUS "2.8; Success,       |
|                | repeating event ignored.  Scheduled as a single  |
|                | component", and schedule as a single component.  |
| CANCEL         | Required                                         |
| REFRESH        | Required                                         |
| COUNTER        | Reply with "Not Supported".                      |
| DECLINECOUNTER | Required if COUNTER for VTODOs is implemented;   |
|                | otherwise, reply with "Not Supported".           |
+----------------+--------------------------------------------------+

the iCalendar properties are next, and honestly these are pretty chill ๐ŸŒธ

+-----------------+-------------------------------------------------+
| iCalendar       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| CALSCALE        | Ignore - assume GREGORIAN.                      |
| PRODID          | Ignore                                          |
| METHOD          | Required as described in the Method list above. |
| VERSION         | Ignore                                          |
+-----------------+-------------------------------------------------+

then the to-do components, which is giving VALARM and VTIMEZONE vibes ๐Ÿ•ฐ๏ธ

+-----------------+-------------------------------------------------+
| To-Do-Related   | Fallback                                        |
| Components      |                                                 |
+-----------------+-------------------------------------------------+
| VALARM          | Reply with "Not Supported".                     |
| VTIMEZONE       | Required if any DateTime value refers to a time |
|                 | zone.                                           |
+-----------------+-------------------------------------------------+

and last but DEFINITELY not least, the component properties. this one is long bestie, grab a snack ๐Ÿฟ๐Ÿซถ

+------------------+------------------------------------------------+
| Component        | Fallback                                       |
| Property         |                                                |
+------------------+------------------------------------------------+
| ATTACH           | Ignore                                         |
| ATTENDEE         | Required if METHOD is REQUEST; otherwise,      |
|                  | ignore.                                        |
| CATEGORIES       | Ignore                                         |
| CLASS            | Ignore                                         |
| COMMENT          | Ignore                                         |
| COMPLETED        | Required                                       |
| CONTACT          | Ignore                                         |
| CREATED          | Ignore                                         |
| DESCRIPTION      | Required if METHOD is REQUEST; otherwise,      |
|                  | ignore.                                        |
| DUE              | Required                                       |
| DURATION         | Required                                       |
| DTSTAMP          | Required                                       |
| DTSTART          | Required                                       |
| EXDATE           | Ignore - reply with "Not Supported".           |
| LAST-MODIFIED    | Ignore                                         |
| LOCATION         | Ignore                                         |
| ORGANIZER        | Required if METHOD is REQUEST; otherwise,      |
|                  | ignore.                                        |
| PERCENT-COMPLETE | Ignore                                         |
| PRIORITY         | Required                                       |
| RECURRENCE-ID    | Required if RRULE is implemented; otherwise,   |
|                  | ignore.                                        |
| RELATED-TO       | Ignore                                         |
| REQUEST-STATUS   | Ignore                                         |
| RDATE            | Ignore                                         |
| RRULE            | Ignore - assume the first instance occurs on   |
|                  | the DTSTART property.  If implemented,         |
|                  | VTIMEZONE MUST also be implemented.            |
| RESOURCES        | Ignore                                         |
| SEQUENCE         | Required                                       |
| STATUS           | Required                                       |
| SUMMARY          | Ignore                                         |
| URL              | Ignore                                         |
| UID              | Required                                       |
| X-               | Ignore                                         |
+------------------+------------------------------------------------+

journals have their own fallback table too, and it's a little more relaxed about METHODs ๐Ÿฆ‹

+---------+---------------------------------------------------------+
| Method  | Fallback                                                |
+---------+---------------------------------------------------------+
| PUBLISH | Implementations MAY ignore the METHOD type.  The        |
|         | REQUEST-STATUS "3.14; Unsupported capability" MUST be   |
|         | returned.                                               |
| ADD     | Implementations MAY ignore the METHOD type.  The        |
|         | REQUEST-STATUS "3.14; Unsupported capability" MUST be   |
|         | returned.                                               |
| CANCEL  | Implementations MAY ignore the METHOD type.  The        |
|         | REQUEST-STATUS "3.14; Unsupported capability" MUST be   |
|         | returned.                                               |
+---------+---------------------------------------------------------+

the iCalendar properties are the same vibe as before ๐ŸŒˆ

+-----------------+-------------------------------------------------+
| iCalendar       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| CALSCALE        | Ignore - assume GREGORIAN.                      |
| PRODID          | Ignore                                          |
| METHOD          | Required as described in the Method list above. |
| VERSION         | Ignore                                          |
+-----------------+-------------------------------------------------+

journal components are pretty minimal, just VTIMEZONE here ๐Ÿ•ฐ๏ธ

+-----------------+-------------------------------------------------+
| Journal-Related | Fallback                                        |
| Components      |                                                 |
+-----------------+-------------------------------------------------+
| VTIMEZONE       | Required if any DateTime value refers to a time |
|                 | zone.                                           |
+-----------------+-------------------------------------------------+

and the journal component properties, which are mostly ignored except the big requireds ๐Ÿ’…

+-----------------+-------------------------------------------------+
| Component       | Fallback                                        |
| Property        |                                                 |
+-----------------+-------------------------------------------------+
| ATTACH          | Ignore                                          |
| ATTENDEE        | Ignore                                          |
| CATEGORIES      | Ignore                                          |
| CLASS           | Ignore                                          |
| COMMENT         | Ignore                                          |
| CONTACT         | Ignore                                          |
| CREATED         | Ignore                                          |
| DESCRIPTION     | Ignore                                          |
| DTSTAMP         | Required                                        |
| DTSTART         | Required                                        |
| EXDATE          | Ignore                                          |
| LAST-MODIFIED   | Ignore                                          |
| ORGANIZER       | Ignore                                          |
| RECURRENCE-ID   | Required if RRULE is implemented; otherwise,    |
|                 | ignore.                                         |
| RELATED-TO      | Ignore                                          |
| RDATE           | Ignore                                          |
| RRULE           | Ignore - assume the first instance occurs on    |
|                 | the DTSTART property.  If implemented,          |
|                 | VTIMEZONE MUST also be implemented.             |
| SEQUENCE        | Required                                        |
| STATUS          | Ignore                                          |
| SUMMARY         | Required                                        |
| URL             | Ignore                                          |
| UID             | Required                                        |
| X-              | Ignore                                          |
+-----------------+-------------------------------------------------+

5.2. Latency Issues ๐ŸŒ

okay so with a store-and-forward transport, events can totally show up out of order ๐Ÿ˜ญ like a "CANCEL" might land before the "REQUEST" it's cancelling for the calendar component. this section walks through a few of those messy scenarios ๐Ÿ’€

5.2.1. Cancellation of an Unknown Calendar Component ๐Ÿ‘ป

when a "CANCEL" shows up before the original "REQUEST", the calendar can't match the "UID" property of the cancellation to anything it already has, so it's lost lowkey ๐Ÿ™ˆ the advice is to hold onto messages that can't be correlated and also have non-zero sequence numbers, instead of tossing them. implementations MAY age them out if no other messages arrive with the same "UID" property value and a lower sequence number โณ

5.2.2. Unexpected Reply from an Unknown Delegate ๐ŸŽญ

when an "Attendee" delegates an item to someone else, they MUST send a "REPLY" method to the "Organizer" using the "ATTENDEE" properties, so everyone knows the request was delegated and to whom ๐Ÿ’Œ this means the "Organizer" can get a "REPLY" from a CU who wasn't on the original "Attendees" list, which is a plot twist ๐Ÿ˜ณ how to handle that is up to the implementation, but the calendaring software is expected to either accept the reply or hold it until the related "REPLY" method comes in from the "Delegator". if the version of the "REPLY" method is out of date, the "Organizer" SHOULD treat the message as a "REFRESH" message and update the "Delegate" with the correct version, as long as delegating to that delegate is acceptable ๐Ÿซก

5.3. Sequence Number ๐Ÿ”ข

so under some conditions, a CUA might get requests and replies that have the same "SEQUENCE" property value ๐Ÿคฏ when that happens, the "DTSTAMP" property is the tie-breaker when two items with the same "SEQUENCE" property value get evaluated. main character tiebreaker energy โœจ

6. Security Considerations ๐Ÿ”โœจ

okay bestie, iTIP is an abstract transport protocol, which means it's gonna get bound to a real-time transport, a store-and-forward transport, and maybe other transports too ๐Ÿš€. The transport protocol is the one responsible for providing facilities for authentication and encryption, using standard Internet mechanisms that the sender and receiver both understand. so the security glow-up is handled at that layer ๐Ÿ’…

6.1. Security Threats ๐Ÿ˜ฑ

6.1.1. Spoofing the Organizer

in iTIP, the "Organizer" (or someone acting on the "Organizer's" behalf) is the only person who's allowed to change an existing "VEVENT", "VTODO", or "VJOURNAL" calendar component and republish it or send out updates to the "Attendees" ๐Ÿ™…โ€โ™€๏ธ. but someone who isn't the "Organizer" can totally build an iCalendar object that maliciously changes or cancels one of those components, then republish it or send it to the "Attendees." that's a whole villain arc ๐Ÿ’€

6.1.2. Spoofing the Attendee

in iTIP, an "Attendee" of a "VEVENT" or "VTODO" calendar component (or someone working on the "Attendee's" behalf) is the only person who can update any parameter tied to their "ATTENDEE" property and send it back to the "Organizer" ๐ŸŽ€. however, an iCalendar object that maliciously changes the "ATTENDEE" parameters can be made by someone who isn't the real "Attendee" and then sent to the "Organizer." not the vibe ๐Ÿ™ˆ

6.1.3. Unauthorized Replacement of the Organizer

there are gonna be times when "Attendees" of an event or to-do decide, using out-of-band mechanisms, that the "Organizer" has to be replaced ๐Ÿ”„. when the new "Organizer" sends out the updated "VEVENT" or "VTODO," the "Attendee's" CUA will notice that the "Organizer" has changed. the problem? it has no way of knowing whether or not that change was actually agreed on by everyone ๐Ÿ˜ฌ

6.1.4. Eavesdropping and Data Integrity

the iCalendar object is built out of human-readable clear text ๐Ÿ“–. so anything inside an iCalendar object can be read and/or changed by unauthorized people while it's in transit. literally wide open ๐Ÿซฃ

6.1.5. Flooding a Calendar

implementations could give you a way to automatically pull "REQUEST" methods into a calendar ๐ŸŒŠ. that opens the door for a calendar to get flooded with requests, which basically blocks off all of the calendar's free time. the calendar's whole personality is gone ๐Ÿ’€

6.1.6. Unauthorized REFRESH Requests

it's possible for an "Organizer" to get a "REFRESH" request from someone who is not an "Attendee" of an event or to-do ๐Ÿ‘€. only "Attendees" of an event or to-do are authorized to receive replies to "REFRESH" requests. replying to these requests for anyone who isn't an "Attendee" may be a security problem ๐Ÿšจ

6.2. Recommendations ๐Ÿซถ

for an application where the information is sensitive or critical, and the network has a high probability of attack, iTIP transactions SHOULD be encrypted and authenticated ๐Ÿ”’. this helps mitigate spoofing, eavesdropping, and malicious changes in transit. protect your plans, bestie ๐Ÿ’–

6.2.1. Securing iTIP transactions

iTIP transport bindings MUST provide a mechanism to enable authentication of the sender's identity, as well as privacy and integrity of the data being transmitted ๐Ÿ›ก๏ธ. this lets the receiver of a signed iCalendar object verify who the sender is. that sender can then be correlated to an "ATTENDEE" property in the iCalendar object. if the correlation is made and the sender is authorized to make the requested change or update, then the operation may proceed โœ…. it also lets the message be encrypted so nobody can read the contents in transit. the iTIP transport binding documents go into detail about how this works ๐Ÿ“š

6.2.2. Implementation Controls

the threat of unauthorized replacement of the "Organizer" SHOULD be mitigated by a calendar system that uses this protocol. it does that by providing controls or alerts that make "Calendar Users" aware of "Organizer" changes, and by letting them decide whether or not the request should be honored ๐Ÿšฆ.

the threat of flooding a calendar SHOULD be mitigated by a calendar system that uses this protocol, by providing controls that limit the acceptable sources for iTIP transactions. it can also limit the size of messages and the volume of traffic, by source ๐Ÿงฑ.

the threat of unauthorized "REFRESH" requests SHOULD be mitigated by a calendar system that uses this protocol, by providing controls or alerts that let "Calendar Users" decide whether or not the request should be honored ๐Ÿ™‹โ€โ™€๏ธ. an implementation MAY decide to keep track, for audit or historical purposes, of "Calendar Users" who were part of an "Attendee" list and were later uninvited ๐Ÿ“. similar controls or alerts should be provided when a "REFRESH" request comes in from these "Calendar Users" too โœจ

6.2.3. Access Controls and Filtering

in a lot of environments, there could be restrictions on who is allowed to schedule with whom, and on who the allowed delegates are for particular "Calendar Users" ๐Ÿ—‚๏ธ.

iTIP transport bindings SHOULD provide mechanisms for access controls or filtering, so iTIP transactions only happen between authorized "Calendar Users" ๐Ÿ”. that includes stopping one "Calendar User" from scheduling with another, or stopping one "Calendar User" from delegating to another ๐Ÿšซ

6.3. Privacy Issues ๐Ÿ™ˆ

the "Organizer" might want to keep "Attendees" from knowing which other "Attendees" are participating in an event or to-do ๐Ÿคซ. the "Organizer" gets to choose between sending single iTIP messages with a full list of "Attendees," or sending an iTIP message to each "Attendee" with only that one "Attendee" listed ๐Ÿ’œ


7. IANA Considerations ๐Ÿงพ

7.1. Registration Template for REQUEST-STATUS Values

this specification updates [RFC5545] by adding a "REQUEST-STATUS" value registry to the iCalendar Elements registry ๐ŸŒธ.

a "REQUEST-STATUS" value is defined by filling out the following template ๐Ÿ“‹.

   Status Code:  Hierarchical, numeric return status code, following
      the rules defined in Section 3.8.8.3 of [RFC5545].

   Status Description:  Textual status description.  A short but
      clear description of the error.

   Status Exception Data:  Textual exception data.  A short but clear
      description of what might appear in this field.

   Description:  Describe the underlying cause for this status code
      value.

7.2. Additions to iCalendar METHOD Registry ๐Ÿ’ซ

this document defines the following values for the iCalendar METHOD property, using the values template from Section 8.2.6 of [RFC5545]. these should be added to the Methods Registry defined in Section 8.3.12 of [RFC5545]:

7.2.1. METHOD:PUBLISH

Value: PUBLISH

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.2. METHOD:REQUEST

Value: REQUEST

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.3. METHOD:REPLY

Value: REPLY

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.4. METHOD:ADD

Value: ADD

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.5. METHOD:CANCEL

Value: CANCEL

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.6. METHOD:REFRESH

Value: REFRESH

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.7. METHOD:COUNTER

Value: COUNTER

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.2.8. METHOD:DECLINECOUNTER

Value: DECLINECOUNTER

Purpose: Standard iTIP METHOD value.

Conformance: Only used with the METHOD property.

Examples: See this RFC.

7.3. REQUEST-STATUS Value Registry ๐Ÿ“Š

new "REQUEST-STATUS" values can be registered using the process described in Section 8.2.1 of [RFC5545] ๐Ÿ†•.

the following table is used to initialize the "REQUEST-STATUS" value registry ๐Ÿ“.

        +-------------+---------+--------------------------+
        | Status Code | Status  | Reference                |
        +-------------+---------+--------------------------+
        | 2.0         | Current | RFC 5546, Section 3.6.1  |
        | 2.1         | Current | RFC 5546, Section 3.6.2  |
        | 2.2         | Current | RFC 5546, Section 3.6.3  |
        | 2.3         | Current | RFC 5546, Section 3.6.4  |
        | 2.4         | Current | RFC 5546, Section 3.6.5  |
        | 2.5         | Current | RFC 5546, Section 3.6.6  |
        | 2.6         | Current | RFC 5546, Section 3.6.7  |
        | 2.7         | Current | RFC 5546, Section 3.6.8  |
        | 2.8         | Current | RFC 5546, Section 3.6.9  |
        | 2.9         | Current | RFC 5546, Section 3.6.10 |
        | 2.10        | Current | RFC 5546, Section 3.6.11 |
        | 2.11        | Current | RFC 5546, Section 3.6.12 |
        | 3.0         | Current | RFC 5546, Section 3.6.13 |
        | 3.1         | Current | RFC 5546, Section 3.6.14 |
        | 3.2         | Current | RFC 5546, Section 3.6.15 |
        | 3.3         | Current | RFC 5546, Section 3.6.16 |
        | 3.4         | Current | RFC 5546, Section 3.6.17 |
        | 3.5         | Current | RFC 5546, Section 3.6.18 |
        | 3.6         | Current | RFC 5546, Section 3.6.19 |
        | 3.7         | Current | RFC 5546, Section 3.6.20 |
        | 3.8         | Current | RFC 5546, Section 3.6.21 |
        | 3.9         | Current | RFC 5546, Section 3.6.22 |
        | 3.10        | Current | RFC 5546, Section 3.6.23 |
        | 3.11        | Current | RFC 5546, Section 3.6.24 |
        | 3.12        | Current | RFC 5546, Section 3.6.25 |
        | 3.13        | Current | RFC 5546, Section 3.6.26 |
        | 3.14        | Current | RFC 5546, Section 3.6.27 |
        | 4.0         | Current | RFC 5546, Section 3.6.28 |
        | 5.0         | Current | RFC 5546, Section 3.6.29 |
        | 5.1         | Current | RFC 5546, Section 3.6.30 |
        | 5.2         | Current | RFC 5546, Section 3.6.31 |
        | 5.3         | Current | RFC 5546, Section 3.6.32 |
        +-------------+---------+--------------------------+

8. Acknowledgments ๐Ÿซถ

this is an update to the original iTIP document, authored by S. Silverberg, S. Mansour, F. Dawson, and R. Hopson ๐ŸŒŸ.

this revision is the product of the Calsify IETF Working Group, and several participants made important contributions to this specification ๐Ÿ’œ. those include Oliver Block, Bernard Desruisseaux, Mike Douglass, Tim Hare, Ciny Joy, Bruce Kahn, Reinhold Kainhofer, Eliot Lear, Jonathan Lennox, Andy Mabbett, Aki Niemi, John W. Noerenberg II, Robert Ransdell, and Caleb Richardson. the whole squad ๐Ÿ‘‘

9. References ๐Ÿ“š

9.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2368]  Hoffman, P., Masinter, L., and J. Zawinski, "The mailto
           URL scheme", RFC 2368, July 1998.

[RFC5545]  Desruisseaux, B., "Internet Calendaring and Scheduling
           Core Object Specification (iCalendar)", RFC 5545,
           September 2009.

9.2. Informative References

[iMIP]     Melnikov, A., Ed., "iCalendar Message-Based
           Interoperability Protocol (iMIP)", Work in Progress,
           October 2009.

Appendix A. Differences from RFC 2446 โœจ

A.1. Changed Restrictions ๐Ÿ’…

okay so this part is all about what got changed in the restriction tables, bestie ๐ŸŽ€ the big one is that this spec now defines an allowed combination of "REQUEST-STATUS" codes when multiple iCalendar components are included in an iTIP message โœจ

this spec also restricts "RECURRENCE-ID" to only a single occurrence in any one iCalendar component in an iTIP message, as required by [RFC5545] ๐Ÿฆ‹ here's the full list of tweaks, and they're all about lining up with [RFC5545] ๐Ÿ’–

  • Changed the "RECURRENCE-ID" entry in the component restriction table to "0 or 1" from "0+", to fall in line with [RFC5545] ๐ŸŒธ
  • Changed the "FREEBUSY" entry in the "VFREEBUSY", "PUBLISH", and "REPLY" restriction tables to "0+" from "1+", to fall in line with [RFC5545] ๐Ÿงš
  • Changed the "FREEBUSY" description in the "VFREEBUSY" and "REPLY" restriction tables to indicate that different "FBTYPE" ranges MUST NOT overlap ๐Ÿ™ˆ
  • Changed the "TZNAME" entry in the "VTIMEZONE" restriction table to "0+" from "0 or 1", to fall in line with [RFC5545] ๐Ÿ“
  • Changed the "COMMENT" entry in the component restriction tables to "0+" from "0 or 1", to fall in line with [RFC5545] ๐Ÿ’œ
  • Added the "ATTENDEE" entry in the "VALARM" restriction table to match the email alarm type in [RFC5545] ๐Ÿฆ‹
  • Changed the "CATEGORIES" entry in the component restriction tables to "0+" from "0 or 1", to fall in line with [RFC5545] โœจ
  • Changed the "RESOURCES" entry in the component restriction tables to "0+" from "0 or 1", to fall in line with [RFC5545] ๐ŸŒˆ
  • Changed the "CONTACT" entry in the "VFREEBUSY" restriction table to "0 or 1" from "0+", to fall in line with [RFC5545] ๐Ÿ’…
  • Changed the "UID" entry in the "VFREEBUSY" and "PUBLISH" restriction tables to "1" from "0", to fall in line with [RFC5545] ๐Ÿ‘‘
  • Added the "COMPLETED" entry in the "VTODO" restriction tables to fall in line with [RFC5545] ๐Ÿซถ
  • Added the "REQUEST-STATUS" entry in the "VJOURNAL" restriction tables to fall in line with [RFC5545] ๐Ÿ”ฅ

A.2. Deprecated Features ๐ŸŒธ

bestie, some features got retired, and this document cleaned up after them too ๐Ÿงน

  • The "EXRULE" property was removed in [RFC5545], and references to that have been removed in this document too ๐Ÿ’€
  • The "PROCEDURE" value for the "ACTION" property was removed in [RFC5545], and references to that have been removed in this document too ๐Ÿ™ˆ
  • The "THISANDPRIOR" option for the "RANGE" parameter was removed in [RFC5545], and references to that have been removed in this document too โœจ

Author's Address ๐ŸŽ€

the editor, Cyrus Daboo, can be reached at the address below, and that's the end of the document ๐Ÿฆ‹

Cyrus Daboo (editor)
Apple Inc.
1 Infinite Loop
Cupertino, CA  95014
USA

EMail: cyrus@daboo.name
URI:   http://www.apple.com/
๐Ÿ“ฆ where this page comes from