Skip to main content
CalDAV, the published standard

The calendar protocol nobody owns.

Apple Calendar speaks CalDAV. Fastmail speaks it. Your own Nextcloud speaks it. Event Schedule speaks it too, in six standard requests against a URL you type in yourself. No partnership, no API key, no permission from anyone.

Free on every plan Both directions, or one HTTPS only Selfhost to selfhost
Specification RFC 4791 / CalDAV
Protocol
CalDAV over HTTP

Calendaring extensions to WebDAV. Published, stable, and implemented independently at both ends.

Transport
HTTPS, required

A plain http:// address is refused before a single request leaves the building.

Auth
Basic, over TLS

Your username and a password, ideally an app password. Stored encrypted and never shown back to you.

Payload
iCalendar VEVENT

The same .ics text your calendar app already understands. No private format in the middle.

Discovery
PROPFIND

Three property requests turn one server URL into the list of calendars you pick from.

Owner
Nobody

Which is the whole point. There is no partnership to renew and no API key to be revoked.

Free CalDAV sync is on the free plan, in both directions, on the hosted service and on your own server alike.

§ 1Interoperability

Not a list of partners. A list of clients.

These are the three hostnames the connection form suggests, and the honest fourth cell. Nothing here was negotiated with anybody.

caldav.icloud.com

Apple Calendar

iCloud is one of the three hostnames suggested on the connection form. Generate an app-specific password in your Apple account rather than using your main one.

caldav.fastmail.com

Fastmail

Also suggested on the form, and also happier with an app password than with your account password.

your-server/remote.php/dav

Nextcloud

Your own server, your own data. Pair it with a selfhosted Event Schedule and no third party touches your calendar at all.

PROPFIND /

Anything conformant

Radicale, or any other server that answers the standard requests. There is no vendor-specific code here to wait for, which is why this list is not a list of partners.

The connection lives on the schedule, set up once by its owner under Integrations. The setup steps, in the guide

§ 2On the wire

Six requests. All of them in the spec.

This is the conversation, in the order it happens. A polled read opens with one more property request, which is what § 6 is about. Read both once and there is no magic left in the word integration.

PROPFIND

Who am I on this server?

current-user-principal

The first thing a CalDAV client asks. Your server answers with the address of your own principal, which is where everything else hangs from.

PROPFIND

And where do my calendars live?

calendar-home-set

One more property request, this time against your principal. The answer is the collection that holds your calendars.

PROPFIND

List them, then.

displayname, Depth: 1

One level down from the home collection, asking each child for its display name and its resource type. This is the entire content of what a settings page calls automatic discovery: you type a URL, and three property requests turn it into a dropdown.

REPORT

What is on this one?

calendar-query, time-range

A filtered report for VEVENT components inside a window: thirty days back and one year ahead. The response carries each event, and each event carries a tag saying which version of it you just read.

PUT

Here is one event.

{uid}.ics

One event, one resource, at a URL built from the identifier we generated for it. Saving the same event again is a PUT to the same URL, which is an edit rather than a duplicate.

DELETE

Take that one back off.

{uid}.ics

The same URL, the other verb. Deleting an event here removes the resource there, and so does turning a published event back into a draft.

No endpoint of ours

Not one of those six is an Event Schedule endpoint. They are the requests the standard defines, which is exactly why the same client reaches a server we have never heard of, running software written by somebody we have never met.

Tested before it is saved

A connection is only stored once a live request to your server has succeeded. A typo in the hostname fails on the form in front of you, rather than silently at three in the morning.

§ 3Direction

Four states. That is the whole enum.

You choose one per schedule. There is no fifth setting hiding behind an upgrade.

to

To the calendar

Events you publish here are written to your calendar. Nothing on your calendar is read.

from

From the calendar

Events on your calendar arrive here as real events on your schedule. Nothing is written back.

both

Both ways

Push on save, and read every quarter hour. A change on either side reaches the other.

unset

Off

The server stays connected and the credentials stay stored. The sync simply does not run.

It sits on the schedule

Free

The schedule owner adds the server, picks the calendar and picks the direction, and the sync runs on that connection. Every schedule you own is configured on its own, so a second one can point at a completely different calendar.

Drafts stay here

Free

