Google CalDAV vs Calendar API: Which Should You Use?

Does Google Calendar support CalDAV? Yes. Compare Google CalDAV with the Calendar API, including sync, OAuth, event data, and multi-provider tradeoffs.

10 min read
A CalDAV XML request and Google Calendar API JSON describing the same calendar event

When I started hora, supporting every calendar provider looked like the responsible choice. A serious calendar app, I thought, should probably support Google, iCloud, Exchange, and every CalDAV server it could discover.

It also meant putting a translation layer between the app and the calendar most of its users already lived in.

I evaluated both approaches and chose the Google Calendar API because hora is intentionally Google-first. That decision narrowed the product, but it gave me a clearer contract: build the best Google Calendar experience I can on a Mac and accept that generic CalDAV accounts are not part of that promise.

If you are choosing between Google Calendar API vs CalDAV, the short answer is this: choose the Google Calendar API for a Google-first product that needs Google's event model and documented change notifications. Choose CalDAV when interoperability across providers is a core product requirement, not a future checkbox.

Google Calendar API vs CalDAV at a glance

DimensionGoogle Calendar APICalDAV
Best fitProducts built specifically around Google CalendarProducts that need a standards-based baseline across providers
Wire formatREST and JSONWebDAV, XML, and iCalendar
Change detectionwatch notification channels plus client-initiated reconciliationCollection sync, sync tokens, ETags, and server-specific strategies
Event modelGoogle's event resources and Google-specific fieldsiCalendar resources mapped through each server's CalDAV implementation
Authentication with GoogleOAuth 2.0 over HTTPSOAuth 2.0 over HTTPS
PortabilityGoogle-specificBroader provider portability, with implementation differences
Operational surfaceGoogle endpoints, quotas, expiring channels, and recovery syncDAV discovery, XML, iCalendar, validators, and provider differences

This is not a choice between a modern protocol and an obsolete one. It is a choice between provider depth and provider portability.

The Google Calendar API gives you a direct contract with one provider. CalDAV gives you an open protocol that several providers implement. Neither removes synchronization complexity. They place it in different parts of your product.

What CalDAV actually gives you

CalDAV is an open standard built on WebDAV and iCalendar. It defines how a client discovers calendar collections, reads and writes calendar resources, and performs calendar-specific queries. The base specification is RFC 4791, while RFC 6578 adds a collection synchronization report that can make delta updates more efficient.

That standards layer is valuable. A client can reuse the same conceptual model across iCloud, Fastmail, Nextcloud, Google, and other CalDAV servers instead of building a completely separate integration for every provider.

The important qualification is that CalDAV provides a portable baseline, not a zero-effort universal adapter.

Servers support different extensions, authentication flows, scheduling features, and interpretations of edge cases. A client still has to handle discovery, XML, iCalendar serialization, recurrence, ETags, sync tokens, and the behavior of each provider it claims to support.

Refresh behavior is also more nuanced than "CalDAV is slow." A server can support efficient collection deltas, and a well-built client can keep a local calendar fresh. What the core standard does not provide is a universal webhook equivalent to Google's events.watch. How quickly a change appears depends on the server, its extensions, and the client's synchronization strategy.

Google's CalDAV endpoint is one implementation of CalDAV, not the definition of the protocol. Google documents its own supported and unsupported features in the Google CalDAV support matrix. Those boundaries should not be generalized to every CalDAV server.

If hora's promise were "all your calendars in one place," this portability would be hard to ignore. That was not the problem I wanted to solve.

What the Google Calendar API gives you

The Google Calendar API exposes Google's calendar model directly through REST and JSON. That includes the normal event fields you would expect, but also Google-specific behavior such as event types, conference data, extended properties, calendar-list metadata, and the relationship between recurring masters, instances, and exceptions.

For synchronization, two primitives matter.

First, the API supports watch channels. Google sends an HTTPS notification when a watched resource changes. The notification is a hint, not the changed event. Calendar notifications contain headers and no event body, so the receiving application must make another API request to learn what changed. Google also states that a small percentage of notifications can be dropped, which means periodic reconciliation is still required.

Second, the API documents incremental synchronization with syncToken. A client performs an initial fetch, stores the nextSyncToken from the last page, and sends that token with later requests. The response includes changed and deleted resources. If Google invalidates a token and returns 410 Gone, the client must rebuild the synchronized state for that collection.

