# CalDAV Endpoint Requirements

## Purpose
Define exact CalDAV URI structure, required methods/reports/properties, and expected status behavior for interoperability.

## Scope
This document covers:

- CalDAV URI layout
- Method support by resource type
- Required WebDAV/CalDAV properties and reports
- Required status-code behavior

## Normative Boundaries
- This document is authoritative for CalDAV URI structure and method/property/report support.
- Event/recurrence data semantics are defined in `requirements/caldav.md` and `requirements/recurrence_exceptions.md`.
- Authentication/authorization and error behavior norms are defined in:
  - `requirements/authentication.md`
  - `requirements/authorization.md`
  - `requirements/error_model.md`

## Endpoint Layout
Base CalDAV root:

- `/caldav/`
- If `url_slug` is configured in setup, canonical CalDAV root is `/<url_slug>/caldav/`.

Resource hierarchy:

- Principal collection: `/caldav/principals/`
- User principal: `/caldav/principals/{user_id}/`
- Calendar home set: `/caldav/calendars/`
- Shared public calendar collection: `/caldav/calendars/public/`
- Event object resource: `/caldav/calendars/public/{object_id}.ics`

URI rules:

- `{user_id}` is stable and URL-safe.
- `{object_id}` is stable for object lifetime.
- All authenticated principals discover the same shared calendar home set and `public` collection.
- Object rename/move behavior is unsupported in first pass unless explicitly implemented.

## Methods by Resource Type

### `/caldav/`
- `OPTIONS`
- `PROPFIND` (Depth 0/1)

### Principal resources
- `PROPFIND`
- `REPORT` where applicable for principal discovery support

### Calendar collection resources
- `OPTIONS`
- `PROPFIND`
- `GET` (availability probe support; returns `200` with empty body on collection URL)
- `REPORT` (`calendar-query`, `calendar-multiget`, `sync-collection`)

### Event object resources
- `GET`
- `PUT`
- `DELETE`
- `PROPFIND` (Depth 0)

## Required DAV/CalDAV Properties
Calendar collection and principal responses must support, at minimum, these properties (where applicable):

- `resourcetype`
- `displayname`
- `current-user-principal`
- `principal-URL`
- `calendar-home-set`
- `supported-calendar-component-set`
- `getctag` (or equivalent documented change tag)
- `getetag` for object resources
- `sync-token` for collections supporting sync

## REPORT Support
- `calendar-query` with time-range filtering
- `calendar-multiget` by href set
- `sync-collection` for incremental changes since sync token
- Collection `REPORT` handling must accept both canonical and non-canonical trailing-slash variants (for example `/caldav/calendars/public/` and `/caldav/calendars/public`).
- For `sync-collection`, if client sync-token equals server sync-token, server should return `207` with no `D:response` change entries.
- `sync-collection` responses must not emit large sets of historical `404` tombstones for unchanged state.

If a report is unsupported for a resource, server returns standards-appropriate error status with DAV error body.

## Status Behavior
- `200` successful read/report/property retrieval
- `201` object created by `PUT`
- `204` successful delete/update with no body where applicable
- `207` multi-status for PROPFIND/REPORT responses
- `401` unauthenticated
- `403` authenticated but forbidden
- `404` resource not found
- `405` method not allowed on resource
- `409` parent/resource state conflict
- `412` precondition failed (etag/if-match semantics)
- `415` unsupported media type

## Content Handling
- Event objects use `text/calendar` payloads with RFC 5545-compatible `VCALENDAR`.
- Authenticated CalDAV object responses (`GET`, `REPORT`, `calendar-multiget`) return full event details for both public and private events.
- Unsupported component types should be rejected unless explicitly mapped.
- Server should normalize line endings/content as required by iCalendar compatibility.

## Concurrency
- Object resources must emit `ETag`.
- `If-Match` and `If-None-Match` must be honored on `PUT`.
- Lost-update prevention is required on concurrent writes.

## Recurrence Exception Behavior
- Deleting one recurrence occurrence must be represented as an exception for the existing series.
- The resulting data must remain one logical series (same `UID`), without splitting into separate series resources unless explicitly required by standards-compatible override semantics.

## Verification Requirements
Acceptance should verify:

- URI layout and discovery flows are stable.
- Required methods return expected statuses.
- REPORT responses include correct event sets.
- Collection `GET` returns `200` for authenticated probe requests.
- `sync-collection` no-change request (current token) returns `207` with zero change responses.
- `sync-collection` works with and without trailing slash on collection URI.
- Conditional write and etag behavior prevents stale overwrite.