Only published events are written out. Put an event back into Draft and it is removed from your calendar again, so a show you are still arguing about does not appear on anybody's phone.

§ 4Conformance

Property by property, both ways.

No mystery mapping. These are iCalendar property names, what Event Schedule writes into each one, and what it takes back out of one that arrives.

How each iCalendar VEVENT property maps to an Event Schedule event, outbound and inbound
Property Written out Read back in
UID An identifier we generate, kept on the row that links the event to this schedule The key. It is the reason a second visit is an edit and not a second event
SUMMARY The event name, exactly as you typed it Becomes the event name
DESCRIPTION The event description, or your own calendar description template if you set one Converted from HTML back to Markdown, and only when the calendar actually sent one
DTSTART The start, as an absolute instant in UTC Becomes the start, stored in UTC
DTEND Start plus the event duration, or two hours if none is set The length becomes the duration, but only when an end was actually sent
LOCATION The address of the venue on the event Matched against the venues on your schedule, and added as one if it is new
URL The public page for the event Not read back
CLASS PRIVATE, when the event is unlisted Not read back
DTSTAMP, CREATED, LAST-MODIFIED Stamped on every write Not read back

Time

Both ends store the instant

Times cross as UTC, which is what iCalendar is for: an absolute moment rather than a wall clock. Your client draws it in your own zone, and a colleague three timezones away sees the same show at their own eight o'clock.

Arriving events

Real events, not shadows

An event read from your calendar becomes a proper event on the schedule: accepted the moment it lands, given a URL from your own slug pattern, and filed under your default event category if you set one.

Sync is per event, not per date: a recurring event crosses as a single entry. Every individual date is covered by the published iCal feed for your schedule.

§ 5Timing

One side is instant. The other is polled.

CalDAV has no way for your server to call us, so the honest answer is a schedule rather than a webhook.

Outbound

The moment you save

Creating, editing or deleting an event goes out to your calendar as part of that save. Nothing to press, no queue to watch.

Inbound

Every fifteen minutes

A scheduled task walks the schedules set to read from a calendar. It takes a lock first, so a slow server can never leave two runs overlapping.

The window

30 days back, 365 ahead

The report asks for that range. An event edited long after it happened is outside it, and so is one scheduled more than a year out.

Worth knowing

Fifteen minutes is the interval for reading, not for writing. If you need a change on your public page the second you make it, make it here: outbound is part of the save. And if you want near-instant traffic in the other direction, Google Calendar and Outlook can push to us, because their APIs have somewhere to push to.

§ 6Idempotence

The hard part of two-way sync is doing nothing.

A loop that runs every quarter hour has to be able to decide that nothing happened. Four guards do that, and three of them are just properties the calendar already publishes about itself.

ctag

Collection tag

Before reading anything, one property request asks the calendar for its own tag. Unchanged since last time means nothing has happened there, and the run stops at that single request.

etag

Resource tag

Every synced event keeps its own tag on the link row. Unchanged means skip it. Changed means reconcile the fields, and even then the write is guarded, so nothing is saved unless a value really differs.

uid

One identifier, one event

A repeating resource arrives as several instances sharing a single identifier. The first is handled and the rest are left alone, so a weekly booking does not land as fifty two events.

appointment Pro

Bookings are not overwritten

An appointment booked on your booking page also appears on your calendar, and the calendar is never allowed to write back over it. A rescheduled booking cannot be dragged back to its old time by a stale copy.

There is one more guard behind those: an arriving event whose name and start time already exist on your schedule is treated as the same event and left alone, which catches the copy you typed in by hand the week before you connected anything.

§ 7Security considerations

Every specification has this section.

CalDAV asks you to hand a password to a program and let it talk to a server on your behalf. That deserves saying out loud, in the same plain terms as the rest of the page.

Disconnecting

Disconnecting is not deleting. It clears the credentials, the stored tag and the direction, and the sync stops. Every event already written to your calendar stays on your calendar, and everything already read in stays here.

HTTPS
Required, checked twice

Both the server URL and the calendar URL have to be https. The form rejects anything else, and the client refuses the settings again on its own account, so a connection without TLS is never stored in the first place.

Credentials
Encrypted at rest

Server, username, password and calendar URL are stored as one encrypted value, and held back from anything the application serialises, so they do not leak through an export or an error page.

