webcalsubscription calendarsics filescalendar sync

What Is webcal? Subscription Calendar URLs Explained

By AddCal Team

Click a link starting https:// that points at a calendar file and your browser downloads it. Click the same link starting webcal:// and your calendar app opens and offers to subscribe. Same server, same bytes, entirely different outcome.

Below: what the scheme does, why subscribing beats importing, how each major client handles refresh, how to publish a feed, and the security consideration most people miss.

What is webcal?

webcal:// is a URL scheme that tells the operating system "this URL points at a calendar feed, hand it to a calendar application to subscribe to, do not download it".

It is not a protocol. There is no webcal port, no webcal handshake, no webcal server software. When a client resolves webcal://example.com/team.ics, it substitutes https:// (or http:// for older or explicitly insecure feeds) and makes a completely ordinary HTTP GET request. What comes back is standard iCalendar data, exactly as described in the complete guide to ICS files.

It is also not a standard. There is no RFC for webcal. Apple introduced it, everyone else adopted it because it solved a real problem, and it has been de facto universal ever since without being formally specified. In practice it works reliably.

Why the scheme is needed at all

Browsers treat an HTTPS URL ending in .ics as a file to download, which is the wrong outcome when the publisher wants you subscribed rather than holding a snapshot. There is no HTTP header that reliably means "subscribe to me": Content-Type: text/calendar gets you close on some platforms and does nothing on others. Registering a custom scheme sidesteps the browser entirely, handing the URL to whichever application claims webcal.

Subscribing vs importing

This is the actual decision, and the scheme is just the mechanism for expressing it.

Import (file)Subscribe (URL)
What you getA copy, owned by youA live mirror, owned by the publisher
UpdatesNeverOn each refresh
Deletions upstreamStay in your calendar foreverDisappear from your calendar
Editable by youYesNo, read-only
Removing itDelete each event, or the calendarUnsubscribe, one action
Works offlineYesYes, cached copy

The row that matters most is the second. An imported file is frozen at the moment of import. Publish a fixture list as a downloadable .ics, then postpone a match, and every person who downloaded it holds a wrong date with no way for you to reach them. Publish the same data as a feed and the correction propagates on the next poll.

The corollary is that subscribed events are read-only. Recipients cannot drag them, edit the title, or delete a single instance. For a published schedule that is usually correct. For something a recipient might want to personalise, it is a real limitation.

Refresh intervals by client

Feeds are polled, not pushed. There is no notification mechanism, so "how often does it update" is entirely down to the client, and the answer varies a lot.

Google Calendar

Google polls external feeds on its own schedule, typically around 24 hours, with no user-facing setting to change it. Observed intervals range from about 8 hours to several days, and clicking refresh in the UI does not force a re-fetch.

This is the single biggest constraint on subscription calendars. If your audience is mostly on Google, do not promise same-day updates. Google's "From URL" field also only accepts http and https, so publish both forms of your link, as covered in the Google Calendar guide.

Apple Calendar

Apple is the most configurable. On iOS, Settings > Apps > Calendar > Accounts > the subscribed calendar > Refresh lets you pick every 5 minutes, 15 minutes, hourly, daily or weekly. On macOS it is the calendar's Get Info panel. The catch is that iOS treats the setting as a target rather than a guarantee, deferring background fetches on battery or in Low Power Mode. Opening the Calendar app forces a check. Full detail in the Apple Calendar guide.

Outlook

Classic Outlook for Windows honours publisher hints. Two properties can advertise a poll frequency inside the feed itself:

X-PUBLISHED-TTL:PT1H
REFRESH-INTERVAL;VALUE=DURATION:PT1H

X-PUBLISHED-TTL is Microsoft's non-standard original. REFRESH-INTERVAL is the standardised equivalent from RFC 7986. Emit both, using an ISO 8601 duration such as PT1H for hourly or P1D for daily. Outlook enforces a floor of roughly an hour regardless of what you ask for. Outlook on the web and new Outlook are less predictable, often landing in the several-hours range. See the Outlook guide for the subscription setup path in each version.

Practical guidance

Design for a worst case of about 24 hours. Publish the hints anyway, because the clients that honour them will refresh faster and it costs you two lines. And if a change is genuinely urgent, email people. Do not rely on a poll.

