Skip to main content

How to Build an ICS Calendar Event That Imports Into Any App

A practical guide to making an .ics calendar event with the right VEVENT fields, time zones, and all-day handling so it imports cleanly into any calendar app.

Published By Li Lei
#ics #calendar #icalendar #vevent #productivity

How to Build an ICS Calendar Event That Imports Into Any App

There is a moment every webinar host, course instructor and event planner runs into: you have the date locked, the link ready, the room booked, and now you need 200 people to have the exact same entry on their calendar. You can ask each of them to type it in by hand, or you can hand them one file that does it for them. That file is an .ics, and once you understand the half-dozen lines inside it, you can produce one that drops cleanly into Google Calendar, Apple Calendar or Outlook without a single retype.

What an .ics file actually contains

An .ics file is plain text in the iCalendar format, defined by RFC 5545. Open one in a text editor and it is surprisingly readable. The wrapper is BEGIN:VCALENDAREND:VCALENDAR, and inside it sits one or more event blocks. Each event is a VEVENT, and a VEVENT holds a handful of fields:

  • DTSTART — when the event begins
  • DTEND — when it ends
  • SUMMARY — the title that shows on the calendar
  • LOCATION and DESCRIPTION — optional, the place and the notes
  • UID and DTSTAMP — a unique id and a creation timestamp so apps can tell two events apart

That is the whole core. Any calendar app that follows the spec — and Google, Apple and Outlook all do — reads those fields and creates the event. Because they share the same format, you build the file once and the same download works in all three. No per-app export, no separate Google version and Outlook version.

A worked example you can read line by line

Say you are scheduling a 30-minute design sync on June 20, 2026, from 2:00pm to 2:30pm UTC. The VEVENT for that looks like this:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Toolora//ICS Event Generator//EN
BEGIN:VEVENT
UID:9f3c1a7e-2026@toolora.info
DTSTAMP:20260613T091500Z
DTSTART:20260620T140000Z
DTEND:20260620T143000Z
SUMMARY:Design sync
LOCATION:Zoom
DESCRIPTION:Review the new event form layout
END:VEVENT
END:VCALENDAR

Read it top to bottom and nothing is mysterious. The timestamps are written as YYYYMMDDTHHMMSSZ. The trailing Z means UTC — Zulu time — so every importer agrees on the absolute moment no matter where the attendee sits. SUMMARY becomes the event title, LOCATION becomes the place field, and DESCRIPTION fills the notes. Save those lines as design-sync.ics, double-click it, and the event appears.

Time zones and the UTC trick

Time is where most hand-built .ics files go wrong. There are three ways to write a moment, and they behave very differently:

  1. UTC — the Z suffix above. This is the safe default for anyone working across regions, because the absolute instant never shifts. A 140000Z start is 10:00am in New York and 3:00pm in London, computed correctly on each device.
  2. A named zoneDTSTART;TZID=America/New_York:20260620T100000. This pins the event to a specific city's clock, which is what you want for something local that should respect daylight saving.
  3. Floating — no zone at all, just 20260620T100000. The event shows as whatever local clock the importer happens to be on. Fine for a personal "take vitamins at 9am" note, wrong for a cross-country call.

If you are inviting people in different countries, write UTC and state the local times in the description, or convert each attendee's time first. I keep the time zone converter open in a second tab whenever I prep an invite for a distributed team — it takes ten seconds to confirm that 2pm UTC is the slot I actually meant for everyone, and it has saved me from at least one meeting that nobody showed up to.

All-day events and the exclusive end date

All-day events have their own rule that trips people up. Instead of a time, you write a date-only value: DTSTART;VALUE=DATE:20261225. No hours, no minutes — the spec reads that as a full-day band.

The catch is the end date. iCalendar treats DTEND as exclusive, meaning the morning the event is already over. So a single all-day event on December 25 must end on December 26:

DTSTART;VALUE=DATE:20261225
DTEND;VALUE=DATE:20261226

Set the end to the same day as the start and the event collapses to nothing. This is the most common mistake when typing the file by hand, which is exactly why a generator that fills DTEND for you is worth the few seconds. Birthdays, public holidays, deadlines and multi-day trips all live in this date-only form.

Turning the file into an "add to calendar" link

A raw .ics is great as an email attachment — anyone who opens it gets the two-tap add. But you can go one step further and put an "add to calendar" action on a landing page, a confirmation screen or a campaign email. The mechanics are simple: host the .ics file at a URL and link to it. When a reader clicks, their browser hands the file to their default calendar app, which offers to add the event. For Google specifically you can also build a template link with the title and times in the query string, but the hosted .ics is the universal route that works for Apple and Outlook users too.

This is the difference between "here is when we meet" buried in body text and a button that saves the slot before the reader closes the tab. After someone books a demo or buys a ticket, the appointment is on their calendar with a working reminder, instead of a date they meant to copy and forgot.

Build it without leaking the details

You can write all of this by hand, but the escaping rules — commas, semicolons and line breaks inside SUMMARY or DESCRIPTION each need a backslash — are tedious and easy to get wrong, and a single malformed line can make an importer reject the whole file. The ICS Event Generator takes a form, formats every timestamp the way the spec wants, escapes your text, stamps a fresh UID and DTSTAMP, and wraps a VALARM around your reminder. You copy the text or download the file with one click.

Worth knowing: the whole file is assembled by JavaScript inside your browser tab. The title, the guest list, the location and your notes never touch a server. The one thing to watch is the share-by-link feature, which encodes the fields in the URL — so for a confidential event, use the download or copy button and send the file directly rather than pasting a link into chat.

Once you have seen the inside of a VEVENT, the format stops being a black box. A title, a start, an end, and a Z for UTC will carry an event into any calendar on earth — and the rest is just polish.


Made by Toolora · Updated 2026-06-13