Passwords
Use an app password

The setup screen recommends one, and it is the right advice: an app password can be revoked at your provider without touching the rest of your account, and the sync simply stops.

Addresses
Vetted, then pinned

Every address is checked against private and reserved ranges before it is contacted, including the ones your own server hands back during discovery, and the connection is pinned to the address that passed. Redirects are not followed, so a reply cannot send the client somewhere else.

Logs
Redacted

When a request fails, the response is truncated and stripped of authorization headers and password-shaped strings before a single line is written.

Requests
Throttled

Testing a server and listing its calendars are rate limited per account, so the connection form cannot be turned into a scanner.

§ 8Both ends open

An open standard on one side. Open source on the other.

It is the same argument made twice: you can read what the protocol promises, and you can read what we actually do with it.

Your server, both times

Selfhost to selfhost

Run Event Schedule on your own machine, point it at your own calendar server, and no third party is involved in your calendar at all. The usage metering that exists on the hosted service does not run on your own install, so nothing is counted and nothing is reported.

No cloud dependency Full data ownership Nothing metered

Read the client

The implementation is public

The requests it makes, the properties it asks for, the fields it writes and the guards that stop it looping are all in the repository. If you want to know exactly what happens to your calendar, you do not have to take our word for it.

How open source works here
  • Everything on this page is on the free plan. Zero platform fees on ticket sales is a separate promise, and also true.
  • Your audience does not need CalDAV or an account: every schedule publishes an iCal feed, and every event has its own iCal download, per date.
  • CalDAV, Google Calendar and Outlook are independent connections. Running one does not rule out the others.
§ 9Questions

Frequently asked questions

What people ask before they hand a calendar password to anything.

Which CalDAV servers are supported?

Any server that implements CalDAV. The connection form suggests hostnames for three of them, iCloud for Apple Calendar, Nextcloud and Fastmail, but there is no vendor-specific code behind them: Radicale or any other conformant server is reached by exactly the same requests. If your server answers a PROPFIND for its calendar home, it works.

Is CalDAV sync free?

Yes. CalDAV sync is on the free plan, in both directions, hosted or selfhosted. There is no calendar feature behind the paywall.

Does CalDAV sync work with selfhosted Event Schedule?

Yes, and it is the combination the protocol was made for. Both Event Schedule and your calendar server can run on your own infrastructure, with nothing in between and no account with anyone. The usage metering that exists on the hosted service does not run on your own install either, so nothing about your calendar is counted or reported anywhere.

How often does CalDAV sync run?

Outbound is immediate: saving, editing or deleting an event writes to your calendar as part of that save. Inbound runs every fifteen minutes, and starts by asking your calendar for its collection tag, so a calendar with nothing new costs one property request rather than a full read.

Is my CalDAV password stored securely?

Yes. The server URL, username, password and calendar URL are stored as a single encrypted value and are excluded from anything the application serialises, so they are not exposed through an export or an error page. Use an app-specific password from your provider rather than your account password, and you can revoke the connection from their side at any time.

What happens if I delete an event in my calendar app?

Nothing here. Reading from a calendar adds and updates events; it does not remove them. Deleting an event in Event Schedule does remove it from your calendar, and so does turning it back into a draft, but a deletion made in your calendar client leaves the event on your schedule for you to deal with. Google Calendar and Outlook sync do offer a policy for that; CalDAV does not.

Do recurring events send every date to my calendar?

No. Sync works at the event level, so a recurring event crosses as one entry rather than one per date. If you want every individual date in a calendar, use the published iCal feed for your schedule, which expands recurring events into one entry per date for the next ninety days, or the per-date iCal download on the event itself.

Can I use CalDAV and Google Calendar at the same time?

Yes. They are separate connections with separate directions on the same schedule, so you can push to one and read from the other, or run both ways on both. Each schedule you own is configured on its own, so two schedules can point at two entirely different calendars.

§ 10Conformance statement

One standard. Two calendars.

Pick a name, add your server, choose a direction. Both directions, hosted or on your own machine, at no cost on any plan.

.eventschedule.com
Get started free

No credit card required

Protocol
RFC 4791
Direction
to, from, both, off
Price
Free, every plan
Owner
Nobody