Creating a CalDAV collection

Last modified by Pascal Robert on 2013/11/18 06:15

To create a new CalDAV collection, you must use the MKCALENDAR HTTP method. You don't need to pass any properties in the request, you can create a collection with only:

 

MKCALENDAR /calendars/__uids__/D0CA5B92-B12F-4CC1-AB67-CCDC5ED665B4/mynewcalendar/
 
<?
xml

 

version
=
"1.0"

 

encoding
=
"utf-8"

 

?>
<
C:mkcalendar

 

xmlns:D
=
"DAV:"

 

xmlns:C
=

urn:ietf:params:xml:ns:caldav

""
>
</
C:mkcalendar
>

 

If you do it with this simple request, the display name of the collection will be the last part of the URL (mynewcalendar). In the request, you can send most of the DAV and CalDAV attributes that applies to a calendar collection (warning: some of the 

A successful request will return a HTTP 201 status code. 

 

HTTP/1.1 201 Created
Content-Length: 0
Server: CalendarServer/4.2(CalendarServerv19.0.95) Twisted/12.0.0 TwistedWeb/9.0.0
Last-Modified: Thu, 21 Feb 2013 03:09:56 GMT
DAV: 1, access-control, calendar-access, addressbook, extended-mkcol
Etag: "25b621cd05498be5ab945acda80cf3dc"
Date: Thu, 21 Feb 2013 03:09:56 GMT
Connection: close, close

 

So you only need to read the status code to know if the request was successful (you might want to store the value of the Etag value if needed). 

If you don't put a slash at the end of the URL, e.g. /mycalendar instead of /mycalendar/, the status code will 301 (Moved Permanently), and the collection WON'T be created, so be sure you add the slash at the end.

If you don't get a 201 status code, it means you got an error. The following errors can occur:

  • 403 (Forbidden)
  • 409 (Conflict)
  • 415 (Unsupported Media Type)
  • 507 (Insufficient Storage)
  • 207 (Multi-Status)

As a rule of thumb:

  • If you get a 201 (Created) status code, it's a success, you don't have anything special to do.
  • If you get a 3xx (redirection), resend the request by adding a / at the end of the URL.
  • If you get a 4xx or a 207 status code, it's an error on the client side. If the content-type of the response is "text/xml", parse it to find the exact error.
  • If you get a 5xx status code, it's an error on the server side. You can't do much except asking the manager of the server about the problem, or retry to send the request later.

A 405 (Unsupported Media Type) might happen if you send the wrong namespace in your request. Example:

 

MKCALENDAR /calendars/__uids__/D0CA5B92-B12F-4CC1-AB67-CCDC5ED665B4/mynewcalendar/

 

<?
xml

 

version
=
"1.0"

 

encoding
=
"utf-8"

 

?>
<
C:mkcalendar

 

xmlns:D
=
"DAV:"

 

xmlns:C
=

urn:ietf:params:xml:ns:carddav

""
>
</
C:mkcalendar
>
 
HTTP/1.1 415 Unsupported Media Type

 

Where is the error in my request? It was using the CardDAV namespace instead of the CalDAV namespace, hence the error.

A 403 (Forbidden) error might happen if you try to create a new collection on top of another collection. For example, if you sent the same MKCALENDAR requests two times:

 

MKCALENDAR /calendars/__uids__/D0CA5B92-B12F-4CC1-AB67-CCDC5ED665B4/mynewcalendar/
 

 

<?
xml

 

version
=
"1.0"

 

encoding
=
"utf-8"

 

?>
<
C:mkcalendar

 

xmlns:D
=
"DAV:"

 

xmlns:C
=

urn:ietf:params:xml:ns:caldav

""
>
</
C:mkcalendar
>
 
MKCALENDAR /calendars/__uids__/D0CA5B92-B12F-4CC1-AB67-CCDC5ED665B4/mynewcalendar/
 

 

<?
xml

 

version
=
"1.0"

 

encoding
=
"utf-8"

 

?>
<
C:mkcalendar

 

xmlns:D
=
"DAV:"

 

xmlns:C
=

urn:ietf:params:xml:ns:caldav

""
>
</
C:mkcalendar
>

 

The last one will return:

 

HTTP/1.1 403 Forbidden
Content-Length: 215
Date: Thu, 21 Feb 2013 02:49:23 GMT
DAV: 1, access-control, calendar-access, calendar-schedule, calendar-auto-schedule, calendar-availability, inbox-availability, calendar-proxy, calendarserver-private-events, calendarserver-private-comments, calendarserver-sharing, calendarserver-sharing-no-scheduling, calendar-query-extended, calendar-default-alarms, addressbook, extended-mkcol, calendarserver-principal-property-search, calendarserver-principal-search
Content-Type: text/xml
Server: CalendarServer/4.2(CalendarServerv19.0.95) Twisted/12.0.0 TwistedWeb/9.0.0
Connection: close
<?
xml

 

version
=
'1.0'

 

encoding
=
'UTF-8'
?>
<
error

 

xmlns
=
'DAV:'
>
  
<
resource-must-be-null
/>
  
<
error-description

 

xmlns
=

http://twistedmatrix.com/xml_namespace/dav/'

'
>Resource already exists</
error-description
>
</
error
>

 

The following errors might be present in the body of the response:

 

  • resource-must-be-null (namespace: DAV): you can't create this collection at this URL. As we saw in the example just above, you will get this error if you try to create a collection on an already existing collection.
  • calendar-collection-location-ok (namespace: urn:ietf:params:xml:ns:caldav): identify a location where a calendar collection. You will get this error if you try to create a calendar collection inside another calendar collection, which isn't allowed in CalDAV.
  • needs-privilege (namespace: DAV): you don't have privilege to create this collection at the specified URL.
  • valid-calendar-data (namespace: urn:ietf:params:xml:ns:caldav): you must pass a valid VTIMEZONE component for the calendar-timezone property.
  • initialize-calendar-collection (namespace: urn:ietf:params:xml:ns:caldav): the resourcetype property must be of both DAV:collection and urn:ietf:params:xml:ns:caldav:calendar.

If you get a 207 (Multi-Status) for the response, you have to parse each <response> element to analyse each error. For example, I tried to create a collection that only supports VJOURNAL component:

 

<?
xml

 

version
=
"1.0"

 

encoding
=
"utf-8"

 

?>
<
C:mkcalendar

 

xmlns:D
=
"DAV:"

 

xmlns:C
=

urn:ietf:params:xml:ns:caldav

""
>
<
D:set
>
<
D:prop
>
<
C:supported-calendar-component-set
>
<
C:comp

 

name
=
"VJOURNAL"
/>
</
C:supported-calendar-component-set
>
</
D:prop
>
</
D:set
>
</
C:mkcalendar
>

 

VJOURNAL is not supported as a component type on calendar or tasks collections, hence the response will be of the Multi-Status type:

 

HTTP/1.1 207 Multi-Status

 

<?
xml

 

version
=
'1.0'

 

encoding
=
'UTF-8'
?>
<
multistatus

 

xmlns
=
'DAV:'
>
  
<
response
>
    
<
href
>/calendars/__uids__/D0CA5B92-B12F-4CC1-AB67-CCDC5ED665B4/calendrier6/</
href
>
    
<
propstat
>
      
<
prop
>
        
<
supported-calendar-component-set

 

xmlns
=

urn:ietf:params:xml:ns:caldav

''
/>
      
</
prop
>
      
<
status
>HTTP/1.1 403 Forbidden</
status
>
      
<
responsedescription
>Invalid CALDAV:supported-calendar-component-set</
responsedescription
>
    
</
propstat
>
  
</
response
>
</
multistatus
>