[ Back to all articles ](https://addcal.co/blog.md)

ics files icalendar rfc 5545 calendar formats guides

What Is an ICS File? A Complete Guide to the iCalendar Format
=============================================================

By Tom •May 4, 2025

You have almost certainly received an ICS file. It arrives attached to a meeting invitation, or downloads when you click "Add to Calendar" on a ticketing page. You double-click it, your calendar app opens, and an event appears. Most of the time it just works.

When it doesn't, ICS files become genuinely confusing. The event lands an hour off. Only the first date of a weekly meeting shows up. Nothing happens at all when you tap the attachment on your phone. Understanding what is actually inside the file makes all of those failures much easier to diagnose.

What follows is the format itself, where it came from, what every important line inside a file does, and where it falls down.

What is an ICS file?
--------------------

An ICS file is a plain text file describing calendar data: events, to-dos, free/busy information, journal entries and timezone definitions. The `.ics` extension stands for iCalendar, the specification the file follows. Open one in a text editor and you see readable key/value pairs, not binary gibberish.

That is the most useful thing to know about the ICS file format. It is text. You can read it, diff it, grep it, and fix it by hand. When someone says "the event imported at the wrong time", the answer is almost always visible in the raw file.

The format is registered under the MIME type `text/calendar`, which is how mail clients and servers know to hand the file to a calendar app rather than a text editor.

ICS file structure: the anatomy of a file
-----------------------------------------

Every ICS file is built from nested components. Each component starts with `BEGIN:` and ends with a matching `END:`. The outermost is always `VCALENDAR`, and inside it you find one or more `VEVENT`, `VTODO`, `VJOURNAL`, `VFREEBUSY` or `VTIMEZONE` components.

Here is an annotated example of a small but complete file:

```
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//AddCal//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VTIMEZONE
TZID:Europe/London
BEGIN:STANDARD
DTSTART:19701025T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19700329T010000
TZOFFSETFROM:+0000
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:9f2c1a70-team-standup@addcal.co
DTSTAMP:20260114T093000Z
DTSTART;TZID=Europe/London:20260119T093000
DTEND;TZID=Europe/London:20260119T094500
SUMMARY:Weekly product standup
LOCATION:Meeting Room 2\, Level 4
DESCRIPTION:Agenda in the shared doc. Bring blockers.
RRULE:FREQ=WEEKLY;BYDAY=MO;COUNT=12
STATUS:CONFIRMED
SEQUENCE:0
BEGIN:VALARM
TRIGGER:-PT10M
ACTION:DISPLAY
DESCRIPTION:Standup in 10 minutes
END:VALARM
END:VEVENT
END:VCALENDAR
```

Every line in that file earns its place. Working through the important ones:

### The VCALENDAR wrapper

- `VERSION:2.0` is required and means "this is iCalendar as defined by RFC 5545". There is no version 3.
- `PRODID` identifies the software that produced the file. It is required, and it is invaluable when debugging: it tells you which system generated the ICS file you are staring at.
- `CALSCALE:GREGORIAN` is the default and usually omitted.
- `METHOD` is optional and hugely consequential. More on that below.

### VEVENT and its core properties

**`UID`** is the unique identifier for the event. It must be globally unique and it must stay stable across updates. This is the single most important property in the file for anything beyond a one-off import: when you re-send an updated ICS file with the same `UID`, a compliant client updates the existing event rather than creating a second copy. When generators lazily emit a fresh random `UID` every time, you get duplicates.

**`DTSTAMP`** is when this particular representation of the event was created, always in UTC. Paired with `SEQUENCE`, it lets clients work out which of two versions of the same `UID` is newer.

**`DTSTART` and `DTEND`** are the start and end. They come in three flavours, and mixing them up is responsible for most timezone bugs:

- **UTC**, with a trailing Z: `DTSTART:20260119T093000Z`. Unambiguous, but loses the original local time.
- **Local time with a timezone reference**: `DTSTART;TZID=Europe/London:20260119T093000`. Requires a matching `VTIMEZONE` in the same file. This is the correct choice for recurring events, because "every Monday at 09:30" should stay at 09:30 after the clocks change.
- **Floating local time**, with no Z and no TZID. Means "09:30 wherever the viewer is". Rarely what you want.

**All-day events** use a fourth form: `DTSTART;VALUE=DATE:20260119`. The critical rule here is that `DTEND` is *exclusive*. A single-day event on 19 January has `DTSTART;VALUE=DATE:20260119` and `DTEND;VALUE=DATE:20260120`. Getting this wrong is why all-day events sometimes render as one day short or one day long.

**`SUMMARY`** is the event title. **`LOCATION`** is a free-text location string. **`DESCRIPTION`** is the body. All three are plain text with a specific escaping rule: commas, semicolons and backslashes must be escaped with a backslash, and newlines are written as a literal `\n`. That is why the example above has `Meeting Room 2\, Level 4`.

**`RRULE`** defines recurrence. It is a compact grammar of its own: `FREQ` (DAILY, WEEKLY, MONTHLY, YEARLY), plus modifiers such as `INTERVAL`, `BYDAY`, `BYMONTHDAY`, `BYSETPOS`, and a terminator of either `COUNT` or `UNTIL`. "Last Friday of every month" is `FREQ=MONTHLY;BYDAY=-1FR`. Individual instances can be removed with `EXDATE` or overridden with a second `VEVENT` carrying the same `UID` plus a `RECURRENCE-ID` naming the instance being replaced.

**`VALARM`** is a nested component describing a reminder, where `TRIGGER:-PT10M` means ten minutes before the start. Most modern clients ignore alarms in imported files and apply the user's own default instead, which is sensible: nobody wants an emailed invitation setting alarms on their phone.

**`ATTENDEE` and `ORGANIZER`** carry email addresses and participation status, and only matter for actual invitations. An attendee line typically looks like `ATTENDEE;CN=Sam Lee;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:sam@example.com`.

### Line folding at 75 octets

RFC 5545 says no line may exceed 75 octets, excluding the line break. Longer lines are "folded": broken at any point and continued on the next line, which must begin with a single space or tab. Parsers unfold by removing the CRLF and the following whitespace character.

Two practical consequences. First, the limit is in octets, not characters, so a fold must not split a multi-byte UTF-8 sequence. Second, a naive line-by-line parser will mangle long descriptions and URLs: unfold first, then parse. To inspect a file without writing code, the [free ICS viewer](https://addcal.co/tools/ics-viewer.md) unfolds and pretty-prints any `.ics` you drop into it. Lines are also required to end with CRLF, not bare LF, and strict parsers do enforce it.

METHOD:REQUEST vs METHOD:PUBLISH
--------------------------------

This one property changes how the entire file is treated, and it is the difference between "here is an event you might like" and "you are invited to this meeting, please reply".

- **`METHOD:PUBLISH`** means the file is informational. Clients import it as a plain event. No RSVP buttons appear, no reply email is generated. This is what you want for a public event, a webinar listing, or anything you are sharing broadly.
- **`METHOD:REQUEST`** means the file is a scheduling request, governed by iTIP. Combined with `ORGANIZER` and `ATTENDEE` lines, clients render Accept / Tentative / Decline buttons and send a `METHOD:REPLY` back to the organiser. Outlook in particular treats these very differently from published events.
- **`METHOD:CANCEL`** withdraws a previously sent event, matched on `UID`.

A common mistake is sending a marketing event to a thousand people with `METHOD:REQUEST` and every recipient as an attendee. Everyone then sees the full recipient list, and every RSVP fires an email at you. Use `PUBLISH` for broadcast, `REQUEST` for real meetings.

Where you meet ICS Files in the wild
------------------------------------

- **Email invitations.** Attached as `invite.ics` and rendered inline by Gmail, Outlook and Apple Mail.
- **Add to Calendar buttons.** Ticketing sites, webinar platforms and event pages usually offer a downloadable `.ics` alongside deep links into Google and Outlook. If you are building one, the [add to calendar link generator](https://addcal.co/tools/add-to-calendar-link-generator.md) produces the whole set from one form.
- **Subscription feeds.** A URL that serves an ICS document over HTTPS and gets re-fetched periodically. Sports fixtures, [school terms](https://addcal.co/blog/how-to-sync-your-blackbaud-calendar-with-google-outlook-and-apple-calendar.md), on-call rotas and project deadlines all commonly ship this way. See [how webcal and subscription calendar URLs work](https://addcal.co/blog/what-is-webcal-subscription-calendar-urls.md) for the mechanics.
- **Exports and backups.** Every major calendar app can export to ICS, which makes it the standard migration path between platforms.

Limitations of ICS Files
------------------------

The format is thirty years old and it shows in a few places.

**An attached file is a snapshot, not a subscription.** Once someone has imported your ICS attachment, you have no way to change it. Move the venue and every recipient is still holding the old address. You can re-send with the same `UID` and a higher `SEQUENCE`, but only if you know everyone's email address and only if their client honours the update, which is inconsistent in practice. For anything that might change, a link that resolves live beats a file every time. That is the core argument for [add to calendar links](https://addcal.co/solutions/add-to-calendar-links.md) over raw file downloads.

**Mobile clients handle attachments badly.** Tapping a `.ics` file on Android often opens a file manager rather than a calendar. On iOS it usually works from Mail but not from every third-party app. Neither [Google Calendar's mobile app](https://addcal.co/blog/how-to-add-an-ics-file-to-google-calendar.md) nor most webmail clients offer a true import path.

**Rich content does not survive.** `DESCRIPTION` is plain text. Some clients read the non-standard `X-ALT-DESC;FMTTYPE=text/html` property, most do not. Assume formatting will be flattened.

**Recurrence support is uneven.** Every client implements `RRULE`, but complex rules using `BYSETPOS` or unusual `WKST` values expand differently across implementations. Timezone handling around DST transitions is another source of one-hour drift.

How to open an ICS file
-----------------------

Double-clicking is usually enough. On Windows the file opens in Outlook or the Calendar app, on macOS in Apple Calendar, and on most Linux desktops in whichever application is registered for `text/calendar`. The event appears in a preview window and you confirm before it is saved.

To read the file rather than import it, open it in any text editor. An ICS file is plain text, so Notepad, TextEdit or VS Code will all show you the raw properties. This is the fastest way to diagnose a bad import: the wrong time, a missing recurrence or a duplicate is nearly always visible in the source. If you would rather see it parsed into labelled fields, the [free ICS viewer](https://addcal.co/tools/ics-viewer.md) unfolds the file and lists every property without uploading it anywhere.

Platform-specific import paths differ more than you would expect, particularly on mobile. The walkthroughs for [Google Calendar](https://addcal.co/blog/how-to-add-an-ics-file-to-google-calendar.md), [iPhone and Apple Calendar](https://addcal.co/blog/how-to-add-an-ics-file-to-iphone-apple-calendar.md) and [Outlook](https://addcal.co/blog/how-to-add-an-ics-file-to-outlook.md) cover the quirks of each.

How to create an ICS file
-------------------------

Every major calendar application can export one, though the menus are less consistent than you would hope.

**Google Calendar** exports from a web browser only, not the mobile app. Settings, then Import & export, then Export downloads a ZIP containing one `.ics` per calendar. To export a single calendar as a bare `.ics` instead, hover it in the calendar list, then More, then Settings and sharing, then Export calendar.

**Apple Calendar** on macOS exports a whole calendar, not an individual event. Select the calendar's name in the calendar list, then File, then Export, then Export. If the list is hidden, View, then Show Calendar List. Avoid File, then Export, then Calendar Archive: that produces an `.icbu` archive of every calendar rather than an `.ics`, which is a common trap.

**Outlook** depends on which Outlook you are running. In classic Outlook for Windows, File, then Save Calendar, then More Options lets you set the date range and level of detail before saving an `.ics`. Outlook on the web has no equivalent save command: instead use Settings, then Shared calendars, then Publish a calendar, which gives you an ICS link rather than a file. In the new Outlook for Windows the reliable route is still classic Outlook, reachable from the Help menu where the switch is offered.

Writing a file by hand is also entirely reasonable, because the format is text. The minimum viable file is a `VCALENDAR` wrapper containing a single `VEVENT` with `UID`, `DTSTAMP`, `DTSTART` and `SUMMARY`. Everything else is optional. The annotated example above is a complete, valid file you can copy and edit.

Two things to get right if you do hand-roll it: keep the `UID` stable across updates so clients update rather than duplicate, and either use UTC with a trailing `Z` or include a matching `VTIMEZONE` for any `TZID` you reference. The [ICS generator](https://addcal.co/tools/ics-generator.md) handles both automatically if you would rather fill in a form, and for anything you might need to change later, an [add to calendar link](https://addcal.co/solutions/add-to-calendar-links.md) stays editable after people have added it.

ICS file FAQs
-------------

### What does ICS stand for?

ICS is short for iCalendar, the specification the file implements. The format is also referred to as iCal or by its MIME type `text/calendar`. All of these describe the same RFC 5545 format.

### Are ICS and iCal the same thing?

Effectively yes, though the terms get muddled. ICS is the file extension, iCalendar is the format, and iCal was the name of Apple's calendar application before it was renamed to Calendar in 2012. People use iCal to mean any of the three. Webcal is genuinely different: it is a URL scheme for subscribing to a feed rather than a file format. [ICS vs iCal vs webcal](https://addcal.co/blog/ics-vs-ical-vs-webcal-explained.md) covers the distinction in full.

### Can an ICS file contain more than one event?

Yes. A single `VCALENDAR` can hold any number of `VEVENT` components, which is how a full calendar export fits into one file. Note that Google Calendar caps imports at 1MB, so large exports sometimes need splitting before they will upload.

### Why did my event import at the wrong time?

Almost always a timezone problem. Either `DTSTART` was written in floating local time with no timezone reference, or it used a `TZID` whose matching `VTIMEZONE` block is missing from the file. Open the file and check whether `DTSTART` ends in `Z`, carries a `TZID`, or has neither.

### Why do I get duplicate events when I reimport a file?

Because the `UID` changed. A compliant client matches on `UID` and updates the existing event when it recognises one. Generators that emit a fresh random `UID` on every export defeat that, so each import creates another copy.

### Is it safe to open an ICS file?

The format is inert plain text with no scripting, so opening one carries little risk in itself. Ordinary caution applies to the contents: an event `DESCRIPTION` or `URL` can link anywhere, and calendar invitations from unknown senders are a known phishing vector. Read it in a text editor first if you are unsure.

A short history: RFC 5545 and friends
-------------------------------------

iCalendar started life as RFC 2445 in 1998, produced by an IETF working group with input from Lotus, Microsoft and Netscape. The goal was interoperability: a way for calendar systems from different vendors to exchange scheduling data without a shared server.

RFC 2445 was replaced by **RFC 5545** in 2009, which is the version everything implements today. It tightened ambiguous language, clarified recurrence behaviour and fixed a number of edge cases. Later documents extended it: RFC 5546 defines iTIP (invitations, replies and cancellations), RFC 6047 defines iMIP (iTIP carried over email), and RFC 7986 added properties such as `COLOR`, `IMAGE` and `CONFERENCE`.

In practice, "an ICS file" means "a file following RFC 5545", with a scattering of non-standard `X-` properties vendors have bolted on. Apple adds `X-APPLE-STRUCTURED-LOCATION`, Microsoft a small army of `X-MICROSOFT-` properties. Everyone else ignores them, which is what the spec tells parsers to do with properties they do not recognise.

Further reading
---------------

If you are trying to get a specific file into a specific app, these walkthroughs cover the platform quirks in detail:

- [Adding an ICS file to Google Calendar](https://addcal.co/blog/how-to-add-an-ics-file-to-google-calendar.md), including the mobile gap and the 1MB import limit.
- [Adding an ICS file to iPhone and Apple Calendar](https://addcal.co/blog/how-to-add-an-ics-file-to-iphone-apple-calendar.md), including subscribed calendars and refresh intervals.
- [Adding an ICS file to Outlook](https://addcal.co/blog/how-to-add-an-ics-file-to-outlook.md), where the Open, Import and Subscribe choices each behave differently.
- [ICS vs iCal vs webcal](https://addcal.co/blog/ics-vs-ical-vs-webcal-explained.md), if the terminology has ever tripped you up.

And if you want to look inside a file right now, drop it into the [ICS viewer](https://addcal.co/tools/ics-viewer.md) to see every property parsed out, or use the [ICS to CSV converter](https://addcal.co/tools/ics-to-csv.md) if you would rather have the events in a spreadsheet.

Once you can read the format, most calendar problems stop being mysterious. Wrong time? Check `DTSTART` and whether a `VTIMEZONE` is present. Duplicates? Check `UID` stability. Only one instance imported? Check the `RRULE`. The answer is nearly always sitting in the text. And if you would rather not hand-write any of it, the [free ICS generator](https://addcal.co/tools/ics-generator.md) builds a spec-compliant file from a simple form, or you can share an event as a link that stays editable from [addcal.co](https://addcal.co/).

 Last updated on August 14, 2026

![Tom](https://cdn.addcal.co/static/authors/atymic.jpg)### Tom

Founder

Built Calndr.link in 2020 because an event link broke in Outlook and it annoyed him enough to fix it properly. Six years later he can tell you exactly how each calendar app mangles a timezone, which is a worse party trick than it sounds. Otherwise found hanging off a rock somewhere in Australia.

[GitHub](https://github.com/atymic)[X](https://x.com/atymic)

###  Related articles 

[ICS vs iCal vs webcal: What's the Difference? One is a file format, one is a defunct Apple app name that stuck, and one is a URL scheme. They get used interchangeably and they are not the same thing. Here is what each term actually means and which to use when.](https://addcal.co/blog/ics-vs-ical-vs-webcal-explained.md)[What Is webcal? Subscription Calendar URLs Explained The webcal scheme tells a device to subscribe to a calendar rather than download it. It is not a protocol and it was never standardised, but it is universally supported. How it works, refresh intervals per client, how to build a feed, and why the URL is the credential.](https://addcal.co/blog/what-is-webcal-subscription-calendar-urls.md)[How to Add an ICS File to Outlook Outlook is four different products, and each handles ICS files differently. Classic Outlook alone offers three import options with three different outcomes. Here is what each one does and how to fix the usual timezone and recurrence problems.](https://addcal.co/blog/how-to-add-an-ics-file-to-outlook.md)

[ Browse all articles ](https://addcal.co/blog.md)
