Generate an ICS feed from a spreadsheet

An .ics file and an .ics feed are different things. A file is a one-time import you can never correct. A feed is a stable URL serving text/calendar that Apple Calendar, Google Calendar, Outlook, and anything else that speaks iCalendar can subscribe to and refetch, which means it stays correctable for as long as the schedule exists.

CalRelay generates that feed from your spreadsheet. Point it at a Google Sheet share link or a CSV URL (polled, so it updates on its own) or paste the table in (a snapshot you refresh by re-pasting). Map the columns once and you get a hosted feed URL plus a subscribe page.

Free plan, no credit card. No account needed to see your events.

1

Point CalRelay at your table

Paste a Google Sheets share link, a CSV URL, or the table itself. URL sources are polled on a schedule so the feed regenerates as the data changes. Pasted tables are a snapshot you update by pasting again.

2

Map columns and verify the preview

Title and date are required. Time, end time, location, and description are optional. The preview shows every generated event, and any row that can't be confidently parsed is held with its raw values. The feed never contains guessed data.

3

Grab the feed URL

You get the raw ICS URL plus webcal:// links wired into one-click subscribe buttons on a hosted page. The URL is permanent, so schedule changes flow through it and nobody needs to re-subscribe.

What an ICS feed URL actually is

It's an iCalendar (RFC 5545) document served over HTTPS with the text/calendar content type, at a URL that doesn't change. Calendar clients subscribe to it and refetch it periodically. The webcal:// scheme is the same https URL with a different prefix, so that clicking it opens the OS calendar's subscribe flow instead of downloading a file.

That refetch loop is the whole difference between a feed and a file. A downloaded .ics is frozen at export time. A feed reflects the source every time a client checks back, which is what lets the spreadsheet stay the source of truth.

The standards details that actually bite

Stable UIDs: every event's UID is deterministic and permanent, so when a row changes, subscribers' clients update the existing event instead of stacking a duplicate next to it. Generators that mint fresh UIDs on every export are the reason edited schedules turn into calendars full of doubles.

All-day events are emitted as VALUE=DATE, not as midnight-to-midnight timed events. The midnight version is the classic bug that shows your event on the wrong day for anyone in another timezone. Timed events carry explicit timezone handling, with the feed's timezone set by you rather than inferred.

Nothing is guessed. A row with an ambiguous or unparseable date is held out of the feed and shown to you with its raw values, because a plausible-looking wrong event is worse than a visibly missing one.

Refresh cadence: two hops, be honest about both

There are two delays between an edit and a subscriber's screen. First, CalRelay re-reads a URL source hourly on the free plan and every 15 minutes on Pro. Second, each calendar client refetches the feed on its own schedule. Apple Calendar and Outlook are typically prompt and configurable. Google Calendar refetches external feeds whenever it decides to, which can take up to 24 hours, and no feed provider can get around that.

If the source becomes unreadable (revoked sharing, renamed columns, a dead URL), the feed freezes at its last good state and you're emailed. Subscribers keep a valid calendar instead of getting an empty response.

Questions

What's the difference between webcal:// and https://?
Same URL, same bytes. webcal:// tells the OS to open its calendar app's subscribe flow instead of downloading the file. CalRelay's subscribe page offers both, plus one-click buttons for Apple, Google, and Outlook that handle the scheme for you.
Can I consume the feed URL from my own tools?
Yes. It's a standard iCalendar document over HTTPS, so anything that can subscribe to or fetch an ICS feed can use it: calendar apps, room displays, scripts, other services. No authentication is required to read it, and the URL is unguessable.
Does the feed use RRULEs for recurring events?
No, there's no recurrence support. Recurring schedules are one row per occurrence, which emits one VEVENT per row. For spreadsheet-driven schedules that's usually the right model anyway, since exceptions become ordinary row edits instead of EXDATE surgery.
If I edit a row, do subscribers get a duplicate event?
No. UIDs are stable across regenerations, so clients treat the changed row as an update to the existing event. Deleting a row removes the event on the next refetch.
What are the limits?
Free: one feed, up to 50 events, source re-read hourly, free forever. Pro ($12/mo or $99/yr): 10 feeds, unlimited events, 15-minute re-reads.

Your schedule already exists.

Turn it into a calendar your whole roster can subscribe to. Takes about three minutes.

Create your free feed