TL;DR: Compose the iCalendar text (BEGIN:VCALENDAR … VEVENT … END:VCALENDAR), Base64-encode it, and attach it as invite.ics (text/calendar) to Send an email (V2). The recipient adds the event to any calendar - Outlook, Google, Apple - with one click. Standard actions only, no premium.

Not every “put this in my calendar” needs a full Graph API event on someone else’s mailbox. Often you just want to hand the recipient a portable calendar entry they can accept themselves - a webinar, a deadline, a pickup slot. The open iCalendar format (RFC 5545) does exactly that, and you can generate a valid .ics file in a flow with nothing more than a Compose action.

💡 Challenge

You want to send someone a calendar event they can add to their calendar - regardless of whether they use Outlook, Google, or Apple - without write access to their mailbox and without a premium connector. Creating the event directly via Graph or the Outlook connector writes to your calendar or needs delegated permissions; it doesn’t produce a portable file you can simply email out.

✅ Solution

Generate a standards-compliant iCalendar (.ics) file yourself. An .ics is just plain text following RFC 5545: a VCALENDAR wrapper containing at least one VEVENT. Build that string in a Compose action, Base64-encode it, and attach it to Send an email (V2) with the text/calendar extension. Any mail client recognises it and offers a one-click “Add to calendar”.

🔧 How it’s done

1. Compose the iCalendar text.

🔸 Add a Compose action (call it ICS) with a body like this. \n marks line breaks - each property is its own line:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//powerplatformtip//EN
METHOD:PUBLISH
BEGIN:VEVENT
UID:@{guid()}
DTSTAMP:@{formatDateTime(utcNow(),'yyyyMMddTHHmmss')}Z
DTSTART:20260805T130000Z
DTEND:20260805T140000Z
SUMMARY:Project Kickoff
DESCRIPTION:Kickoff call for project X
LOCATION:Microsoft Teams
END:VEVENT
END:VCALENDAR

🔸 Mandatory bits: the file needs at least one VEVENT (without it, Outlook treats the file as a calendar folder, not an appointment), plus UID, DTSTAMP, and DTSTART. Times ending in Z are UTC in the yyyyMMddTHHmmssZ pattern.

2. Make the timestamps dynamic (optional).

🔸 For a data-driven event, build DTSTART/DTEND from your own values: @{formatDateTime(variables('StartUtc'),'yyyyMMddTHHmmss')}Z. Convert local times to UTC first (e.g. convertTimeZone(...,'UTC')) so the Z suffix is truthful.

3. Base64-encode the content.

🔸 The Outlook attachment expects Base64. Use the expression base64(outputs('ICS')) in the next step - no separate action needed.

4. Attach it to the email.

🔸 Send an email (V2)Add new parameter → Attachments. Set Attachments Name to invite.ics (the .ics extension is what triggers calendar handling) and Attachments Content to @{base64(outputs('ICS'))}. Fill in To / Subject / Body as usual.

🎉 Result

The recipient gets an email with an invite.ics attachment. One click adds “Project Kickoff” to their calendar - in Outlook, Google Calendar, or Apple Calendar alike - correctly timed, titled, and located. No premium connector, no mailbox permissions, and it works cross-platform because it’s the open iCalendar standard.

🌟 Key Advantages

🔸 Cross-platform: RFC 5545 is understood by every major calendar client, not just Outlook.

🔸 No premium, no permissions: just Compose + Send an email (V2) - nothing written to anyone’s mailbox.

🔸 Fully dynamic: title, times, location and description all come from flow data, so one flow serves every event.

🔸 Portable artifact: the .ics is a self-contained file you can also save to SharePoint/OneDrive or return from the flow.

🛠️ FAQ

Q1: PUBLISH vs REQUEST - which METHOD should I use?

Use METHOD:PUBLISH for a simple “add this to your calendar” (no RSVP). Use METHOD:REQUEST when you want a real meeting invitation with Accept/Decline - that additionally requires an ORGANIZER line and one ATTENDEE line per invitee, and responses flow back to the organizer.

Q2: The event imports at the wrong time - what’s wrong?

Almost always a time-zone mismatch. The Z suffix means the value is UTC. Either provide true UTC times (convert with convertTimeZone(...,'UTC')), or drop the Z and add a TZID (e.g. DTSTART;TZID=Europe/Zurich:20260805T150000) together with a matching VTIMEZONE block.

Q3: Do I need CRLF line endings?

The spec calls for CRLF (\r\n). Most clients (including Outlook) also accept plain LF, but to be strictly compliant build the line breaks with decodeUriComponent('%0D%0A') instead of relying on the editor’s newline.

Q4: My SUMMARY or DESCRIPTION breaks the file.

In iCalendar TEXT values, commas, semicolons and backslashes must be escaped (\, \; \\) and literal line breaks written as \n. Run a replace() over user-supplied text before dropping it into the Compose.

Need Help with Your Power Platform Project?

Get expert guidance through personalized workshops, consulting, and training tailored to your specific needs.

Request Workshop

Consulting and process automation for SMBs is delivered by KMUpower. Prefer structured, German-language courses? The Power Platform Academy offers live Power Platform Schulung and hands-on Power Platform courses for Power Apps, Power Automate and Copilot.