How to build a webcal feed

The server side is straightforward. You need an HTTPS endpoint that returns iCalendar data.

Serve it with the right headers:

Content-Type: text/calendar; charset=utf-8
Content-Disposition: inline; filename="schedule.ics"
Cache-Control: max-age=3600

Avoid Content-Disposition: attachment, which nudges browsers toward downloading rather than handing off.

The body is a normal VCALENDAR with your events inside it, plus a few properties that matter specifically for feeds:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Your Org//Fixtures//EN
METHOD:PUBLISH
X-WR-CALNAME:First Team Fixtures
X-WR-CALDESC:All league and cup fixtures for the 2026 season
X-PUBLISHED-TTL:PT1H
REFRESH-INTERVAL;VALUE=DURATION:PT1H
...VEVENT components...
END:VCALENDAR

X-WR-CALNAME sets the calendar's display name in the subscriber's app. Without it, clients fall back to the URL, and your subscribers end up with a calendar called "feed.ics". It is non-standard but universally supported and worth including every time. METHOD:PUBLISH marks the content as informational rather than a scheduling request, which is what you want for a feed.

Two rules for the events themselves. First, keep UIDs stable. Clients match events by UID, so regenerating them on each request makes every poll a churn of deletions and re-additions, showing up as duplicate notifications and lost reminders. Derive the UID from your database identifier and never change it.

Second, include VTIMEZONE blocks for every TZID you reference, or use UTC timestamps ending in Z. Feeds are consumed in unknown locales, and a floating time will be wrong for most of them.

Once the feed is live, publish the webcal:// form as the primary subscribe link and the https:// form as a fallback. To check what a client will actually see, fetch the URL and drop the response into the ICS viewer, which surfaces structural errors, or use the ICS to CSV converter for a spreadsheet view.

Security and privacy: the URL is the credential

This is the part people miss, and it has caused real incidents.

Calendar clients do not reliably support authentication on subscribed feeds. Some handle HTTP Basic auth, most do not, and none handle OAuth or a login form. In practice, feed URLs are secured by being unguessable: a long random token embedded in the path or query string.

Which means anyone holding the URL can read the entire calendar, forever. Consider what that implies:

  • The URL travels in plain text through whatever channel you shared it in. Email, Slack, a shared doc, a screenshot of someone's settings screen.
  • It sits in your subscribers' device settings indefinitely. If a subscriber's laptop is compromised, so is the feed.
  • A private feed URL pasted into a public support forum or a bug report is now public.
  • There is no session to expire and no per-subscriber revocation unless you built one.

Sensible practices: use a high-entropy token of at least 128 bits, issue a distinct URL per subscriber so you can revoke individually, support easy rotation, serve only over HTTPS, and rate-limit the endpoint since a leaked URL is a free scraping target. If a feed carries sensitive scheduling data, treat the URL exactly as you would treat a password, because functionally that is what it is.

When not to use webcal

Subscriptions are the right answer for ongoing, changing sets of events. They are the wrong answer in several common cases.

A single event. Asking someone to subscribe to a whole calendar for one webinar is a lot of friction, and the read-only constraint means they cannot even set their own reminder. Use an add to calendar link instead: one URL that detects the platform and drops that event into whichever calendar the recipient uses. That is the model on the add to calendar links page, and you can build one with the add to calendar link generator.

Events people need to personalise. If your recipients need to add notes, move things, or delete individual entries, they need their own copies. Offer a downloadable file.

Anything time-critical. A cancellation two hours before the event will not reach Google subscribers in time. Email them.

Where you need to know who is coming. A feed tells you nothing beyond an anonymous poll from an IP address. If attendance matters, you need a link with RSVP handling behind it.

The general rule: subscribe for schedules, link for individual events. Getting that split right removes most of the friction people experience with calendar sharing. More on the ongoing-schedule side is on the subscription calendars page, and if the terminology is still tangled, the ICS vs iCal vs webcal explainer untangles it.

If you want to test how a feed or a link behaves before publishing it, the free ICS generator will produce a valid file you can host and subscribe to yourself. It is a quick way to see the refresh behaviour of your own clients before you ask anyone else to trust it.

Last updated on July 22, 2026

Continue reading

Browse all articles