The official guides for push notifications and incremental synchronization describe the clean version of this loop. Production adds the recovery paths.

Why I chose the API for hora

The deciding factor was not that JSON is objectively better than XML. It was that a direct mapping to Google's resource model was easier to reason about in hora's Swift codebase than a DAV and iCalendar translation layer.

Google Calendar remains the source of truth. hora adds the native Mac layer around it: week and month views, menu bar access, widgets, keyboard workflows, focus planning, quick event creation, and local caching.

That product needs Google-specific details to survive the round trip. Event colors, conference links, attendee state, focus time, out-of-office events, working locations, moved recurring instances, and fields created by other clients should not disappear because my internal model was too generic.

The API does not make those problems vanish. It gives me the provider's actual vocabulary for solving them.

This was also a scope decision. Supporting only Google lets me spend engineering time on synchronization correctness and native Mac behavior instead of maintaining several provider adapters. The cost is equally clear: hora does not support iCloud, Exchange, or generic CalDAV accounts. If you need several providers in one app, a broader calendar client is a better fit.

I wrote more about the product side of that tradeoff in the hora Calendar 1.0 launch story and the platform side in Native App vs Electron and PWA.

How synchronization actually works in hora

The neat architecture diagram says: receive a push, run an incremental sync, update the UI. The real implementation is more conservative.

How Google Calendar change notifications reach hora while event content travels directly between the app and Google.

hora creates a separate events.watch channel for each active calendar. When that calendar changes, Google sends a headers-only notification to a small webhook. A Cloudflare Worker maps the channel to the affected calendar and forwards a silent push through APNs.

Google does not push event content into hora. The notification wakes the app, and the Mac fetches the actual calendar data directly from Google. The result is merged into a local SwiftData cache, so the calendar remains readable without a connection even though remote synchronization and edits still need the network.

Regular synchronization cycles use syncToken. After a push, hora currently clears the token for the affected calendar and performs a bounded reconciliation instead of trusting a tiny delta to contain every relevant recurring-event change. Periodic sync remains a safety net in case a notification is delayed or dropped.

That is less elegant than the first version of my diagram. It is also more honest.

The separate real-time Google Calendar sync article tells the original implementation story. The recovery behavior described here reflects the current code.

Recurring events changed my definition of clean sync

Recurring events were where the simple API comparison stopped being useful.

A recurring Google Calendar series with normal instances, a moved exception, and a cancelled occurrence.

A repeating meeting is not one event copied several times. It has a master with an RRULE, generated instances, moved exceptions, and cancellations. A moved instance keeps an originalStartTime that identifies where it belonged before the move. Editing "this and future" can require splitting one series into two while preserving or deliberately replacing later exceptions.

This matters when the app only caches part of the timeline. A change to the master can affect future dates that are not currently visible. An exception can arrive without the piece of context the UI needs. A deleted occurrence still has to remove the correct local instance.

CalDAV and iCalendar can represent recurrence through RRULE and RECURRENCE-ID. Recurrence is not a capability unique to the Google API. The advantage for hora is that Google's API exposes the exact master, instance, exception, and originalStartTime model used by its source of truth.

In practice, recurring-instance edits were the reason I stopped treating push plus syncToken as a complete answer. The conservative reconciliation after a push costs more requests, but it is easier to trust than a beautiful incremental-sync path that occasionally leaves the wrong meeting on screen.

Google's recurring events guide is useful here, but the production lesson only appeared after real calendars started producing exceptions.

The tradeoffs I accepted

Choosing the Google Calendar API concentrated complexity instead of eliminating it.

Provider lock-in is real. The event model, authentication, watch channels, and error handling are tied to Google. Supporting another provider later would still require a real integration, not a renamed adapter.

Push needs infrastructure. events.watch requires a public HTTPS webhook, channel registration, renewal before expiration, cleanup, and a route back to the correct device. APNs adds another delivery system with its own failure modes.

Notifications are hints. Google explicitly warns that push delivery is not guaranteed. A client that only syncs after a notification will eventually become stale. Recovery and periodic reconciliation are part of the feature.

OAuth and quotas become product work. Scope selection, consent, token storage, throttling, backoff, and quota errors affect the user experience. hora uses a per-account token bucket, bounded concurrency, exponential backoff with jitter, and cooldowns instead of assuming retries will solve every burst.

Direct access does not excuse a lossy model. Patching an attendee list, moving an event, or editing one recurring instance can change fields that are easy to miss. The API shows the provider semantics more clearly, but the client still has to preserve them.

CalDAV has a different bill: server discovery, DAV methods, XML, iCalendar parsing, provider variation, and the parts of scheduling each server implements. The right question is not which option has no complexity. It is which complexity belongs in your product.

Which one should your product use?

Choose the Google Calendar API when:

  • Google Calendar is the product's explicit source of truth.
  • You need Google-specific event types, conference data, or metadata.
  • Documented webhook channels and a direct resource model matter more than provider portability.
  • You are willing to own OAuth, channel renewal, quotas, and recovery sync.

Choose CalDAV when:

  • Supporting several calendar providers is a first-order requirement.
  • A standards-based integration surface matters more than one provider's deepest features.
  • Your team is prepared to handle DAV discovery, XML, iCalendar, and server differences.
  • The product can define a shared capability baseline and expose provider-specific limits honestly.

For a general calendar client, CalDAV can be the stronger architectural starting point. For a focused Google Calendar client, a generic abstraction can become the thing standing between the product and the behavior users expect.

What I would choose today

I would choose the Google Calendar API for hora again.

Not because it wins every row in a comparison table. It does not. I would choose it because the product is deliberately narrow, the source of truth is Google Calendar, and direct provider semantics have proved more valuable than theoretical portability.

If I were building an app whose central promise was "every calendar provider in one place," I would start from CalDAV and design the feature baseline around what multiple servers can reliably support.

For more implementation detail, read how I migrated hora to Google's Swift package after first building the client by hand.

If your calendar already lives in Google and you want to see what a focused API-first Mac client feels like, try hora Calendar on the Mac App Store.

FAQ

Is Google Calendar API better than CalDAV?

It is usually the better fit for a Google-first product because it exposes Google's resource model, watch channels, and incremental synchronization directly. CalDAV is often the better foundation when provider interoperability is more important than Google-specific depth.

Does Google Calendar support CalDAV?

Yes. Google provides a CalDAV endpoint over HTTPS with OAuth 2.0. Its implementation has a documented support matrix, so clients should verify the exact DAV, iCalendar, and scheduling features they need.

What is a CalDAV calendar?

A CalDAV calendar is a calendar collection exposed through an open protocol built on WebDAV and iCalendar. It lets compatible clients discover, query, create, update, and delete calendar resources across supporting servers.

Can CalDAV provide real-time calendar sync?

CalDAV can support efficient collection synchronization, but the core standard does not define a universal webhook like Google Calendar API watch channels. Update speed depends on the server, supported extensions, and the client's sync strategy.

Does Google Calendar API support incremental sync?

Yes. A client stores the nextSyncToken from a completed sync and sends it with later requests to retrieve changed and deleted resources. It still needs recovery logic for invalid tokens and missed push notifications.

When should a calendar app choose CalDAV?

Choose CalDAV when support for multiple providers is a core requirement and a shared standards-based baseline is more valuable than the deepest features of one provider. Expect some server-specific behavior even with a common protocol.

Related stories

Google Calendar API in Swift: The Package I Missed
Engineering

Google Calendar API in Swift: The Package I Missed

I hand-built a Google Calendar API client in Swift, then migrated hora to Google's GTLR library. See the code, tradeoffs, and rate-limit lessons.

Maciej Szamowski10 min read
How I Fixed SwiftUI Color Contrast with OKLCH and APCA
Engineering

How I Fixed SwiftUI Color Contrast with OKLCH and APCA

A TestFlight screenshot exposed unreadable calendar tiles. Here is how I rebuilt hora's SwiftUI color system with OKLCH, APCA-style checks, and tests.

Maciej Szamowski10 min read
Real-Time Google Calendar Sync on macOS
Engineering

Real-Time Google Calendar Sync on macOS

How hora uses Google Calendar watch channels, a Cloudflare Worker, APNs, and fallback polling to keep its native Mac calendar fresh and reliable.

Maciej Szamowski10 min read
Mobile Beta Sign-up

Want to stay updated?

Subscribe for information about iOS/iPadOS beta availability.